You are on page 1of 6

/* Testing version of Iterative Decoding of Turbo Codes */

/* date: 8/22/98 */
/* Characteristics: */
/* Encoder: rate=1/2 CC, g1=5, g2=7, dmin=5 (optimal 1/2 CC) */
/* Interleaver: Pseudo-Random interleaver, size 1024 */
/* Decoding: 1. Maximize the a posteriori probability */
/* 2. No tail bits... */
/* 3. Exp-MAP: computational complexity is high */
/* */
/* Author: chi-hsiao Yih */

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define block_length 1024


#define state_num 4
#define input_num 2
#define output_bit_num 2
#define range 2147483647.0
#define accuracy 500

int st, error, d[block_length], rev_states[state_num][input_num];


int index[block_length];
double x1[block_length],x2[block_length],ya[block_length],yb[block_length];
double alpha[block_length][input_num][state_num];
double beta[block_length][input_num][state_num];
double snr, dev, half_var, count;
double Lc, La[block_length], Ld[block_length];

static int output[state_num][input_num][output_bit_num]=


{0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0};
static int states[state_num][input_num]={0,2,2,0,3,1,1,3};

double uniform(void)
{
return(random()/range);
}

int bernoulli(void)
{
if (uniform() > 0.5)
return(1);
else
return(0);
}

double gauss(void)
{
static int t=0;
static double set;
double r,x,y,v1,v2;

if (t==0)
{
do{
v1 = 2.0*uniform() - 1.0;
v2 = 2.0*uniform() - 1.0;
r = v1*v1 + v2*v2;
} while (r >= 1.0);
y = sqrt(-2.0*log(r)/r);
set = v1 * y;
t = 1;
return(v2*y);
} else {
t=0;
return(set);
}
}

void interleaver(void)
{
int i, j, k, tmp[block_length];
char tt;

for(i=0; i<block_length; i++)


{
tmp[i] = random();
index[i] = i;
}

for(i=0; i<block_length; i++)


for(j=i+1; j<block_length; j++)
{
if (tmp[i] <= tmp[j])
{
k = index[i];
index[i] = index[j];
index[j] = k;

k = tmp[i];
tmp[i] = tmp[j];
tmp[j] = k;
}
}

void turbo_encoder(void)
{
int i, j, tmp[block_length];

/* encoder 1 output */

st=0;
for(i=0; i<block_length; i++)
{
d[i] = bernoulli();
x1[i] = (2.0*d[i] - 1.0) + dev*gauss();
ya[i] = (2.0*output[st][d[i]][1] - 1.0) + dev*gauss();
st = states[st][d[i]];
}

/* interleaving */

for(i=0; i<block_length; i++)


{
tmp[i] = d[index[i]];
x2[i] = x1[index[i]];
}

/* encoder 2 output */

st=0;
for(i=0; i<block_length; i++)
{
yb[i] = (2.0*output[st][tmp[i]][1] - 1.0) + dev*gauss();
st = states[st][tmp[i]];
}
}

void reverse_state(void)
{
int m, i, j;

for(i=0; i<state_num; i++)


for(j=0; j<input_num; j++)
{
m = states[i][j];
rev_states[m][j] = i;
}
}

void initialize(void)
{
int i, j;

for(i=0; i<input_num; i++)


for(j=0; j<state_num; j++)
{
if (j==0)
alpha[0][i][j] = 1;
else
alpha[0][i][j] = 0;
beta[block_length-1][i][j] = 1.0/state_num;
}

for(i=0; i<block_length; i++)


La[i] = 0.0;
}

void compute_alpha(double *x, double *y, double *L)


{
int i, j, k, m, sbim;
double normal, tmp1, tmp2;

for (k=1; k<block_length; k++)


{
for(i=0; i<input_num; i++)
for(m=0; m<state_num; m++)
{
tmp1 = exp((L[k] + Lc*x[k])*i +
Lc*y[k]*output[m][i][1]);
tmp2 = 0.0;
for(j=0; j<2; j++)
{
sbim = rev_states[m][j];
tmp2 += alpha[k-1][j][sbim];
}
alpha[k][i][m] = tmp1*tmp2;

if ((m==0)&&(i==0))
normal = alpha[k][i][m];
else if (normal < alpha[k][i][m])
normal = alpha[k][i][m];
}

for(i=0; i<input_num; i++)


for(m=0; m<state_num; m++)
alpha[k][i][m] = alpha[k][i][m]/normal;
}
}

void compute_beta(double *x, double *y, double *L)


{
int i, j, k, m, sfim;
double tmp, normal;

for (k=block_length-2; k>=0; k--)


{
for(i=0; i<input_num; i++)
for(m=0; m<state_num; m++)
{
tmp = 0.0;
sfim = states[m][i];
for(j=0; j<2; j++)
{
tmp += beta[k+1][j][sfim] *
exp((L[k+1]+Lc*x[k+1])*j +
Lc*y[k+1]*output[sfim][j][1]);
}
beta[k][i][m] = tmp;

if ((m==0)&&(i==0))
normal = beta[k][i][m];
else if (normal < beta[k][i][m])
normal = beta[k][i][m];
}

for(i=0; i<input_num; i++)


for(m=0; m<state_num; m++)
beta[k][i][m] = beta[k][i][m]/normal;
}
}

void main(void)
{
int dc, i, it, k, m, iter_no, tmp[block_length];
double tmp1, tmp2;
char filename[30];
FILE *fp;

printf("\n Number of Iteration ? ");


scanf("%d", &iter_no);
printf("\n Save the data to file ? ");
scanf("%s", &filename);
fp = fopen(filename, "w");

/* begin iterative decoding */

reverse_state();
interleaver();

for(snr=-2.0; snr<=2; snr+=0.5)


{
count = 0;
error = 0;
half_var = 0.5 * pow(10.0, -1.0*snr/10);
dev = 1.0 * pow(10.0, -1.0*snr/20);
Lc = 4 * pow(10.0, snr/10);

do{
turbo_encoder();
initialize();

for(it=0; it<iter_no; it++)


{
compute_alpha(x1, ya, La);
compute_beta(x1, ya, La);

for(k=0; k<block_length; k++)


{
tmp1 = 0.0;
tmp2 = 0.0;
for(m=0; m<state_num; m++)
{
tmp1 += alpha[k][1][m] * beta[k][1][m];
tmp2 += alpha[k][0][m] * beta[k][0][m];
}
Ld[k] = log(tmp1/tmp2);
La[k] = Ld[k] - La[k] - Lc*x1[k];
}

/* interleaving */

for(i=0; i<block_length; i++)


tmp[i] = La[index[i]];
for(i=0; i<block_length; i++)
La[i] = tmp[i];

compute_alpha(x2, yb, La);


compute_beta(x2, yb, La);

for(k=0; k<block_length; k++)


{
tmp1 = 0.0;
tmp2 = 0.0;
for(m=0; m<state_num; m++)
{
tmp1 += alpha[k][1][m] * beta[k][1][m];
tmp2 += alpha[k][0][m] * beta[k][0][m];
}
Ld[k] = log(tmp1/tmp2);
La[k] = Ld[k] - La[k] - Lc*x2[k];
}

/* deinterleaving */
for(i=0; i<block_length; i++)
tmp[index[i]] = La[i];
for(i=0; i<block_length; i++)
La[i] = tmp[i];
}

/* final stage decoding */

for(i=0; i<block_length; i++)


tmp[index[i]] = Ld[i];
for(i=0; i<block_length; i++)
Ld[i] = tmp[i];

for(i=0; i<block_length-2; i++)


{
if (Ld[i] >= 0.0)
dc = 1;
else
dc = 0;
count++;
if (dc != d[i])
error++;
}
}while (error <= accuracy);

printf("\n SNR = %4.1f, Dev = %5.4f, BER = %12.10f",


snr, dev, 1.0*error/count);

fprintf(fp,"\n %4.1f %12.10f %5.4f", snr, 1.0*error/count, dev);


count=0;
error=0;
}
printf("\n");
}

You might also like