⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turbo.cpp

📁 Turbo Code simulator
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -