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

📄 viterbi_qam.c

📁 Hard Viterbi QPSK in AWGN, Rayleight soft Viterbi QAM in AWGN, Rayleight viterbi QAM in AWGN, Rayl
💻 C
字号:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include "random.h"
// make the complex structure
typedef struct complex1
{
	double real;
	double imag;
}complex;
// define the number of the iteration
#define ITERATION pow(10, 4)
#define THENUMBEROFDATA 1000

void convolution(int *data, int *codeddata);
double modulation(int data);
void demodulation(double * r_data);
int bercheck(int data, double d_data);
int comparison(int com1, int com2);
void viterbi_decode(int *d_data, int *decode_data);

void main()
{
	FILE *fp1;
	double Noisepower;
	complex Noise;
	int data[THENUMBEROFDATA];
	int codeddata[2*(THENUMBEROFDATA+2)];
	int cr_data[2];
	int ci_data[2];
	complex m_data;
	complex r_data;
	double d_datareal[2];
	double d_dataimag[2];
	int d_data[2*(THENUMBEROFDATA+2)];
	int decode_data[THENUMBEROFDATA+2];
	int error;
//	int error1;
//	int error2;
//	int error3;
	double avgerr;
	int EbofN0;
	
	// open and make the text file 
	fp1=fopen("result_16qam_Viterbi.txt","w");
	srand(time(0));
	for(EbofN0=11; EbofN0<=15; EbofN0+=1)
	{
		double sumerr=0.0;
		int run;		
		int i;
		int l;
	
		for(run=0;run<ITERATION;run++)
		{
			// generate the real part data 		
			generate_random(&data[0], THENUMBEROFDATA);
			
			convolution(data, codeddata);
			// generate the imaginary part data
            //generate_random(&data1[0], THENUMBEROFDATA/2);
			
            for (i=0; i<=(THENUMBEROFDATA/2);i++)
			{
			
				cr_data[0]=codeddata[4*i];
				cr_data[1]=codeddata[4*i+1];
                ci_data[0]=codeddata[4*i+2];
				ci_data[1]=codeddata[4*i+3];
				// modulated the real part signal
				m_data.real = modulation(cr_data);
				// modulated the imaginary part signal 
				m_data.imag = modulation(ci_data);

				// make the noisepower	
				Noisepower=1/(2*pow(10,(double)EbofN0/10));
				// make the real part of noise
				Noise.real = sqrt(Noisepower/2)*GaussRand();
				// make the imaginary part of noise
				Noise.imag = sqrt(Noisepower/2)*GaussRand();
			
				// receive the real part of the signal 
				r_data.real = sqrt(1.0/10.0)*m_data.real + Noise.real;
				// receive the imaginary part of the signal 
				r_data.imag = sqrt(1.0/10.0)*m_data.imag + Noise.imag;
						
				d_datareal[0] = r_data.real; 
				d_dataimag[0] = r_data.imag;
				// demodulated the real part of the signal 
				demodulation(&d_datareal);
				// demodulated the imaginary part of the signal 
				demodulation(&d_dataimag);
				d_data[4*i]=(int)d_datareal[0];
				d_data[4*i+1]=(int)d_datareal[1];
				d_data[4*i+2]=(int)d_dataimag[0];
				d_data[4*i+3]=(int)d_dataimag[1];
			}
			viterbi_decode(d_data,decode_data);
			// check the error 

			for (l=0;l<=(THENUMBEROFDATA-1);l++)
			{				
				//printf("%d=",decode_data[l]);
				//printf("%d\n",data[l]);
				error= bercheck(data[l], decode_data[l]);
				sumerr = sumerr + error;
			}
			//error= bercheck(data[0], d_datareal[0]);
			//error1= bercheck(data[1], d_datareal[1]);
			//error2= bercheck(data1[0], d_dataimag[0]);
			//error3= bercheck(data1[1], d_dataimag[1]);

			//sumerr = sumerr + error + error1 + error2 + error3;
		}
		//calculated the BER
		avgerr = sumerr / (ITERATION*THENUMBEROFDATA);
		fprintf(fp1,"%.7f\n",avgerr);		

		printf("%.7f\n", avgerr);
	}
	fclose(fp1);
}
// modulation function
double modulation(int *data)
{
	int m_data;
	if (*data==1)
	{
		if(*(data+1)==1)
		{
			m_data=1;
		}
		else
		{
			m_data=3;
		}
	}
	else
	{
		if(*(data+1)==1)
		{
			m_data=-1;
		}
		else
		{
			m_data=-3;
		}		
	}
	return (m_data);
}
// demodulation function
void demodulation(double *r_data)
{
	if (r_data[0]>=0.0)
	{
		if (r_data[0]>=sqrt(1.0/10.0)*2.0)
		{
			r_data[0]=1;
     		r_data[1]=0;
		}
		else
		{
			r_data[0]=1;
			r_data[1]=1;
		}
	}
	else
	{
		if (r_data[0]<=sqrt(1.0/10.0)*(-2.0))
		{
			r_data[0]=0;
     		r_data[1]=0;
		}
		else
		{
			r_data[0]=0;
     		r_data[1]=1;
		}
	}
}
// error check function
int bercheck(int data, double d_data)
{
	int error=0;
	if ((double)data==d_data)
	{
		error=0;
	}
	else
	{
		error=1;
		//printf("error occured\n");
	}
	return (error);
}

void convolution(int *data, int *codeddata)
{
	int a = data[0];
	int b = 0;
	int c = 0;
	int N =0;
	//int codeddata[12];
	for(N=0;N<=(THENUMBEROFDATA+1);N++)
	{
		codeddata[2*N] = a^b^c;
		codeddata[2*N+1] = a^c;
		a = data[N+1];
		b = data[N];
		if(N == 0)
		{
			c = 0;
		}else
		{
			c = data[N-1];
		}
		if(N>=(THENUMBEROFDATA-1))
		{
			a=0;
		}
		if(N>=THENUMBEROFDATA)
		{
			b=0;
		}
	}
}

void viterbi_decode(int *d_data, int *decode_data)
{
	int s[4][(THENUMBEROFDATA+3)];
	int k1;
	int k2;
	int c[(THENUMBEROFDATA+2)];
	int l1;
//	int l2;
	int i;
	int l;
	for (i = 0;i<=3;i++)
	{
		for(l=0;l<=THENUMBEROFDATA+2;l++)
		{
			s[i][l]=9;
		}
	}
    s[0][0]=0;
	s[0][1]=(d_data[0]^0)+(d_data[1]^0);
	s[1][1]=(d_data[0]^1)+(d_data[1]^1);
	s[0][2]=s[0][1]+(d_data[2]^0)+(d_data[3]^0);
	s[1][2]=s[0][1]+(d_data[2]^1)+(d_data[3]^1);
	s[2][2]=s[1][1]+(d_data[2]^1)+(d_data[3]^0);
	s[3][2]=s[1][1]+(d_data[2]^0)+(d_data[3]^1);
	
	for(k2=3;k2<=(THENUMBEROFDATA+2);k2++)
	{
		for(k1=0;k1<=3;k1++)
		{
			if(k1==0)
			{
				s[k1][k2]=comparison(s[k1][k2-1]+(d_data[2*(k2-1)]^0)+(d_data[2*(k2-1)+1]^0), s[k1+2][k2-1]+(d_data[2*(k2-1)]^1)+(d_data[2*(k2-1)+1]^1));
			}
			else if(k1==1)
			{
				s[k1][k2]=comparison(s[k1-1][k2-1]+(d_data[2*(k2-1)]^1)+(d_data[2*(k2-1)+1]^1), s[k1+1][k2-1]+(d_data[2*(k2-1)]^0)+(d_data[2*(k2-1)+1]^0));
			}
			else if(k1==2)
			{
				s[k1][k2]=comparison(s[k1-1][k2-1]+(d_data[2*(k2-1)]^1)+(d_data[2*(k2-1)+1]^0), s[k1+1][k2-1]+(d_data[2*(k2-1)]^0)+(d_data[2*(k2-1)+1]^1));
			}
			else if(k1==3)
			{
				s[k1][k2]=comparison(s[k1-2][k2-1]+(d_data[2*(k2-1)]^0)+(d_data[2*(k2-1)+1]^1), s[k1][k2-1]+(d_data[2*(k2-1)]^1)+(d_data[2*(k2-1)+1]^0));
			}
		}
	}
    
	if((s[0][(THENUMBEROFDATA+1)]+(d_data[2*(THENUMBEROFDATA+1)]^0)+(d_data[2*(THENUMBEROFDATA+1)+1]^0))==comparison(s[0][(THENUMBEROFDATA+1)]+(d_data[2*(THENUMBEROFDATA+1)]^0)+(d_data[2*(THENUMBEROFDATA+1)+1]^0) , s[2][(THENUMBEROFDATA+1)]+(d_data[2*(THENUMBEROFDATA+1)]^1)+(d_data[2*(THENUMBEROFDATA+1)+1]^1)))
	{
		c[(THENUMBEROFDATA+1)] = 0;
		decode_data[(THENUMBEROFDATA-1)]=0;
	}
	else 
	{
		c[(THENUMBEROFDATA+1)] = 2;
		decode_data[(THENUMBEROFDATA-1)]=0;
	}
	for (l1=(THENUMBEROFDATA+1);l1>=1;l1--)
	{
		if (c[l1]==0)
		{
			if((s[0][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^0))==comparison(s[0][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^0),s[2][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^1)))
			{
				c[l1-1] = 0;
				decode_data[l1-1]=0;
			}
			else 
			{
				c[l1-1] = 2;
				decode_data[l1-1]=0;
			}
		}else if(c[l1]==1)
		{
			if((s[0][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^1))==comparison(s[0][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^1),s[2][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^0)))
			{
				c[l1-1] = 0;
				decode_data[l1-1]=1;
			}
			else 
			{
				c[l1-1] = 2;
				decode_data[l1-1]=1;
			}
		}else if(c[l1]==2)
		{
			if((s[1][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^0))==comparison(s[1][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^0),s[3][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^0)))
			{
				c[l1-1] = 1;
				decode_data[l1-1]=0;
			}
			else 
			{
				c[l1-1] = 3;
				decode_data[l1-1]=0;
			}
		}else if(c[l1]==3)
		{
			if((s[1][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^1))==comparison(s[1][l1-1]+(d_data[2*(l1-1)]^0)+(d_data[2*(l1-1)+1]^1),s[3][l1-1]+(d_data[2*(l1-1)]^1)+(d_data[2*(l1-1)+1]^0)))
			{
				c[l1-1] = 1;
				decode_data[l1-1]=1;
			}
			else 
			{
				c[l1-1] = 3;
				decode_data[l1-1]=1;
			}
		}
	}
	/*
		for(l=0;l<=THENUMBEROFDATA+1;l++)
		{
			printf("%d ",c[l]);
		}
	printf("\n");
	
	for(i=0;i<=3;i++)
	{
		for(l=0;l<=THENUMBEROFDATA+2;l++)
		{
			printf("%d",s[i][l]);	
		}
		printf("\n");
	}*/
	
}

int comparison(int com1, int com2)
{
	int com3;
	if(com1>=com2)
	{
		com3=com2;
	}else
	{
		com3=com1;
	}
	return (com3);
}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -