for i = 1:length(EbN0db)
fprintf('%10.2f',EbN0db(i));
end
fprintf('\n----------------------------------------------------\n\n');
fprintf('+ + + + Please be patient. Wait a while to get the result. + + + +\n\n');
for nEN = 1:length(EbN0db)
en = 10^(EbN0db(nEN)/10);
% convert Eb/N0 from unit db to normal numbers
L_c = 4*a*en*rate;
% reliability value of the channel
sigma = 1/sqrt(2*rate*en);
% standard deviation of AWGN noise
% Clear bit error counter and frame error counter
errs(nEN,1:niter) = zeros(1,niter);
nferr(nEN,1:niter) = zeros(1,niter);
nframe = 0;
% clear counter of transmitted frames
while nferr(nEN, niter)
else
L_all = sova(rec_s(2,:), g, L_a, 2);
% complete info.
end
L_e = L_all - 2*rec_s(2,1:2:2*L_total) - L_a;
% extrinsic info.
% Estimate the info. bits
xhat(alpha) = (sign(L_all)+1)/2;
% Number of bit errors in current iteration
err(iter) = length(find(xhat(1:L_total-m)~=x));
% Count frame errors for the current iteration
if err(iter)>0
nferr(nEN,iter) = nferr(nEN,iter)+1;
end
end
%iter
% Total number of bit errors for all iterations
errs(nEN,1:niter) = errs(nEN,1:niter) + err(1:niter);
if rem(nframe,3)==0 | nferr(nEN, niter)==ferrlim
% Bit error rate
ber(nEN,1:niter) = errs(nEN,1:niter)/nframe/(L_total-m);
% Frame error rate
fer(nEN,1:niter) = nferr(nEN,1:niter)/nframe;
% Display intermediate results in process
fprintf('******************* Eb/N0 = %5.2f db ********************\n', EbN0db(nEN));
fprintf('Frame size = %d, rate 1/%d. \n', L_total, 2+puncture);
fprintf('%d frames transmitted, %d frames in error.\n', nframe, nferr(nEN, niter));
fprintf('Bit Error Rate (from iteration 1 to iteration %d):\n', niter);
for i=1:niter
fprintf('%8.4e
', ber(nEN,i));
end
fprintf('\n');
fprintf('Frame Error Rate (from iteration 1 to iteration %d):\n', niter);
for i=1:niter
fprintf('%8.4e
', fer(nEN,i));
end
fprintf('\n');
fprintf('*********************************************************\n\n');
% Save intermediate results
save turbo_sys_demo EbN0db ber fer
end
end
end
%while
%nEN
diary off
4
%------------------------------------------------------------------------------------------------
function [output, state] = encode_bit(g, input, state)
% This function takes as an input a single bit to be encoded, as well as
% the coeficients of the generator polynomials and the current state vector.
% It returns as output n encoded data bits, where 1/n is the code rate.
% the rate is 1/n k is the constraint length m is the amount of memory
[n,k] = size(g);
%g
m = k-1;
%
% determine the next output bit
for i=1:n
output(i) = g(i,1)*input;
% the first bit a_k's contribution to output
for j = 2:k
output(i) = xor(output(i),g(i,j)*state(j-1)); % a_(k-j)'s contribution to output
end;
end
state = [input, state(1:m-1)]; % shift one bit
%------------------------------------------------------------------------------------------------
function y = rsc_encode(g, x, terminated)
% encodes a block of data x (0/1)with a recursive systematic convolutional code
% with generator vectors in g, and returns the output in y (0/1).
% if terminated>0, the trellis is perfectly terminated
% if terminated<0, it is left unterminated;
% determine the constraint length (K), memory (m), and rate (1/n)and number of information bits.
[n,K] = size(g);
m = K - 1;
if terminated>0
L_info = length(x);
% L_info: lenght of information sequence
L_total = L_info + m; % L_total:m additional bits is used to terminate
else
L_total = length(x);
L_info = L_total - m; % see the sequence for untermated in function encoderm for reason. length of x is
L_total
end
state = zeros(1,m);
% initialize the state vector
% generate the codeword
for i = 1:L_total
if terminated<0 | (terminated>0 & i<=L_info)
d_k = x(1,i);
% d_k: information sequence
elseif terminated>0 & i>L_info
% terminate the trellis
d_k = rem( g(1,2:K)*state', 2 );
%
end
a_k = rem( g(1,:)*[d_k state]', 2 );
% a_k: the bit to be put into the register
5
[output_bits, state] = encode_bit(g, a_k, state);
output_bits(1,1) = d_k;
% since systematic, first output is input bit
y(n*(i-1)+1:n*i) = output_bits;
% n output bits for 1 input bit(recursiv encoder)
end
%------------------------------------------------------------------------------------------------
function en_output = encoderm( x, g, alpha, puncture )
% uses interleaver map 'alpha'
% if puncture = 1, unpunctured, produces a rate 1/3 output of fixed length
% if puncture = 0, punctured, produces a rate 1/2 output
% multiplexer chooses odd check bits from RSC1 and even check bits from RSC2
% determine the constraint length (K), memory (m)and number of information bits plus tail bits.
[n,K] = size(g);
m = K - 1;
L_info = length(x);
L_total = L_info + m;
% generate the codeword corresponding to the 1st RSC coder
% end = 1, perfectly terminated;
input = x;
output1 = rsc_encode(g,input,1);
% make a matrix with first row corresponing to info sequence
% second row corresponsing to RSC #1's check bits.
% third row corresponsing to RSC #2's check bits.
% y: unpuncture output of encoder; y(1,:) has m bits more than input bits
y(1,:) = output1(1:2:2*L_total);
y(2,:) = output1(2:2:2*L_total);
% interleave input to second encoder
for i = 1:L_total
input1(1,i) = y(1,alpha(i));
%alpha--index of interleaver
end
%input has been interleaved. L_total bits already.end =-1unterminated
output2 = rsc_encode(g, input1(1,1:L_total), -1 );
y(3,:) = output2(2:2:2*L_total);
% paralell to serial multiplex to get output vector
% puncture = 0: rate increase from 1/3 to 1/2;
% puncture = 1unpunctured, rate = 1/3;
if puncture > 0
% unpunctured
for i = 1:L_total
for j = 1:3
6
en_output(1,3*(i-1)+j) = y(j,i); % put the 3 bits of the same colomn to a sequential outputs
end
end
else
for i=1:L_total
% punctured into rate 1/2
en_output(1,n*(i-1)+1) = y(1,i);
if rem(i,2)
% output check bits by turns
en_output(1,n*i) = y(2,i);
% odd check bits from RSC1
else
en_output(1,n*i) = y(3,i);
% even check bits from RSC2
end
end
end
% antipodal modulation: +1/-1
en_output = 2 * en_output - ones(size(en_output));
%------------------------------------------------------------------------------------------------
function int_state = int_state( state )
% converts a row vector of m bits into a integer (base 10)
[dummy, m] = size( state );
for i = 1:m
vect(i) = 2^(m-i);
end
int_state = state*vect';
%------------------------------------------------------------------------------------------------
function bin_state = bin_state( int_state, m )
% converts an vector of integer into a matrix; the i-th row is the binary form
% of m bits for the i-th integer
for j = 1:length( int_state )
% length(int_state)?=max_state? --yzh
for i = m:-1:1
state(j,m-i+1) = fix( int_state(j)/ (2^(i-1)) );
% fix(X) rounds the elements of X to the nearest
integers towards zero.
int_state(j) = int_state(j) - state(j,m-i+1)*2^(i-1);
% remain of mod 2^(i-1), the leftmost bit
is most significant -yzh
end
end
bin_state = state;
%------------------------------------------------------------------------------------------------
function subr = demultiplex(r, alpha, puncture);
% At receiver end, serial to paralle demultiplex to get the code word of each encoder
7
% alpha: interleaver mapping
% puncture = 0: use puncturing to increase rate to 1/2;
% puncture = 1; unpunctured, rate 1/3;
% Frame size, which includes info. bits and tail bits
L_total = length(r)/(2+puncture);
% Extract the parity bits for both decoders
if puncture == 1
% unpunctured
for i = 1:L_total
x_sys(i) = r(3*(i-1)+1);
for j = 1:2
subr(j,2*i) = r(3*(i-1)+1+j); % 1/3 rate, one info.bit, two parity bits
end
end
else
for i = 1:L_total
% punctured, 1/2 rate
x_sys(i) = r(2*(i-1)+1); % odd posisition is systematic bits,
for j = 1:2
subr(j,2*i) = 0;
end
if rem(i,2)>0
% even position,one check bit from ENC1, one from ENC2 alternatively
subr(1,2*i) = r(2*i); % puntured parity bits are padded to zero
else
subr(2,2*i) = r(2*i);
end
end
end
% Extract the systematic bits for both decoders
for j = 1:L_total
% For decoder one
subr(1,2*(j-1)+1) = x_sys(j);
% odd positions is reserved for systematic bits
% For decoder two: interleave the systematic bits
subr(2,2*(j-1)+1) = x_sys(alpha(j)); % info.bits that are put into DEC2 are interleaved bits -yzh
end
%------------------------------------------------------------------------------------------------
function [next_out, next_state, last_out, last_state] = trellis(g)
% set up the trellis given code generator g
% g given in binary matrix form. e.g. g = [ 1 1 1; 1 0 1 ];
% next_out(i,1:2): trellis next_out (systematic bit; parity bit) when input = 0, state = i; next_out(i,j)
= -1 or 1
% next_out(i,3:4): trellis next_out
(systematic bit; parity bit) when input = 1, state = i;
% next_state(i,1): next state when input = 0, state = i; next_state(i,i) = 1,...2^m
% next_state(i,2): next state when input = 1, state = i;
% last_out(i,1:2): trellis last_out (systematic bit; parity bit) when input = 0, state = i; last_out(i,j)
8