From d75c91bf6061dc415056970bae7149e1e06d4628 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Thu, 17 Apr 2014 01:22:46 +0000 Subject: [PATCH] building up fuzzy codeword idea git-svn-id: https://svn.code.sf.net/p/freetel/code@1495 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/fuzzy_gray.m | 165 +++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 codec2-dev/octave/fuzzy_gray.m diff --git a/codec2-dev/octave/fuzzy_gray.m b/codec2-dev/octave/fuzzy_gray.m new file mode 100644 index 00000000..3a4eb1d1 --- /dev/null +++ b/codec2-dev/octave/fuzzy_gray.m @@ -0,0 +1,165 @@ +% fuzzy_gray.m +% David Rowe +% 10 April 2014 +% +% Experiments in fuzzy gray codes. Idea is that with one bit error +% in the codeword only changes the encoded value by at most 1. + +1; + +function three_bit_code + m=4; + log2_m=2; + value_to_codeword = ["000"; "001"; "101"; "111"]; + codeword_to_value = [0 1 1 2 1 2 2 3 3]; + + printf("tx_value tx_codeword rx_codeword rx_value distance\n"); + for i=1:m + tx_codeword = bin2dec(value_to_codeword(i,:)); + tx_codeword_bin = value_to_codeword(i,:); + rx_value = codeword_to_value(tx_codeword+1); + distance = abs((i-1) - rx_value); + printf("%8d %11s %11s %8d %8d\n", i-1, tx_codeword_bin, tx_codeword_bin, ... + rx_value, distance ); + end + printf("\n"); + for i=1:m + tx_codeword = bin2dec(value_to_codeword(i,:)); + tx_codeword_bin = value_to_codeword(i,:); + for j=1:(log2_m+1) + rx_codeword = bitxor(tx_codeword, bitset(0,j)); + rx_codeword_bin = dec2bin(rx_codeword, 3); + rx_value = codeword_to_value(rx_codeword+1); + distance = abs((i-1) - rx_value); + printf("%8d %11s %11s %8d %8d\n", i-1, tx_codeword_bin, rx_codeword_bin, ... + rx_value, distance ); + end + end +endfunction + +function index = quantise_value(value, min_value, max_value, num_levels) + norm = (value - min_value)/(max_value - min_value); + index = floor(num_levels * norm + 0.5); + if (index < 0 ) + index = 0; + end + if (index > (num_levels-1)) + index = num_levels-1; + end +endfunction + +function value = unquantise_value(index, min_value, max_value, num_levels) + step = (max_value - min_value)/num_levels; + value = min_value + step*(index); +endfunction + +function gray = binary_to_gray(natural) + gray = bitxor(bitshift(natural,-1),natural); +endfunction + +function natural = gray_to_binary(gray) + for i=1:length(gray) + mask = bitshift(gray(i),-1); + num = gray(i); + while(mask) + num = bitxor(num, mask); + mask = bitshift(mask,-1); + end + natural(i) = num; + end +endfunction + +function four_bit_code + Ebvec = 0:7; + Ntrials = 10000; + Nbits = 5; Nlevels = 2.^ Nbits; powersOfTwo = 2 .^ fliplr(0:(Nbits-1)); + Nsymb = Nbits; + + for ne = 1:length(Ebvec) + EbNodB = Ebvec(ne); + EbNo = 10^(EbNodB/10); + + variance = 1/EbNo; + + Terrs = 0; Tbits = 0; + qsignal = qnoise = 0; + + for nn = 1:Ntrials + + tx_value = rand(1,1); + tx_index = quantise_value(tx_value, 0, 1, Nlevels); + tx_bits = dec2bin(tx_index, Nbits) - '0'; + tx_symbols = -1 + 2*tx_bits; + + % AWGN noise and phase/freq offset channel simulation + % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im + + noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb)); + rx_symbols = tx_symbols + noise; + + rx_bits = rx_symbols > 0; + + error_positions = xor(rx_bits, tx_bits); + Nerrs = sum(error_positions); + Terrs += Nerrs; + Tbits += length(tx_bits); + + rx_index = (powersOfTwo * rx_bits'); + rx_value = unquantise_value(rx_index, 0, 1, Nlevels); + + qsignal += tx_value*tx_value; + qnoise += (tx_value - rx_value) .^ 2; + end + + TERvec(ne) = Terrs; + BERvec(ne) = Terrs/Tbits; + QSNRvec(ne) = 10*log10(qsignal/qnoise); + printf("EbNo (dB): %3.2f Terrs: %6d BER %1.4f QSNR (dB): %3.2f\n", EbNodB, Terrs, Terrs/Tbits, QSNRvec(ne)); + end + + figure(1); + clf; + semilogy(Ebvec, BERvec) + xlabel('Eb/N0') + ylabel('BER') + grid("minor") + + figure(2); + clf; + plot(Ebvec, QSNRvec) + xlabel('Eb/N0') + ylabel('SNR') + grid("minor") +endfunction + +function valid_codewords = fuzzy_code_create(ndata,nparity) + Nbits = ndata + nparity; + Nvalid = 2 .^ ndata; + codewords = binary_to_gray(0:(2 .^ Nbits)-1); + valid_codewords = dec2bin(codewords(1:2:(2 .^ Nbits)), Nbits) - '0'; + + % check all valid codewords have a hamming distance of at least 2^nparity + + bad_distance = 0; + for i=1:Nvalid + for k=i+1:Nvalid + distance = sum(bitxor(valid_codewords(i,:), valid_codewords(k,:))); + if distance < 2 + bad_distance++; + end + end + end + if bad_distance != 0 + printf("Error: Nvalid: %d bad_distance: %d\n", Nvalid, bad_distance); + return; + end + +endfunction + +function tx_codeword = fuzzy_code_encode(codewords, value) +endfunction + +function value = fuzzy_code_decode(codewords, rx_codeword) +endfunction + +fuzzy_code_create(3,1) -- 2.25.1