0% found this document useful (0 votes)
15 views6 pages

Turbo

This document contains source code that tests iterative decoding of turbo codes. It includes functions for encoding data using a rate 1/2 convolutional code with a pseudo-random interleaver of size 1024. The decoding uses the max-a-posteriori probability algorithm over multiple iterations to estimate the transmitted bits. The bit error rate is calculated for different signal-to-noise ratios.

Uploaded by

veviw99297
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views6 pages

Turbo

This document contains source code that tests iterative decoding of turbo codes. It includes functions for encoding data using a rate 1/2 convolutional code with a pseudo-random interleaver of size 1024. The decoding uses the max-a-posteriori probability algorithm over multiple iterations to estimate the transmitted bits. The bit error rate is calculated for different signal-to-noise ratios.

Uploaded by

veviw99297
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 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