From: drowe67 Date: Thu, 16 Mar 2017 02:57:19 +0000 (+0000) Subject: first pass a AWGN perf curves for Bill's short codes X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=d68ca444ba5c0aa3634391daf24ac0c866fd97ec;p=freetel-svn-tracking.git first pass a AWGN perf curves for Bill's short codes git-svn-id: https://svn.code.sf.net/p/freetel/code@3064 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/HRA_112_112.txt b/codec2-dev/octave/HRA_112_112.txt index e446c4a9..e7746401 100644 --- a/codec2-dev/octave/HRA_112_112.txt +++ b/codec2-dev/octave/HRA_112_112.txt @@ -1,5 +1,5 @@ # Created by Octave 3.8.1, Wed Mar 15 17:24:05 2017 ACDT -# name: H2 +# name: HRA_112_112 # type: matrix # rows: 112 # columns: 224 diff --git a/codec2-dev/octave/HRA_112_56.txt b/codec2-dev/octave/HRA_112_56.txt index e22ce658..1df20d8c 100644 --- a/codec2-dev/octave/HRA_112_56.txt +++ b/codec2-dev/octave/HRA_112_56.txt @@ -1,5 +1,5 @@ # Created by Octave 3.8.1, Wed Mar 15 17:59:13 2017 ACDT -# name: H1 +# name: HRA_112_56 # type: matrix # rows: 56 # columns: 168 diff --git a/codec2-dev/octave/HRA_56_28.txt b/codec2-dev/octave/HRA_56_28.txt index f31c00fa..ae762484 100644 --- a/codec2-dev/octave/HRA_56_28.txt +++ b/codec2-dev/octave/HRA_56_28.txt @@ -1,5 +1,5 @@ # Created by Octave 3.8.1, Wed Mar 15 18:20:20 2017 ACDT -# name: H1 +# name: HRA_56_28 # type: matrix # rows: 28 # columns: 84 diff --git a/codec2-dev/octave/HRA_56_56.txt b/codec2-dev/octave/HRA_56_56.txt index b35e0e4d..8a18f2d6 100644 --- a/codec2-dev/octave/HRA_56_56.txt +++ b/codec2-dev/octave/HRA_56_56.txt @@ -1,5 +1,5 @@ # Created by Octave 3.8.1, Wed Mar 15 18:12:09 2017 ACDT -# name: H1 +# name: HRA_56_56 # type: matrix # rows: 56 # columns: 112 diff --git a/codec2-dev/octave/ldpc_short.m b/codec2-dev/octave/ldpc_short.m index e769bf74..a60924d3 100644 --- a/codec2-dev/octave/ldpc_short.m +++ b/codec2-dev/octave/ldpc_short.m @@ -25,36 +25,50 @@ function init_cml end -function sim_out = ldpc4(HRA, Ntrials, Esvec, genie_Es); - - [Nr Nc] = size(HRA); +function sim_out = run_sim(HRA, Ntrials, Esvec, genie_Es, packet_size, golay = 0) + + if golay + rate = 0.5; + code_param.data_bits_per_frame = 12; + framesize = 24; + else + % LDPC code + + [Nr Nc] = size(HRA); + rate = (Nc-Nr)/Nc; + framesize = Nc; + modulation = 'BPSK'; + demod_type = 0; + decoder_type = 0; + max_iterations = 100; + [H_rows, H_cols] = Mat2Hrows(HRA); + code_param.H_rows = H_rows; + code_param.H_cols = H_cols; + code_param.P_matrix = []; + code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix ); + end - rate = (Nc-Nr)/Nc; - framesize = Nc; mod_order = 2; - modulation = 'BPSK'; - demod_type = 0; - decoder_type = 0; - max_iterations = 100; bps = code_param.bits_per_symbol = log2(mod_order); - [H_rows, H_cols] = Mat2Hrows(HRA); - code_param.H_rows = H_rows; - code_param.H_cols = H_cols; - code_param.P_matrix = []; - code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix ); - - + % loop around each Esvec point + for ne = 1:length(Esvec) Es = Esvec(ne); EsNo = 10^(Es/10); EbNodB = Es - 10*log10(code_param.bits_per_symbol * rate); - Terrs = 0; Tbits = 0; Ferrs = 0; + Terrs = 0; Tbits = 0; Ferrs = 0; + tx_bits = rx_bits = []; for nn = 1: Ntrials data = round( rand( 1, code_param.data_bits_per_frame ) ); - codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix ); + tx_bits = [tx_bits data]; + if golay + codeword = egolayenc(data); + else + codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix ); + end code_param.code_bits_per_frame = length( codeword ); Nsymb = code_param.code_bits_per_frame/bps; @@ -67,37 +81,64 @@ function sim_out = ldpc4(HRA, Ntrials, Esvec, genie_Es); r = s + noise; Nr = length(r); - % in the binary case the LLRs are just a scaled version of the rx samples ... - % if the EsNo is known -- use the following - if (genie_Es) - input_decoder_c = 4 * EsNo * r; + + if golay + detected_data = egolaydec(r < 0); + detected_data = detected_data(code_param.data_bits_per_frame+1:framesize); else - r = r / mean(abs(r)); % scale for signal unity signal - estvar = var(r-sign(r)); - estEsN0 = 1/(2* estvar); - input_decoder_c = 4 * estEsN0 * r; + + % in the binary case the LLRs are just a scaled version of the rx samples ... + % if the EsNo is known -- use the following + + if (genie_Es) + input_decoder_c = 4 * EsNo * r; + else + r = r / mean(abs(r)); % scale for signal unity signal + estvar = var(r-sign(r)); + estEsN0 = 1/(2* estvar); + input_decoder_c = 4 * estEsN0 * r; + end + + [x_hat, PCcnt] = MpDecode( input_decoder_c, code_param.H_rows, code_param.H_cols, ... + max_iterations, decoder_type, 1, 1); + Niters = sum(PCcnt!=0); + detected_data = x_hat(Niters,:); + detected_data = detected_data(1:code_param.data_bits_per_frame); end - [x_hat, PCcnt] = MpDecode( input_decoder_c, code_param.H_rows, code_param.H_cols, ... - max_iterations, decoder_type, 1, 1); - Niters = sum(PCcnt!=0); - detected_data = x_hat(Niters,:); - error_positions = xor( detected_data(1:code_param.data_bits_per_frame), data ); - Nerrs = sum( error_positions); + rx_bits = [rx_bits detected_data]; + + error_positions = xor( detected_data, data ); + Nerrs = sum(error_positions); if Nerrs>0, Ferrs = Ferrs +1; end Terrs = Terrs + Nerrs; Tbits = Tbits + code_param.data_bits_per_frame; + end - printf("EbNo: %3.1f dB BER: %5.4f Nbits: %4d Nerrs: %4d\n", EbNodB, Terrs/Tbits, Tbits, Terrs); + % count packet errors using supplied packet size. Operating one + % one big string of bits lets us account for cases were FEC framesize + % is less than packet size + + Perrs = 0; Tpackets = 0; + for i=1:packet_size:length(tx_bits)-packet_size + error_positions = xor( tx_bits(i:i+packet_size-1), rx_bits(i:i+packet_size-1)); + Nerrs = sum(error_positions); + if Nerrs>0, Perrs = Perrs +1; end + Tpackets++; + end + + printf("EbNo: %3.1f dB BER: %5.4f PER: %5.4f Nbits: %4d Nerrs: %4d Tpackets: %4d Perr: %4d\n", EbNodB, Terrs/Tbits, Perrs/ Tpackets, Tbits, Terrs, Tpackets, Perrs); TERvec(ne) = Terrs; FERvec(ne) = Ferrs; BERvec(ne) = Terrs/ Tbits; + PERvec(ne) = Perrs/ Tpackets; Ebvec = Esvec - 10*log10(code_param.bits_per_symbol * rate); sim_out.BERvec = BERvec; + sim_out.PERvec = PERvec; sim_out.Ebvec = Ebvec; sim_out.FERvec = FERvec; sim_out.TERvec = TERvec; @@ -107,42 +148,67 @@ endfunction % Start simulation here ---------------------------------------------- +rand('seed',1); +randn('seed',1); more off; format; -init_cml +init_cml; -Ntrials = 2000; +Ntrials = 500; Esvec = -3:0.5:3; +packet_size = 28; + + +load HRA_112_112.txt +load HRA_112_56.txt +load HRA_56_56.txt +load HRA_56_28.txt + +sim_out1 = run_sim(HRA_112_112, Ntrials, Esvec, 1, packet_size); +sim_out2 = run_sim(HRA_112_56 , Ntrials, Esvec, 1, packet_size); +sim_out3 = run_sim(HRA_56_56 , Ntrials*2, Esvec, 1, packet_size); +sim_out4 = run_sim(HRA_56_28 , Ntrials*2, Esvec, 1, packet_size); +sim_out5 = run_sim([], Ntrials*10, Esvec, 1, packet_size, 1); -sim_out1 = ldpc4(H1, Ntrials, Esvec, 1); -sim_out2 = ldpc4(H2, Ntrials, Esvec, 1); -sim_out3 = ldpc4(H3, Ntrials, Esvec, 1); -sim_out4 = ldpc4(H4, Ntrials, Esvec, 1); +Ebvec_theory = -2:0.5:6; +uncoded_BER_theory = 0.5*erfc(sqrt(10.^(Ebvec_theory/10))); -EbNodBvec = sim_out1.Ebvec; -uncoded_BER_theory = 0.5*erfc(sqrt(10.^(EbNodBvec/10))); -uncoded_PER_theory = uncoded_BER_theory*sim_out1.framesize; +% need standard packet size to compare +% packet error if bit 0, or bit 1, or bit 2 ..... +% or bit 0 and bit 1 +% no packet error if all bits ok (1-p(0))*(1-p(1)) +% P(packet error) = p(0)+p(1)+.... + +uncoded_PER_theory = 1 - (1-uncoded_BER_theory).^packet_size; figure(1); clf; -semilogy(EbNodBvec, uncoded_BER_theory, 'b') +semilogy(Ebvec_theory, uncoded_BER_theory, 'b+-;BPSK theory;','markersize', 10, 'linewidth', 2) hold on; -semilogy(EbNodBvec, sim_out1.BERvec, 'g') -semilogy(EbNodBvec, sim_out2.BERvec, 'r') -semilogy(EbNodBvec, sim_out3.BERvec, 'c') -semilogy(EbNodBvec, sim_out4.BERvec, 'k') +semilogy(sim_out1.Ebvec, sim_out1.BERvec, 'g+-;rate 1/2 HRA 112 112;','markersize', 10, 'linewidth', 2) +semilogy(sim_out2.Ebvec, sim_out2.BERvec, 'r+-;rate 2/3 HRA 112 56;','markersize', 10, 'linewidth', 2) +semilogy(sim_out3.Ebvec, sim_out3.BERvec, 'c+-;rate 1/2 HRA 56 56;','markersize', 10, 'linewidth', 2) +semilogy(sim_out4.Ebvec, sim_out4.BERvec, 'k+-;rate 2/3 HRA 56 28;','markersize', 10, 'linewidth', 2) +semilogy(sim_out5.Ebvec, sim_out5.BERvec, 'm+-;rate 1/2 Golay (24,12);','markersize', 10, 'linewidth', 2) hold off; xlabel('Eb/No') ylabel('BER') grid +legend("boxoff"); + figure(2); clf; -semilogy(EbNodBvec, uncoded_PER_theory, 'b') +semilogy(Ebvec_theory, uncoded_PER_theory, 'b+-;BPSK theory;','markersize', 10, 'linewidth', 2) hold on; -semilogy(EbNodBvec, sim_out1.FERvec/Ntrials, 'g') -semilogy(EbNodBvec, sim_out2.FERvec/Ntrials, 'r') -semilogy(EbNodBvec, sim_out3.FERvec/Ntrials, 'c') -semilogy(EbNodBvec, sim_out4.FERvec/Ntrials, 'k') +semilogy(sim_out1.Ebvec, sim_out1.PERvec, 'g+-;rate 1/2 HRA 112 112;','markersize', 10, 'linewidth', 2) +semilogy(sim_out2.Ebvec, sim_out2.PERvec, 'r+-;rate 2/3 HRA 112 56;','markersize', 10, 'linewidth', 2) +semilogy(sim_out3.Ebvec, sim_out3.PERvec, 'c+-;rate 1/2 HRA 56 56;','markersize', 10, 'linewidth', 2) +semilogy(sim_out4.Ebvec, sim_out4.PERvec, 'k+-;rate 2/3 HRA 56 28;','markersize', 10, 'linewidth', 2) +semilogy(sim_out5.Ebvec, sim_out5.PERvec, 'm+-;rate 1/2 Golay (24,12);','markersize', 10, 'linewidth', 2) hold off; xlabel('Eb/No') ylabel('PER') grid +legend("boxoff"); + + +