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

📄 codec.cpp

📁 Turbo码性能仿真源程序信道编码方面的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}		
	}

	m = TrellisLen;
	for( i=0; i<NodeOrder; i++ )
	{
		for( j=0; j<NodeNum; j++ )
		{
			if( ConvSpc.Bcode[j][0] == 0 ) ConvSpc.CodeInf[m][j][0] = RClip3( Tail[2*i] * Tail[2*i+1] );
			else ConvSpc.CodeInf[m][j][0] = Tail[2*i];
			if( ConvSpc.Bcode[j][1] == 0 ) ConvSpc.CodeInf[m][j][1] = Tail[2*i+1];
			else ConvSpc.CodeInf[m][j][1] = 1;
		}
		m++;
	}
}
/******************************************************************************************
function : sub-function of SpcCoDec::Apriori( float *Parity )
******************************************************************************************/
void SpcCoDec::PrePrtDec( float *Zin, float *Parity, float *bf, int blength )
{
	int i, m = blength - 1;
	float a=1;

	if( blength > 1 )
	{
		bf[blength-2] = Zin[m--];
		for( i=blength-3; i>=0; i--) bf[i] = Plr( bf[i+1], Zin[m--] );
		a = Zin[m++];
		*Parity = Plr( bf[0], a );
		for( i=1; i<blength-1; i++)
		{
			bf[i] = Plr( bf[i], a );
			a = Plr( Zin[m++], a );
		}
		bf[i]= a;
	}
//	else if( blength == 1 ) { bf[0]=TOOLARGE; *Parity=*Zin; } 
	else if( blength == 1 ) { bf[0]=RTOOLARGE3; *Parity=*Zin; } 

}
/******************************************************************************************
function : parity likelihood ratio -- handle the probability likelihood value
******************************************************************************************/
float SpcCoDec::Plr( float x, float y )
{
	return ( x * y + 1 ) / ( x + y );
}

/******************************************************************************************
function : pre-decoding of turbo-SPC
******************************************************************************************/
void SpcCoDec::PreDecode( )
{
	int i, j, nuser;

	for( nuser=0; nuser<NUser; nuser++ ) for( i=0; i<NestDim; i++ ) for( j=0; j<DataLen; j++ )
		ExInf[nuser][i][j] = 1;
}






/******************************************************************************************
function : initialization of the convolutional CODEC
            allocate the dynamic memory and setup **Flnk, **Bcode, etc
input    : _NodeOrder, _TrellisLen, _Npoly and _Dpoly
******************************************************************************************/
void Conv::Init( int _NodeOrder, int _TrellisLen, int _Npoly, int _Dpoly )
{
	NodeOrder	= _NodeOrder;
	NodeNum		= ( 1 << NodeOrder );
	TrellisLen	= _TrellisLen;
	Conv::SysCodeTable( _Npoly, _Dpoly );
	Conv::TailGen( );
}
/******************************************************************************************
function : convolutional encoder
input    : _DataIn and _StartS
output   : _ParityOut and _Ends
******************************************************************************************/
void Conv::Encoder( int *_DataIn, int *_ParityOut, int *_EndS )
{
	int i;

//	for( i=0; i<TrellisLen; i++ )
	for( i=0; i<TrellisLen-NodeOrder; i++ )
	{
		_ParityOut[i] = Bcode[*_EndS][_DataIn[i]];
		*_EndS = Flnk[*_EndS][_DataIn[i]];
	}
}
/******************************************************************************************
function : convolutional decoder
input    : _StartProb and _EndProb ( _CodeInf[][2][2] -- a priori branch probability)
output   : _Rcd[][4] -- a posteriori branch probability
******************************************************************************************/
void Conv::BCJR( float *_StartProb, float *_EndProb )
{
	Conv::BwSearch( _StartProb, _EndProb );
	Conv::AppDecode( _StartProb, _EndProb );
}
/******************************************************************************************
function : a posteriori probability decoding of each trellis section
input    : _StartProb and _EndProb ( _CodeInf[][2][2] )
output   : _Rcd[][4]
******************************************************************************************/
void Conv::AppDecode( float *_StartProb, float *_EndProb )
{
	int i, j;

	for( i=0; i<TrellisLen; i++ )
	{
		for( j=0; j<4; j++ ) aPP[i][j] = 0;
		for( j=0; j<NodeNum; j++ )
		{
			if( Bcode[j][0] == 0 )
				aPP[i][0] += Rcd[i][j] * CodeInf[i][j][0] * Rcd[i+1][Flnk[j][0]];
			else//if( Bcode[j][0] == 1 )
				aPP[i][1] += Rcd[i][j] * CodeInf[i][j][0] * Rcd[i+1][Flnk[j][0]];
			if( Bcode[j][1] == 0 )
				aPP[i][2] += Rcd[i][j] * CodeInf[i][j][1] * Rcd[i+1][Flnk[j][1]];
			else//if( Bcode[j][1] == 1 )
				aPP[i][3] += Rcd[i][j] * CodeInf[i][j][1] * Rcd[i+1][Flnk[j][1]];	
		}
		Conv::FwSearch( i );
	}
	for( i=0; i<NodeNum; i++ )
	{
		_StartProb[i] = tmp[i];
		_EndProb[i] = Rcd[TrellisLen][i];
	}
}
/******************************************************************************************
function : forward search of the BCJR decoding algorithm
******************************************************************************************/
void Conv::FwSearch( int i )
{
	int j;

	for( j=0; j<NodeNum; j++ ) Rcd[i+1][j] = 0;
	for( j=0; j<NodeNum; j++ )
	{
		Rcd[i+1][Flnk[j][0]] += Rcd[i][j] * CodeInf[i][j][0];
		Rcd[i+1][Flnk[j][1]] += Rcd[i][j] * CodeInf[i][j][1];
	}
	Conv::StateNorm( &Rcd[i+1][0] );
}
/******************************************************************************************
function : backward search of the BCJR decoding algorithm
input    : _StartProb and _EndProb
output   : _Rcd[][4]
******************************************************************************************/
void Conv::BwSearch( float *_StartProb, float *_EndProb )
{
	int i, j;

	for( i=0; i<NodeNum; i++ )
		Rcd[TrellisLen][i] = _EndProb[i];  // Initialization of the backward search
	for( i=TrellisLen-1; i>=0; i-- )
	{
		for( j=0; j<NodeNum; j++ )
			Rcd[i][j] = Rcd[i+1][Flnk[j][0]] * CodeInf[i][j][0] + Rcd[i+1][Flnk[j][1]] * CodeInf[i][j][1];
		StateNorm( &Rcd[i][0] );
	}
	for( i=0; i<NodeNum; i++ )
	{
		tmp[i] = Rcd[0][i];
		Rcd[0][i] = _StartProb[i];
	}
}
/******************************************************************************************
function : normalization the probability of the state
input    : Rcd[i][]
******************************************************************************************/
void Conv::StateNorm( float *rcd )
{
	int i;
	float a=0;

	for( i=0; i<NodeNum; i++ ) a += rcd[i];
	for( i=0; i<NodeNum; i++ ) rcd[i] /= a;
}

/******************************************************************************************
function : setup Flnk[][]
input    : _Npoly and _Dpoly
******************************************************************************************/
void Conv::SysCodeTable( int Npoly, int Dpoly )
{
	int i, j, m, n;

	for( i=0; i < NodeNum; i++ )
	{
		m = (i<<1) & Dpoly;
		for( n=0, j=1; j<=NodeOrder; j++ )
			n ^= (m>>j) % 2;
		n &= (Dpoly%2);					//n is the feedback

		j = i & ( NodeNum / 2 - 1 );		//i is current state, j is next state

		Flnk[i][0] = n + ( j << 1 );
		Flnk[i][1] = ( 1 ^ n ) + ( j << 1);

		Conv::BranchCode( i, n, Npoly );
	}
}
/******************************************************************************************
function : setup Bcode[][]
input    : _Npoly, current state (i) and feedback input (n)
******************************************************************************************/
void Conv::BranchCode( int i, int n, int Npoly )
{
	int n0, n1, j;

	n0 = (i<<1) + n;
	n1 = (i<<1) + (1^n);

	n0 &= Npoly;
	n1 &= Npoly;

	Bcode[i][0] = Bcode[i][1] = 0;

	for( j=0; j<=NodeOrder; j++ )
	{
		Bcode[i][0] ^= (n0>>j) % 2;
		Bcode[i][1] ^= (n1>>j) % 2;
	}
}

void Conv::TailGen( )
{
	int i, j, k, tmp;
	int TailState[POLYSTATENUM];

	for( i=0; i<NodeNum; i++ ) for( j=0; j<NodeNum; j++ )
	{
		tmp = i;
		for( k=0; k<NodeOrder; k++ ) tmp = Flnk[tmp][(j>>k)&1];
		if( tmp == 0 ) { TailState[i] = j; j = NodeNum; }
	}

	for( i=0; i<NodeNum; i++ ) for( j=0, k=i; j<NodeOrder; j++ )
	{
		tmp = ( TailState[i] >> j ) & 1;
		TermTable[i][2*j] = tmp;
		TermTable[i][2*j+1] = Bcode[k][tmp];
		k = Flnk[k][tmp];
	}
}

⌨️ 快捷键说明

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