Skip to content

Commit 2acee25

Browse files
committed
added LDPC curve for comparison, and imported trellis results
1 parent d148c0c commit 2acee25

File tree

1 file changed

+135
-17
lines changed

1 file changed

+135
-17
lines changed

octave/vq_compare.m

Lines changed: 135 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
2828
more off;
2929
randn('state',1);
30-
30+
graphics_toolkit("gnuplot");
31+
3132
if strcmp(action, "run_curves")
3233
run_curves(30*100);
3334
end
@@ -123,7 +124,7 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
123124
target_ = vq(rx_indexes+1,:);
124125
diff = target - target_;
125126
mse = mean(diff(:).^2);
126-
printf("Eb/No: %3.2f dB nframes: %2d nerrors: %3d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n",
127+
printf("Eb/No: %3.2f dB nframes: %3d nerrors: %4d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n",
127128
EbNodB, nframes, nerrors, nerrors/tbits, nper/nframes, mse_noerrors, mse);
128129
results.ber = nerrors/tbits;
129130
results.per = nper/nframes;
@@ -133,10 +134,113 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
133134
results.rx_indexes = rx_indexes;
134135
endfunction
135136

137+
% VQ a target sequence of frames then run a test using a LDPC code
138+
function results = run_test_ldpc(target, vq, EbNo, verbose)
139+
[frames tmp] = size(target);
140+
[vq_length tmp] = size(vq);
141+
nbits = log2(vq_length);
142+
nerrors = 0;
143+
tbits = 0;
144+
nframes = 0;
145+
nper = 0;
146+
147+
% init LDPC code
148+
mod_order = 4; bps = 2;
149+
modulation = 'QPSK';
150+
mapping = 'gray';
151+
max_iterations = 100; demod_type = 0; decoder_type = 0;
152+
ldpc; init_cml('~/cml/');
153+
tempStruct = load("HRA_56_56.txt");
154+
b = fieldnames(tempStruct);
155+
ldpcArrayName = b{1,1};
156+
% extract the array from the struct
157+
HRA = tempStruct.(ldpcArrayName);
158+
[code_param framesize rate] = ldpc_init_user(HRA, modulation, mod_order, mapping);
159+
160+
% set up noise
161+
EbNodB = 10*log10(EbNo);
162+
EsNodB = EbNodB + 10*log10(rate) + 10*log10(bps);
163+
EsNo = 10^(EsNodB/10);
164+
variance = 1/EsNo;
165+
166+
% Vector Quantise target vectors sequence
167+
[tx_indexes target_ ] = vector_quantiser_fast(vq, target, verbose);
168+
% use convention of indexes starting from 0
169+
tx_indexes -= 1;
170+
% mean SD of VQ with no errors
171+
diff = target - target_;
172+
mse_noerrors = mean(diff(:).^2);
173+
174+
% construct tx frames x nbit matrix using VQ indexes
175+
tx_bits = zeros(frames, nbits);
176+
for f=1:frames
177+
tx_bits(f,:) = dec2sd(tx_indexes(f), nbits) > 0;
178+
end
179+
180+
% find a superframe size, that has an integer number of nbits and data_bits_per_frame frames
181+
bits_per_superframe = nbits;
182+
while mod(bits_per_superframe,nbits) || mod(bits_per_superframe,code_param.data_bits_per_frame)
183+
bits_per_superframe += nbits;
184+
end
185+
186+
Nsuperframes = floor(frames*nbits/bits_per_superframe);
187+
Nldpc_codewords = Nsuperframes*bits_per_superframe/code_param.data_bits_per_frame;
188+
frames = Nsuperframes*bits_per_superframe/nbits;
189+
%printf("bits_per_superframe: %d Nldpc_codewords: %d frames: %d\n", bits_per_superframe, Nldpc_codewords, frames);
190+
191+
% reshape tx_bits matrix into Nldpc_codewords x data_bits_per_frame
192+
tx_bits = tx_bits(1:frames,:);
193+
tx_bits_ldpc = reshape(tx_bits',code_param.data_bits_per_frame, Nldpc_codewords)';
194+
195+
% modulate tx symbols
196+
tx_symbols = [];
197+
for nn=1:Nldpc_codewords
198+
[tx_codeword atx_symbols] = ldpc_enc(tx_bits_ldpc(nn,:), code_param);
199+
tx_symbols = [tx_symbols atx_symbols];
200+
end
201+
202+
noise = sqrt(variance*0.5)*(randn(1,length(tx_symbols)) + j*randn(1,length(tx_symbols)));
203+
rx_symbols = tx_symbols+noise;
204+
205+
% LDPC decode
206+
for nn = 1:Nldpc_codewords
207+
st = (nn-1)*code_param.coded_syms_per_frame + 1;
208+
en = (nn)*code_param.coded_syms_per_frame;
209+
210+
arx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, rx_symbols(st:en), EsNo, ones(1,code_param.coded_syms_per_frame));
211+
rx_bits_ldpc(nn,:) = arx_codeword(1:code_param.data_bits_per_frame);
212+
end
213+
214+
% reshape rx_bits_ldpc matrix into frames x nbits
215+
rx_bits = reshape(rx_bits_ldpc',nbits,frames)';
216+
217+
rx_indexes = tx_indexes;
218+
for f=1:frames
219+
rx_indexes(f) = sum(rx_bits(f,:) .* 2.^(nbits-1:-1:0));
220+
errors = sum(xor(tx_bits(f,:), rx_bits(f,:)));
221+
nerrors += errors;
222+
if errors nper++;, end
223+
tbits += nbits;
224+
nframes++;
225+
end
226+
227+
EbNodB = 10*log10(EbNo);
228+
target_ = vq(rx_indexes+1,:);
229+
diff = target - target_;
230+
mse = mean(diff(:).^2);
231+
printf("Eb/No: %3.2f dB nframes: %4d nerrors: %4d BER: %4.3f PER: %3.2f mse: %3.2f %3.2f\n",
232+
EbNodB, nframes, nerrors, nerrors/tbits, nper/nframes, mse_noerrors, mse);
233+
results.ber = nerrors/tbits;
234+
results.per = nper/nframes;
235+
results.mse = mse;
236+
results.tx_indexes = tx_indexes;
237+
results.rx_indexes = rx_indexes;
238+
endfunction
239+
136240
% Simulations ---------------------------------------------------------------------
137241

138242
% top level function to set up and run a test with a specific vq
139-
function [results target_] = run_test_vq(vq_fn, target_fn, nframes=100, dec=1, EbNodB=3, verbose=0)
243+
function [results target_] = run_test_vq(vq_fn, target_fn, nframes=100, dec=1, EbNodB=3, ldpc_en=0, verbose=0)
140244
K = 20; K_st=2+1; K_en=16+1;
141245

142246
% load VQ
@@ -157,7 +261,11 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
157261

158262
% run a test
159263
EbNo=10^(EbNodB/10);
160-
results = run_test(target, vqsub, EbNo, verbose);
264+
if ldpc_en
265+
results = run_test_ldpc(target, vqsub, EbNo, verbose);
266+
else
267+
results = run_test(target, vqsub, EbNo, verbose);
268+
end
161269
if verbose
162270
for f=2:nframes-1
163271
printf("f: %03d tx_index: %04d rx_index: %04d\n", f, results.tx_indexes(f), results.rx_indexes(f));
@@ -182,43 +290,53 @@ function vq_compare(action="run_curves", vq_fn, dec=1, EbNodB=3, in_fn, out_fn)
182290
% generate sets of curves
183291
function run_curves(frames=100, dec=1)
184292
target_fn = "../build_linux/all_speech_8k_lim.f32";
185-
results1_log = [];
186293
EbNodB = 0:5;
294+
295+
results1_ldpc_log = [];
187296
for i=1:length(EbNodB)
188-
results = run_test_vq("../build_linux/vq_stage1.f32", target_fn, frames, dec, EbNodB(i), verbose=0);
189-
results1_log = [results1_log results];
297+
results = run_test_vq("../build_linux/vq_stage1.f32", target_fn, frames, dec, EbNodB(i), ldpc_en=1, verbose=0);
298+
results1_ldpc_log = [results1_ldpc_log results];
190299
end
191-
results2_log = [];
300+
results4_ldpc_log = [];
192301
for i=1:length(EbNodB)
193-
results = run_test_vq("../build_linux/vq_stage1_bs001.f32", target_fn, frames, dec, EbNodB(i), verbose=0);
194-
results2_log = [results2_log results];
302+
results = run_test_vq("../build_linux/vq_stage1_bs004.f32", target_fn, frames, dec, EbNodB(i), ldpc_en=1, verbose=0);
303+
results4_ldpc_log = [results4_ldpc_log results];
304+
end
305+
306+
results1_log = [];
307+
for i=1:length(EbNodB)
308+
results = run_test_vq("../build_linux/vq_stage1.f32", target_fn, frames, dec, EbNodB(i), ldpc_en=0, verbose=0);
309+
results1_log = [results1_log results];
195310
end
196311
results4_log = [];
197312
for i=1:length(EbNodB)
198-
results = run_test_vq("../build_linux/vq_stage1_bs004.f32", target_fn, frames, dec, EbNodB(i), verbose=0);
313+
results = run_test_vq("../build_linux/vq_stage1_bs004.f32", target_fn, frames, dec, EbNodB(i), ldpc_en=0, verbose=0);
199314
results4_log = [results4_log results];
200315
end
201316
for i=1:length(results1_log)
202317
ber(i) = results1_log(i).ber;
203318
per(i) = results1_log(i).per;
204319
mse_noerrors(i) = sqrt(results1_log(i).mse_noerrors);
205320
mse_vq1(i) = sqrt(results1_log(i).mse);
206-
mse_vq2(i) = sqrt(results2_log(i).mse);
207321
mse_vq4(i) = sqrt(results4_log(i).mse);
322+
mse_vq1_ldpc(i) = sqrt(results1_ldpc_log(i).mse);
323+
mse_vq4_ldpc(i) = sqrt(results4_ldpc_log(i).mse);
208324
end
209325

210326
figure(1); clf;
211327
semilogy(EbNodB, ber, 'g+-;ber;','linewidth', 2); hold on;
212328
semilogy(EbNodB, per, 'b+-;per;','linewidth', 2);
213329
grid('minor'); xlabel('Eb/No(dB)');
214-
215-
hold off;
330+
hold off;
216331

217332
figure(2); clf;
218333
plot(EbNodB, mse_noerrors, "b+-;no errors;"); hold on;
219-
plot(EbNodB, mse_vq1, "g+-;vanilla;");
220-
plot(EbNodB, mse_vq2, "r+-;binary switch;");
221-
plot(EbNodB, mse_vq4, "b+-;binary switch with prob;");
334+
plot(EbNodB, mse_vq1, "g+-;vanilla AWGN;");
335+
plot(EbNodB, mse_vq4, "b+-;binary switch;");
336+
plot(EbNodB, mse_vq1_ldpc, "r+-;ldpc (112,56);");
337+
plot(EbNodB, mse_vq4_ldpc, "k+-;binary switch ldpc (112,56);");
338+
load trellis_dec3_nstage3.txt
339+
plot(EbNodB, rms_sd, "c+-;binary switch trellis dec3;");
222340
hold off; grid; title("RMS SD (dB)"); xlabel('Eb/No(dB)');
223341
endfunction
224342

0 commit comments

Comments
 (0)