Talk:BCH code

From Wikipedia, the free encyclopedia

[edit] Dispute on Graph

I dont know how this is going to be useful, but to the best of my knowledge this is the graph I obtained from running my simulation code. The main program is given here (ancillary functions omitted for want of space). You can get the full program from | here.

#!/usr/bin/octave -q

#A simple communications channel,

%BPSK uncoded.
System.BER=[];
System.Error=[];
System.Length=36*1000;
System.Mesg=zeros(1,System.Length);
System.Coded=[];

%BCH coded.
System.BCHError=[];
System.BCHBER=[];
System.BCHLength=System.Length*(63.0/36.0);
System.BCHCoded=zeros(1,System.BCHLength);
System.BCHDeCoded=[];


%BPSK parameters.
System.Modulated=[];
System.DeModulated=[];
System.DeCoded=[];
System.CarrierRate=10;
System.DataRate=2;
System.SNRdb=0:0.5:10;


gen_poly=BCH_poly();

Length=length(System.SNRdb);
System.BCHActualErrors=zeros(1,Length);
System.BCHCorrected=zeros(1,Length);

%Additive White Gaussian Noise, power.
System.N0=5;


for iter=1:Length

  disp('=>')
  System.SNRdb(iter)
  System.BCHBER

  disp('Simulating AWGN  channel with BCH & BPSK')

  %Value of SNR
  Eb=System.SNR=10^(System.SNRdb(iter)/10)*System.N0;
  
  %Signal strength, power.
  System.Eb=  System.SNR*System.N0;
  Ec=Eb*36.0/63.0;
  
  %Source Message
  System.Mesg=mod(floor(randn(1,System.Length)),2);

  Rxword=[];
  Chunks=length(System.Mesg)/36;
  for biter=1:Chunks
    bmesg=System.Mesg((biter-1)*36+1:biter*36);
    cwmesg=GF_product(gen_poly,GF_polarize(bmesg));

    %convert from the 0,-1 mode to the 1,0 mode.
    cwmesgTx=cwmesg+1;

    System.BCHCoded((biter-1)*63+1:(biter)*63)=cwmesg;

%Modulate BPSK
    bch1=bpskmod(cwmesgTx,20,10,sqrt(Ec));

%Add noise
    bch2=bch1+sqrt(System.N0)*boxmuller(length(bch1)); 

%Demodulate BPSK
    cwRx=bpskdemod(bch2,20,10,sqrt(Ec)); 

%   This is in the +1,+0 mode,
%   convert to a 0,-1 mode
    cwrecv=cwRx-1;

    Rxword=[Rxword cwrecv];

%error pos gives roots w.r.t index of 0.
   errpos=BCH_decode_berlekamp(cwrecv,63,36,5);%_berlekamp

%so add +1, to convert error position locations form 0 index, to +1 index.
    errpos=errpos+1;

    if isempty(errpos)
      %disp('Codeword is correct')
      correctw=cwrecv;
    else
      %printf('Correcting %d errors\n',length(errpos))
      %errpos
      correctw=cwrecv;
      for i=1:length(errpos)
        %flip the bits,
        correctw(errpos(i))=-(1+correctw(errpos(i)));
      end
    end

   %disp('Corrected CW')
   %correctw
   %fgets(stdin)

   
   CorrectError=length(errpos);
   System.BCHCorrected(iter)=System.BCHCorrected(iter)+CorrectError;

   System.BCHDeCoded((biter-1)*63+1:biter*63)=correctw;
  end
  
  System.BCHActualErrors(iter)=Difference(System.BCHCoded,Rxword);
  System.BCHError(iter)=Difference(System.BCHCoded,System.BCHDeCoded);
  System.BCHBER(iter)=System.BCHError(iter)/System.BCHLength;





  %BPSK part of simulation,
  System.Coded=System.Mesg;

  %Modulate 
  System.Modulated=bpskmod(System.Coded,System.CarrierRate,System.DataRate,sqrt(System.Eb));
  
  
  %Channel with AWGN
  System.Channel=System.Modulated + sqrt(System.N0)*randn(1,length(System.Modulated));


  %DeModulate
  System.DeModulated=bpskdemod(System.Channel,System.CarrierRate,System.DataRate,sqrt(System.Eb));

  %Channel Decode
  System.DeCoded=System.DeModulated;

  %Error Calculation
  System.Error(iter)=Difference(System.Coded,System.DeCoded);
  System.BER(iter)=System.Error(iter)/System.Length;

end

disp('System Error')
System.Error

disp('System BER')
System.BER

disp('System.BCHError')
System.BCHError

disp('System.BCHBER')
System.BCHBER

disp('System BCH Actual')
System.BCHActualErrors

disp('System BCH Corrected')
System.BCHCorrected

disp('System SNRdb')
System.SNRdb

semilogy(System.SNRdb,System.BER,";Simulated BPSK;",System.SNRdb,0.5*erfc(sqrt(10.^(System.SNRdb/10))),";Theoretical BPSK;",System.SNRdb,System.BCHBER,";Simulated BCH, [63,36];")
title "BPSK Uncoded, Vs BCH Coded systems"
save bchchannel_sim System
fgets(stdin)
fgets(stdin)

Let me know whats the problem, if there is any. --பராசக்தி 16:48, 16 September 2006 (UTC)


I tried to run your code on my octave, but I don't have the required other functions. Perhaps, it is better to consider the theoretical error rate. The (63,36) Binary BCH code with Berlekamp-Massey decoding should correct all error patterns of weight <= 5 and no error patterns of weight >5. Since the theoretical BER for BPSK is

Q(\sqrt{2 E_s / N_0}) = \frac{1}{2} Erfc (\sqrt{E_s / N_0}),

we can write

P_b = \sum_{j=6}^{63} \frac{j}{n} {n\choose j}p^j(1-p)^{n-j}

where p = Q( 2 \sqrt{E_s/N_0} ) is the raw error rate at the input of the decoder (due to the rate adjusted SNR). This assumes further that all decoder failures are detected, which is not a terrible assumption for this code.

I think that p should be equal to your "simulated BPSK" error rate. Perhaps you could add these theoretical curves to your graph to see what is going on.

Here is my Matlab code (apologies but my Octave installation has never quite worked for me).

n = 63;
k = 36;
t = 5;
rate = k/n;

ebno = 0:0.5:10;

bpsk_ber = 0.5*erfc(sqrt(10.^(ebno/10)));
coded_raw_ber = 0.5*erfc(sqrt(10.^(rate*ebno/10)));
coded_ber = 0*coded_raw_ber;

b = (0:n)/n;
b(1:(t+1)) = 0;
for i=1:length(ebno)
  coded_ber(i) = dot(binopdf(0:n,n,coded_raw_ber(i)),b);
end

semilogy(ebno,bpsk_ber,'r-',ebno,coded_raw_ber,'g-',ebno,coded_ber,'b-');
title('(63,36) BCH with bounded distance decoding');
legend('BPSK','Input to decoder','After decoder',3);
grid on


I have given a link to the code tarball on my website. Please use that for the other functions. AFAIK I think it is correct. The method maybe different, but I think it is statistically significant, as I ran the code for 36000 bits and got BER for 1e-4 (10x more bits than 1/BER). Also the right way would be to perform any simulation for just about till 10 errors or 100 errors accumulate at each SNR value as I understand from books by Moore on ECC. Let me know, now that other functions are avaiable. I will try & check your claims as well. --பராசக்தி 00:38, 19 September 2006 (UTC)

---

Here is an updated version of my code which uses the Matlab Communications Toolbox for the simulation. The theoretical BER formula/curve was updated to count only message bit errors.

n = 63;
k = 36;
t = 5;
rate = k/n;

ebno = 0:0.5:10;

ebno_lin = 10.^(ebno/10);
bpsk_ber = 0.5*erfc(sqrt(ebno_lin));
coded_raw_ber = 0.5*erfc(sqrt(rate*ebno_lin));
coded_ber = 0*coded_raw_ber;

% Theory
[X,Y] = meshgrid(0:k,0:n-k);
T = (((X+Y)>t)+0).*X;
for i=1:length(ebno)
  msg_err = binopdf(0:k,k,coded_raw_ber(i));
  par_err = binopdf(0:(n-k),n-k,coded_raw_ber(i))';
  joint = msg_err(ones(1,n-k+1),:) .* par_err(:,ones(1,k+1));
  coded_ber(i) = sum(sum(T.*joint))/k;
end

% Simulation (all zeros codeword)
M = 500;
sim_ber = zeros(1,length(ebno));
for i=1:2:15
  y = -1 + randn(M,n)/sqrt(2*rate*ebno_lin(i));
  ybit = (y>0)+0;
  xhat = bchdec(gf(ybit,1),n,k);
  sim_ber(i) = sum(sum(xhat~=0))/M/k;
end

semilogy(ebno,bpsk_ber,'r-',ebno,coded_raw_ber,'g-',ebno,coded_ber,'b-',ebno,sim_ber,'bo');
title('(63,36) BCH with bounded distance decoding');
legend('BPSK','Input to decoder','After decoder','Simulation',3);
xlabel('E_n / N_0');
ylabel('BER');
grid on;
set(gca,'YLim',[1e-7 1]);

The results of this script are plotted here. You will notice the theory and simulation now match because they are both correct.

Image:BCH_63_36_Code_Graph2.png