📄 turbo.cpp
字号:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "random.h"
const int SEED=1000;
unsigned int N=128;
unsigned int ITERATIONS=20;
double No;
// zero mean RV with variance as given
double gaussian(double variance);
// encodes mesg into parity1, and if force it true it modifies mesg to
// force the encoder to the zero state by the last bit.
void encode(bool *mesg,bool *parity1,unsigned size, bool force);
void interleave(bool *mesg, unsigned size);
// binary addition with no carry
bool add(bool a,bool b);
void interleave(bool *mesg, unsigned size);
void deinterleave(bool *mesg, unsigned size);
void deinterleavedouble(double *mesg, unsigned size);
void interleavedouble(double *mesg, unsigned size);
void createinterleave(unsigned size);
void createencodetable();
void inttobool(unsigned state, bool *array, unsigned size);
void booltoint(bool *array, unsigned size, unsigned *state);
unsigned decode (double *channelmesg, double *parity1, double *parity2, unsigned size, bool *mesg);
unsigned *interleavearray;
unsigned *deinterleavearray;
// global information about the encoder used by the encoder and the decoder
// routine
// how many states are in the encoder (a power of 2)
unsigned numstates;
// log2(numstates)
unsigned memory;
// [2] = input, [16] = current state, tostate[2][16] = next state
unsigned *tostate[2];
// [2] = last input, [16] = current state, fromstate[2][16] = previous state
unsigned *fromstate[2];
// [2] = input, [16] = current state, output[2][16] = output of encoder
bool *output[2];
Random before;
main()
{
bool *mesg;
bool *parity1;
bool *parity2;
double *channelmesg;
double *channelparity1;
double *channelparity2;
interleavearray = new unsigned[N];
deinterleavearray = new unsigned[N];
mesg = new bool[N];
parity1 = new bool[N];
parity2 = new bool[N];
channelmesg = new double[N];
channelparity1 = new double[N];
channelparity2 = new double[N];
// only needs to be done once
createencodetable();
bool firstloop=true;
// change if you want to loop for other values of dB
for (double dB=-4.0;dB<=-4.0;dB+=0.5)
{
unsigned totalN=0;
unsigned totalerrors=0;
unsigned numiter;
unsigned totaliter=0;
unsigned numloops=0;
// load the previous state
if (firstloop)
{
FILE *fp;
char line[30];
firstloop = false;
if ((fp = fopen("laststate","r")) != NULL)
{
fgets(line,30,fp);
dB = atof(line);
fgets(line,30,fp);
totalerrors = atoi(line);
fgets(line,30,fp);
totalN = atoi(line);
fgets(line,30,fp);
totaliter = atoi(line);
fgets(line,30,fp);
numloops = atoi(line);
fclose(fp);
}
}
// dB = 10*log(Eb/No) where Eb is 1
No = 1/pow(10.0,dB/10.0);
bool keepgoing=true;
do
{
for (int x=0;x<N;x++)
mesg[x] = before.boolrandom();
// create a random interleaver for each decode trial
createinterleave(N);
encode(mesg,parity1,N,true);
interleave(mesg,N);
encode(mesg,parity2,N,false);
// deinterleave for the decoder
deinterleave(mesg,N);
for (int x=0;x<N;x++)
{
mesg[x] ? channelmesg[x] = 1.0 : channelmesg[x]=-1.0;
parity1[x] ? channelparity1[x]=1.0 : channelparity1[x]=-1.0;
parity2[x] ? channelparity2[x]=1.0 : channelparity2[x]=-1.0;
}
// add gaussian noise, mean=0, variance=No/2
for (int x=0;x<N;x++)
{
channelmesg[x] += gaussian(No/2);
channelparity1[x] += gaussian(No/2);
channelparity2[x] += gaussian(No/2);
}
numiter = decode(channelmesg, channelparity1, channelparity2,N,mesg);
unsigned numerrors=0;
for (int x=0;x<N;x++)
{
bool temp = channelmesg[x] == 1 ? true : false;
if (mesg[x] != temp)
numerrors++;
}
totalerrors += numerrors;
totalN += N;
totaliter += numiter;
numloops++;
char name[30];
// open a file for output
sprintf (name,"%dN%lfdB",N,dB);
FILE *fp;
// if file exists, we will append to it
fp = fopen(name,"a");
printf ("N=%d, e=%d, totITER=%d, numITER=%d, No=%lf, tote=%d, totn=%d, dB=%lf\n",N,numerrors,ITERATIONS,numiter,No,totalerrors,totalN,dB);
fprintf (fp,"N=%d, e=%d, totITER=%d, numITER=%d, No=%lf, tote=%d, totn=%d, dB=%lf\n",N,numerrors,ITERATIONS,numiter,No,totalerrors,totalN,dB);
fclose(fp);
// save this state in case we need to start over again
fp = fopen ("laststate","w");
fprintf(fp,"%lf\n",dB);
fprintf(fp,"%u\n",totalerrors);
fprintf(fp,"%u\n",totalN);
fprintf(fp,"%u\n",totaliter);
fprintf(fp,"%u\n",numloops);
fclose(fp);
// a number of conditions for stopping the simulation for this dB value
if (totalerrors> 1000)
keepgoing = false;
else if (totalN>500000 && totalerrors > 100)
keepgoing = false;
else if (totalN>1E6 && totalerrors > 10)
keepgoing = false;
else if (totalN>5E6 && totalerrors > 5)
keepgoing = false;
else if (totalN>7.5E6 && totalerrors > 3)
keepgoing = false;
else if (totalN>1E7)
keepgoing=false;
}
while (keepgoing == true); // 10 million is as high as I'm willing to go
// 1000 errors should be enough for good stats.
// add a summary of the last run to the summary file
FILE *fp;
fp = fopen("summary","a");
printf ("dB = %lf, N=%ld, error=%ld, avgiter = %lf, interleaver size=%d, original encoder\n",dB, totalN,totalerrors,(double)totaliter/(double)numloops,N);
fprintf(fp,"dB = %lf, N=%ld, error=%ld, avgiter = %lf, interleaver size=%d, original encoder\n",dB, totalN,totalerrors,(double)totaliter/(double)numloops,N);
fclose(fp);
}
delete interleavearray;
delete deinterleavearray;
delete mesg;
delete parity1;
delete parity2;
delete channelmesg;
delete channelparity1;
delete channelparity2;
// use repeat n code, n=3 in this case. For large probability of error this code
// will beat turbo code, turbo is way better for lesser probability of error
/*
for (int x=0;x<N;x++)
mesg[x] = parity1[x] = parity2[x] = before.boolrandom();
for (int x=0;x<N;x++)
{
mesg[x] ? channelmesg[x] = 1.0 : channelmesg[x]=-1.0;
parity1[x] ? channelparity1[x]=1.0 : channelparity1[x]=-1.0;
parity2[x] ? channelparity2[x]=1.0 : channelparity2[x]=-1.0;
}
numerrors=0;
// add white guassian noise
for (int x=0;x<N;x++)
{
bool temp;
channelmesg[x] += gaussian(No/2);
if (channelmesg[x] > 0)
temp = true;
else
temp = false;
if (mesg[x] != temp)
numerrors++;
channelparity1[x] += gaussian(No/2);
channelparity2[x] += gaussian(No/2);
}
printf ("%ld\n",numerrors);
numerrors=0;
// make decisions based on majority rules
for (int x=0;x<N;x++)
{
int count=0;
if (channelmesg[x] > 0)
count ++;
else
count--;
if (channelparity1[x] > 0)
count++;
else
count--;
if (channelparity2[x] > 0)
count++;
else
count--;
bool temp;
if (count > 0)
temp = true;
else
temp = false;
if(mesg[x] != temp)
numerrors ++;
}
printf ("%ld\n",numerrors);
*/
}
void createencodetable()
{
bool *boolstate;
bool *newstate;
numstates = 16;
memory = 4;
// create arrays used by encode and decode
output[0] = new bool[numstates];
output[1] = new bool[numstates];
fromstate[0] = new unsigned[numstates];
fromstate[1] = new unsigned[numstates];
tostate[0] = new unsigned[numstates];
tostate[1] = new unsigned[numstates];
boolstate = new bool[memory];
newstate = new bool[memory];
for (unsigned input=0;input<2;input++)
for (unsigned intstate=0;intstate<numstates;intstate++)
{
bool boolinput = (input == 0) ? false : true;
inttobool(intstate,boolstate,memory);
// calculate output due to the input
output[input][intstate] = add(boolinput,boolstate[0]);
output[input][intstate] = add(output[input][intstate],boolstate[3]);
output[input][intstate] = add(output[input][intstate],boolstate[1]);
output[input][intstate] = add(output[input][intstate],boolstate[2]);
output[input][intstate] = add(output[input][intstate],boolstate[3]);
// calculate new states
newstate[3] = boolstate[2];
newstate[2] = boolstate[1];
newstate[1] = boolstate[0];
newstate[0] = add(add(boolinput,boolstate[0]),boolstate[3]);
// from s' to s
booltoint (newstate,memory,&tostate[input][intstate]);
// from s to s'
fromstate[input][tostate[input][intstate]] = intstate;
}
delete boolstate;
delete newstate;
}
/*
void createencodetable()
{
numstates = 128;
memory = 7;
// create arrays used by encode and decode
output[0] = new bool[numstates];
output[1] = new bool[numstates];
fromstate[0] = new unsigned[numstates];
fromstate[1] = new unsigned[numstates];
tostate[0] = new unsigned[numstates];
tostate[1] = new unsigned[numstates];
yesno[0] = new bool[numstates];
yesno[1] = new bool[numstates];
bool *yesno[2];
Random r;
for (unsigned input=0;input<2;input++)
for (unsigned intstate=0;intstate<numstates;intstate++)
yesno[input][intstate] = false;
for (unsigned input=0;input<2;input++)
for (unsigned intstate=0;intstate<numstates;intstate++)
{
bool output
unsigned nextstate;
do
{
output = r.boolrandom();
nextstate=r.longrandom();
}
while(yesno[input][nextstate] == true);
yesno[input][nextstate]=false;
while (done < 2*numstates)
{
bool input = a.boolrandom();
unsigned state = a.unsignedrandom(numstates);
if(yesno[input][state] == false)
{
yesno[input][state] = true;
done++;
tostate[input]
for (unsigned input=0;input<2;input++)
for (unsigned intstate=0;intstate<numstates;intstate++)
{
bool boolinput = (input == 0) ? false : true;
inttobool(intstate,boolstate,memory);
// calculate output due to the input
output[input][intstate] = add(boolinput,boolstate[0]);
output[input][intstate] = add(output[input][intstate],boolstate[3]);
output[input][intstate] = add(output[input][intstate],boolstate[1]);
output[input][intstate] = add(output[input][intstate],boolstate[2]);
output[input][intstate] = add(output[input][intstate],boolstate[3]);
// calculate new states
newstate[3] = boolstate[2];
newstate[2] = boolstate[1];
newstate[1] = boolstate[0];
newstate[0] = add(add(boolinput,boolstate[0]),boolstate[3]);
// from s' to s
booltoint (newstate,memory,&tostate[input][intstate]);
// from s to s'
fromstate[input][tostate[input][intstate]] = intstate;
}
delete boolstate;
delete newstate;
}
*/
void inttobool(unsigned state, bool *array, unsigned size)
{
for (unsigned x=0;x<size;x++)
{
unsigned next = state >> 1;
if ((next << 1) == state)
array[x] = false;
else
array[x] = true;
state = next;
}
}
void booltoint(bool *array, unsigned size, unsigned *state)
{
*state = 0;
for (int x=0;x<size;x++)
if (array[x] == true)
(*state) |= (1 << x);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -