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

📄 common.c

📁 B3g_phase2_C语言_Matlab程序及说明
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************
*Copyright (C) 2004 FUTURE@NCRL SEU
*All Rights Reserved.

*FileName: _COMMON_H_

*Abstract: Used for GMC System.

*Cue.Ver : V4.0
*Author  : Bin Jiang
*Date    : 2004-06-02
*Modify  : New detector:
           SIC with spatial domain filter.

*Pre.Ver : V3.0
*Author  : Bin Jiang
*Date    : 2004-04-08
*Modify  : Add multi-carrier modulation.

*Pre.Ver : V2.0
*Author  : Bin Jiang
*Date    : 2004-03-25
*Modify  : (1) Change the structure of detector.
           (2) Improve the channel estimation.

*Pre.Ver : V1.2
*Author  : Bin Jiang
*Date    : 2003-12-24

*Ref.    : Matlab Program.

*************************************/

#include "common.h"

//----------------------------------------------------------------------
//----------------------_COMPLEX_C_-------------------------------------
//----------------------------------------------------------------------
//Compute the energy of a.
double eng_cmx(COMPLEX a)
{
	double result;
	result = pow(a.real,2)+pow(a.image,2);

	return result;
}

//Compute the norm of a .
double abs_cmx(COMPLEX a)
{
	double result;
	result = sqrt( pow(a.real,2)+pow(a.image,2) );

	return result;
}


//Compute the conjugate of a .
COMPLEX conj_cmx(COMPLEX a)
{
	COMPLEX b;
	b.real  = a.real;
	b.image = -1*a.image;

	return b;
}

//Add two complex a and b.
COMPLEX add_cmx(COMPLEX a, COMPLEX b)
{
	COMPLEX result;

	result.real  = a.real  + b.real;
	result.image = a.image + b.image;

	return result;
}

//Subtract complex b from a.
COMPLEX sub_cmx(COMPLEX a, COMPLEX b)
{
	COMPLEX result;

	result.real  = a.real  - b.real;
	result.image = a.image - b.image;

	return result;
}

//Multiple complexs a and b.
COMPLEX mul_cmx(COMPLEX a, COMPLEX b)
{
	COMPLEX result;

	result.real  = a.real*b.real  - a.image*b.image;
	result.image = a.real*b.image + a.image*b.real;

	return result;
}

//Multiple complex a with a real b.
COMPLEX mul_cmxreal(COMPLEX a, double b)
{
	COMPLEX result;

	result.real  = a.real*b;
	result.image = a.image*b;

	return result;
}

//Divide complex a by real b.
COMPLEX div_cmxreal(COMPLEX a, double b)
{
	COMPLEX result;

	result.real  = a.real/b;
	result.image = a.image/b;

	return result;
}

//Divide complex a by complex b.
COMPLEX div_cmx(COMPLEX a, COMPLEX b)
{
	COMPLEX result;
	double	denominator = pow(b.real,2)+pow(b.image,2);

	result.real  = (a.real*b.real + a.image*b.image)/denominator;
	result.image = (a.image*b.real - a.real*b.image)/denominator;

	return result;
}
/* END _COMPLEX_C_ */


//----------------------------------------------------------------------
//----------------------_RANDOM_C_--------------------------------------
//----------------------------------------------------------------------
long s1,s2;

/*Generate a uniform random number between 0 and 1.*/
double random_source()
{
	long z,k;
	k = s1 / 53668L;
	s1 = 40014L * (s1 - k * 53668L) - k * 12211L;
	if(s1 < 0)
		s1 = s1 + 2147483563L;
	k = s2 / 52774;
	s2 = 40692L * (s2 - k * 52774L) - k * 3791L;
	if(s2 < 0)
		s2 = s2 + 2147483399L;
	z = s1 - s2;
	if(z < 1)
		z = z + 2147483562L;
	
	return (double) z / (double) 2147483563.0;
}

/*Generate a uniform random number between -1 and 1. */
double generate_random_source()
{
	double sign;
	if(random_source() >= 0.5)
		sign = -1.0;
	else
		sign = 1.0;
	return sign * random_source();
}

/*Generate a random number 0 and 1 with p0=p1=0.5.*/
int generate_binary_source()
{
	if(random_source() < 0.5)
		return 0;
	else
		return 1;
}

/*Generate a gaussian random with 0 mean sigma2 variance. */
double generate_gaussian_source(double sigma2)
{
	static int iset = 0;	/* It save the last value. */
	static double gset;
	double fac,r,v1,v2;
	
	if(iset == 0)
	{
		do
		{
			v1 = generate_random_source();
			v2 = generate_random_source();
			r = v1 * v1 + v2 * v2;
		}while(r >= 1.0 || r == 0.0);
		fac = sqrt(-2.0 * sigma2 * log(r) / r);
		gset = v1 * fac;
		iset = 1;
		return (double)(v2 * fac);
	}
	else
	{
		iset = 0;
		return (double)(gset);
	}
}
/* END _RANDOM_C_ */

//----------------------------------------------------------------------
//----------------------_INTERLEAVER_C_---------------------------------
//----------------------------------------------------------------------
//Generate a uniform random number between 0 and 1
double s_random_source(long *s1, long *s2)
{
	long z,k;
	
	k = (*s1) / 53668L;
	(*s1) = 40014L * ((*s1) - k * 53668L) - k * 12211L;
	if((*s1) < 0)
	{
		(*s1) += 2147483563L;
	}
	
	k = (*s2) / 52774;
	(*s2) = 40692L * ((*s2) - k * 52774L) - k * 3791L;
	if((*s2) < 0)
	{
		(*s2) += 2147483399L;
	}
	
	z = (*s1) - (*s2);
	if(z < 1)
	{
		z += 2147483562L;
	}
	
	return (double) z / (double) 2147483563.0;
}

//Generate interleaver table by S-interleaver.
void s_inter_generate(int N, int S, int *inter_index, long ss1, long ss2)
{
	int i,temp;

	int bit1,flag;

	int *index;
	
	long *s1,*s2;
	
	s1 = &ss1;
	s2 = &ss2;

	index = (int *)malloc(N*2*sizeof(int));
	if (index == NULL)
	{
		printf("not enough memery to alloc!\n");
		exit(0);
	}
	
	/* initialise all the array at -1 */
	for (i=0; i<N; i++)
	{
		index[i*2+0]=-1;
		index[i*2+1]=-1;
	}

	for (i=0; i<N; i++)
	{
		do
		{
			flag = 0;
			/* generate a random number between 0 and (N-1) */
			bit1=(int)(s_random_source(s1,s2)*(double) N);
			if (i>0)
			{
		    	/* check if two consecutive bits are at more than S */
		        temp=index[(i-1)*2+1]-bit1;
				if (temp<0)
					temp = -temp;
				if (temp>=S)
					flag = 1;
				/* check the condition 2 of the interleaver */
				if (i>3)
				{
					temp = index[(i-4)*2+1]-bit1;
					if (temp<0)
						temp = -temp;
					if ((temp!=4) && (flag==1))
						flag = 1;
					else
						flag = 0;
				}
			}
			else
			{
				flag = 1;
			}
		}while ( (index[bit1*2+0]!=-1) || (flag==0) );
		
		/* fill the results array if all the conditions are true */
		index[bit1*2+0] = 0;
		index[i*2+1] = bit1;
		inter_index[i] = index[i*2+1];
	}
	
	free(index);
	
}

void s_interleave_int(int * p_block, int N, int * p_InlvTable)
{
	int i;
	
	int * p_interleaved_block;
	p_interleaved_block = (int *)malloc(N*sizeof(int));
	
	for(i=0; i<N; i++)
	{
		*(p_interleaved_block+i) = *(p_block+(*(p_InlvTable+i)));
	}
	
	for(i=0; i<N; i++)
	{
		*(p_block+i) = *(p_interleaved_block+i);
	}
	
	free(p_interleaved_block);
}

void s_interleave_double(double * p_block, int N, int * p_InlvTable)
{
	int i;
	
	double * p_interleaved_block;
	p_interleaved_block = (double *)malloc(N*sizeof(double));
	
	for(i=0; i<N; i++)
	{
		p_interleaved_block[i] = p_block[p_InlvTable[i]];
	}
	
	for(i=0; i<N; i++)
	{
		p_block[i] = p_interleaved_block[i];
	}
	
	free(p_interleaved_block);
}

void s_deinterleave_double(double * p_block, int N, int * p_InlvTable)
{
	int i;
	
	double * p_deinterleaved_block;
	p_deinterleaved_block = (double *)malloc(N*sizeof(double));
	
	for(i=0; i<N; i++)
	{
		p_deinterleaved_block[p_InlvTable[i]] = p_block[i];
	}
	
	for(i=0; i<N; i++)
	{
		p_block[i] = p_deinterleaved_block[i];
	}
	
	free(p_deinterleaved_block);
}

/* END _INTERLEAVER_C_ */

//----------------------------------------------------------------------
//----------------------_MAP_C_-----------------------------------------
//----------------------------------------------------------------------
int GrayMapQAM(int * inBit, int bitlength, COMPLEX * outSymbol, int ModType)
{
	int i;
	int inpos  = 0;
	int outpos = 0;
	int con_site_r = 0;
	int con_site_i = 0;
	int M;
	double GrayMapQAM[64];
	
	if(bitlength%ModType)
	{
		puts("Wrong bit length for QAM modulation!");
		return -1;
	}
	
	switch(ModType)
	{
		case 2:
			GrayMapQAM[0] = -1/sqrt(2);  GrayMapQAM[1] =  1/sqrt(2);
			break;
		case 4:
			GrayMapQAM[0] = -1/sqrt(10); GrayMapQAM[1] = -3/sqrt(10);
			GrayMapQAM[2] =  1/sqrt(10); GrayMapQAM[3] =  3/sqrt(10);
			break;
		case 6:
			GrayMapQAM[0] = -3/sqrt(42); GrayMapQAM[1] = -1/sqrt(42); 
			GrayMapQAM[2] = -5/sqrt(42); GrayMapQAM[3] = -7/sqrt(42);
			GrayMapQAM[4] =  3/sqrt(42); GrayMapQAM[5] =  1/sqrt(42); 
			GrayMapQAM[6] =  5/sqrt(42); GrayMapQAM[7] =  7/sqrt(42);
			break;
		case 8:
			GrayMapQAM[0] =  -5/sqrt(170);  GrayMapQAM[1] =  -7/sqrt(170);
			GrayMapQAM[2] =  -3/sqrt(170);  GrayMapQAM[3] =  -1/sqrt(170); 
			GrayMapQAM[4] = -11/sqrt(170);  GrayMapQAM[5] =  -9/sqrt(170);  
			GrayMapQAM[6] = -13/sqrt(170);  GrayMapQAM[7] = -15/sqrt(170);
			GrayMapQAM[8] =   5/sqrt(170);  GrayMapQAM[9] =   7/sqrt(170); 
			GrayMapQAM[10] =  3/sqrt(170);  GrayMapQAM[11] =  1/sqrt(170); 
			GrayMapQAM[12] = 11/sqrt(170);  GrayMapQAM[13] =  9/sqrt(170);  
			GrayMapQAM[14] = 13/sqrt(170);  GrayMapQAM[15] = 15/sqrt(170);
			break;
		default:
			printf("Wrong modulation Type, only support 4QAM, 16QAM, 64QAM, 256QAM!");
			return -1;
	}
	
	M = ModType/2;
	
	while(inpos<bitlength)
	{
		con_site_r = 0;
		con_site_i = 0;
		
		for(i=0; i<M; i++)
		{
			if( *(inBit+inpos) ) con_site_r += (1<<(M-1-i));
			inpos++;	
		}
		
		for(i=0; i<M; i++)
		{
			if( *(inBit+inpos) ) con_site_i += (1<<(M-1-i));
			inpos++;
		}
		
		(outSymbol+outpos)->real  = GrayMapQAM[con_site_r];
		(outSymbol+outpos)->image = GrayMapQAM[con_site_i];
		outpos++;
	}
	
	return outpos;
}

int SoftDemod16QAM(COMPLEX * p_x_Intf, int n_IntfLen, double * p_x_Sigma, double * p_Rou, double * p_CodedBitLLR)
{
	int     i;
	int   	n_TxAntenna;
	int     n_SupDomain;
	int		LenPerTx = n_IntfLen/TxANTENNA_NUM; 
	
	double	mui;
	double 	sigma2i;
	double 	LLR1,LLR2,LLR3,LLR4;
	double 	Xi,Yi;
	
	double * p_oldLLR;
	p_oldLLR = (double *)malloc(TxANTENNA_NUM*LenPerTx*4*sizeof(double));
	
	for(i=0; i<TxANTENNA_NUM*LenPerTx*4; i++)
	{
		*(p_oldLLR+i) = *(p_CodedBitLLR+i);
	}
	
	
	for(n_TxAntenna=0; n_TxAntenna<TxANTENNA_NUM; n_TxAntenna++)
	{
		for(n_SupDomain=0; n_SupDomain<MAXSUPDOM; n_SupDomain++)
		{
			mui = p_Rou[n_SupDomain*TxANTENNA_NUM+n_TxAntenna];
			
			for(i=SUP_DOM[n_SupDomain]; i<SUP_DOM[n_SupDomain+1]; i++)
			{
				Xi = p_x_Intf[n_TxAntenna*LenPerTx+i].real;
				Yi = p_x_Intf[n_TxAntenna*LenPerTx+i].image;
				sigma2i = p_x_Sigma[n_TxAntenna*LenPerTx+i];
			
				/* First bit */
				LLR1 = -pow( (Xi - 1/sqrt(10)*mui), 2 )/sigma2i - 0.5*(p_oldLLR[(n_TxAntenna*LenPerTx+i)*4+1]);
				LLR2 = -pow( (Xi - 3/sqrt(10)*mui), 2 )/sigma2i + 0.5*(p_oldLLR[(n_TxAntenna*LenPerTx+i)*4+1]);
				LLR3 = -pow( (Xi + 1/sqrt(10)*mui), 2 )/sigma2i - 0.5*(p_oldLLR[(n_TxAntenna*LenPerTx+i)*4+1]);
				LLR4 = -pow( (Xi + 3/sqrt(10)*mui), 2 )/sigma2i + 0.5*(p_oldLLR[(n_TxAntenna*LenPerTx+i)*4+1]);
		
				//    SoftDetOut = [ SoftDetOut (log((exp(LLR1)+exp(LLR2))/(exp(LLR3)+exp(LLR4)))) ];

				p_CodedBitLLR[(n_TxAntenna*LenPerTx+i)*4+0] //= max(LLR1, LLR2) - max(LLR3, LLR4);
															//= log((exp(LLR1)+exp(LLR2))/(exp(LLR3)+exp(LLR4)));

⌨️ 快捷键说明

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