Hamming Codes
Import Python Libraries: 5G-Toolkit and NumPy
tk = py.importlib.import_module('toolkit5G');
np = py.importlib.import_module('numpy');
Import Modules for Simulations: Demapper | Mapper | HammingEncoder | HammingDecoder
Demapper = tk.SymbolMapping.Demapper;
Mapper = tk.SymbolMapping.Mapper;
HammingEncoder = tk.ChannelCoder.HammingEncoder;
HammingDecoder = tk.ChannelCoder.HammingDecoder;
Hamming Code Configurations
m = 3;
k = int32(2^m - m - 1);
n = int32(2^m - 1);
Payload Generation
numBatches = int32(100000);
bits = randi(2,numBatches,k)-1;
bits = np.array(bits);
Hamming Encoder
encoder = HammingEncoder(k,n);
encBits = encoder(bits);
codeword = encBits; % No Rate-matching
Symbol Mapping
constellation_type = "bpsk";
num_bits_per_symbol = 1;
mapperObject = Mapper(constellation_type, num_bits_per_symbol);
symbols = mapperObject(codeword);
Link Level Simulation: SNR vs BLER
numPoints = int32(10);
SNRdB = linspace(-4, 8, numPoints);
SNR = 10.^(SNRdB/10);
uncodedBER = zeros(1,numPoints);
codedBERhard = zeros(1,numPoints);
codedBERsoft = zeros(1,numPoints);
codedBLERhard = zeros(1,numPoints);
codedBLERsoft = zeros(1,numPoints);
% Symbol Demapping
demapping_method = "app";
demapper = Demapper(demapping_method, constellation_type, num_bits_per_symbol, hard_out = 0);
for snrIndex = 1:numPoints
snr = SNR(snrIndex);
% AWGN Channel
symbs = symbols + np.sqrt(0.5/snr)*(np.random.standard_normal(size=symbols.shape)+1j*np.random.standard_normal(size=symbols.shape));
% Symbol Demapping
llrEst = demapper(py.list({symbs, 1/snr}));
% Decoding based on Hard Inputs
uncBits = np.where(llrEst > 0, np.int8(1), np.int8(0));
uncodedBER(snrIndex) = np.mean(np.abs(uncBits-encBits));
decoder = HammingDecoder(k,n);
decBits = decoder(uncBits);
% BER and BLER for decoding based on Hard Inputs
codedBERhard(snrIndex) = np.mean(np.abs(bits-decBits));
codedBLERhard(snrIndex) = np.mean(np.where(np.sum(np.abs(bits-decBits), axis=int32(1))>0, 1, 0));
% Decoding based on Soft Inputs
decoder = HammingDecoder(k,n);
decBits = decoder(llrEst, "sphereDecoding");
% BER and BLER for decoding based on Soft Inputs
codedBERsoft(snrIndex) = np.mean(np.abs(bits-decBits));
codedBLERsoft(snrIndex) = np.mean(np.where(np.sum(np.abs(bits-decBits), axis=int32(1))>0, 1, 0));
disp("At SNR(dB): "+num2str(snr,'%.2f')+" | uncoded BER: "+num2str(uncodedBER(snrIndex),'%.2f')+" | coded BER [Hard]: "+num2str(codedBERhard(snrIndex),'%.2f')+" | coded BER [Soft]: "+num2str(codedBERsoft(snrIndex),'%.2f'))
end
At SNR(dB): 0.40 | uncoded BER: 0.19 | coded BER [Hard]: 0.18 | coded BER [Soft]: 0.14
At SNR(dB): 0.54 | uncoded BER: 0.15 | coded BER [Hard]: 0.13 | coded BER [Soft]: 0.09
At SNR(dB): 0.74 | uncoded BER: 0.11 | coded BER [Hard]: 0.08 | coded BER [Soft]: 0.05
At SNR(dB): 1.00 | uncoded BER: 0.08 | coded BER [Hard]: 0.04 | coded BER [Soft]: 0.02
At SNR(dB): 1.36 | uncoded BER: 0.05 | coded BER [Hard]: 0.02 | coded BER [Soft]: 0.01
At SNR(dB): 1.85 | uncoded BER: 0.03 | coded BER [Hard]: 0.01 | coded BER [Soft]: 0.00
At SNR(dB): 2.51 | uncoded BER: 0.01 | coded BER [Hard]: 0.00 | coded BER [Soft]: 0.00
At SNR(dB): 3.41 | uncoded BER: 0.00 | coded BER [Hard]: 0.00 | coded BER [Soft]: 0.00
At SNR(dB): 4.64 | uncoded BER: 0.00 | coded BER [Hard]: 0.00 | coded BER [Soft]: 0.00
At SNR(dB): 6.31 | uncoded BER: 0.00 | coded BER [Hard]: 0.00 | coded BER [Soft]: 0.00
Performance Evaluation: SNR vs BLER
% Plot the Results of the Simulations
close all;
figure(1)
semilogy(SNRdB, uncodedBER, LineStyle="-", LineWidth = 1.5, Marker= "o", MarkerSize=8)
hold on
semilogy(SNRdB, codedBERhard, LineStyle="--", LineWidth = 1.5, Marker= "P", MarkerSize=8)
semilogy(SNRdB, codedBERsoft, LineStyle=":", LineWidth = 1.5, Marker= "+", MarkerSize=10)
ylim([0.0001,0.2])
legend('Uncoded-BER', 'Hard Decoding', 'Soft Decoding')
grid on