📄 simulation.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <math.h>
#include "Global.h"
#include "CoDec.h"
#include "Channel.h"
#include "ST.h"
#define ASTEP(x) ( (x) > 1 ? 0 : 1 )
#define STEP(x) ( (x) > 0 ? 0 : 1 )
IO IO;
Random Rnd;
SpcCoDec Spc;
CI ChipInterleaver;
ComplexChannel Channel;
RGCD AESE; // Rotating-demosulate GCD / Advanced ESE
CNM Matcher;
void MemoryAllocation( );
void FileNameGen( );
void Simulator( double sigma2 );
void DataGen( );
void ErrorCounter( int it, float *input );
void TransmitterSide( );
void OtherLayertoDecoder( float *input );
void DecodertoOtherLayer( float *input );
void ReceiverSide( float s2 );
void Product_Extrinsic( float *input );
void Division_Extrinsic( float *input );
/******************************************************************************************
function : Simulation initialization -- All initialization process of each layer and the
parameters check should be included here
**
****************************************************************************************/
void Initialization( )
{
float Each_infor_Num; // each time unit send information bit num.
float Total_bit; // each time unit send total bit num.
_Nt = NT;
_PathNum = PATHNUM;
_Nr = NR;
_NBit = NBIT;
_DataLen = DATALEN;
_CodewordLen = CODEWORDLEN;
_FrameLen = _CodewordLen / _NBit; //_CodewordLen / _Nt / _NBit;
if ( (float)_CodewordLen / (float)_NBit - (float)_FrameLen > 0.0001)
IO.ErrorMessage( "Frame Size Error in Initialization" );
MemoryAllocation( );
Rnd.SetState( 443 );
Channel.Init( _Nt, _PathNum, _Nr, _FrameLen );
Spc.Init( 1, _DataLen, _CodewordLen, EFOLDNUM, FFOLDNUM, NESTDIM, SPCTRELLISLEN, POLYSTATEORDER, NPOLY, DPOLY, _ScrambleNum);
// Spc.Init( 1, _DataLen, EFOLDNUM, FFOLDNUM, NESTDIM, SPCTRELLISLEN, POLYSTATEORDER, NPOLY, DPOLY, _ScrambleNum );
ChipInterleaver.Init( _CodewordLen );
Matcher.Init( _Nt*_NBit*_FrameLen, _CodewordLen * _Nt);//Matcher.Init( _Nt*_NBit*_FrameLen, _CodewordLen );
AESE.Init( _Nt, _PathNum, _Nr, _NBit, _FrameLen );
Each_infor_Num= Spc.Rate * NBIT ; // inform bit num. in a symbol "NBIT"
Total_bit= NT* NBIT;
Matcher.Rate= Each_infor_Num / Total_bit ;
_Rate = Matcher.Rate; //Spc.Rate * Matcher.Rate;
//_Rate is normalized according to the BPSK system
//i.e. for (2^N) QAM/PSK energry is normalized to N
FileNameGen( );
if( _RunTime == 1 ) IO.FileHeader( );
}
void MemoryAllocation( )
{
int nt, l, nr;
for( nt=0; nt<_Nt; nt++ ) for( l=0; l<_PathNum; l++ ) for( nr=0; nr<_Nr; nr++ )
_H[nt][l][nr] = new Complex [_FrameLen];
_Sb = new Complex [_Nr*(_FrameLen+_PathNum-1)];
_ProcessingData = new NumericType [_CodewordLen*_Nt];
}
void End( )
{
delete [] _Sb;
delete [] _ProcessingData;
ChipInterleaver.End( );
}
void FileNameGen( )
{
IO.FnInit( );
if( strcmp( _ChannelType, "AWGN" ) == 0 ) IO.FnJoin( "_AWGN_" );
else if( strcmp( _ChannelType, "SlowFade" ) == 0 ) IO.FnJoin( "_SlowFade" );
else if( strcmp( _ChannelType, "FastFade" ) == 0 ) IO.FnJoin( "_FastFade" );
else IO.ErrorMessage( "Unknow channel condition" );
// IO.FnJoin( "i" ); IO.FnJoin( (int) log10(RTOOLARGE1) );
// IO.FnJoin( "n" ); IO.FnJoin( (int) log10(RTOOLARGE2) );
// IO.FnJoin( "o" ); IO.FnJoin( (int) log10(RTOOLARGE3) );
IO.FnJoin( "_B" ); IO.FnJoin( (int) _NBit );
IO.FnJoin( "_Nt" ); IO.FnJoin( (int) _Nt );
IO.FnJoin( "_P" ); IO.FnJoin( (int) _PathNum );
IO.FnJoin( "_Nr" ); IO.FnJoin( (int) _Nr );
IO.FnJoin( "_D" ); IO.FnJoin( (int) _DataLen );
IO.FnJoin( "e" ); IO.FnJoin( (int) EFOLDNUM );
IO.FnJoin( "f" ); IO.FnJoin( (int) FFOLDNUM );
IO.FnJoin( "m" ); IO.FnJoin( (int) NESTDIM );
IO.FnJoin( "Np" ); IO.FnJoin( (int) NPOLY );
IO.FnJoin( "Dp" ); IO.FnJoin( (int) DPOLY );
IO.FnJoin( "Scram" ); IO.FnJoin( _ScrambleNum );
IO.FnJoin( "Rate" ); IO.FnJoin( _NBit * _Nt * _Rate );
IO.FnEnd( );
}
void SimulationProcess( )
{
int i, j, blockNum;
int w, x, y, z;
double chipSnr, sigma;
Rnd.SetState ( 4043, 107, 503, 1013 );//( 443, 17, 53, 113 );
for( i=0; i<_SimPt; i++ )
{
blockNum = 0;
for( j=0; j<_ItNum; j++ )
_BitError[j] = _FrameError[j] = 0;
if( _RunTime == 0 )
{
IO.SimStateRead( &_SnrStart, &i, &blockNum, &w, &x, &y, &z, _BitError, _FrameError );
Rnd.SetState( w, x, y, z );
_RunTime = 1;
}
//For BPSK system Es is normalized to 1; M=Num. of Tr ante. ; Eb/No=M/2MRSigma2=1/2RSigma
//For (2^N)PSK system Es is normalized to N
//Therefore, no need to change the value of R
chipSnr = _Rate * pow( 10, _SnrStart / 10 );
sigma = sqrt( 0.5 / chipSnr );
while( (_BitError[_ItNum-1] < _BitErrNum || blockNum < _MinBlockNum ) && blockNum < _MaxBlockNum )
{
blockNum++;
Simulator( sigma );
if( blockNum % _TempReport == 0 )
{
Rnd.ReadState( &w, &x, &y, &z );
IO.SimStateWrite( _SnrStart, i, blockNum, w, x, y, z, _BitError, _FrameError );
}
if( blockNum % _ReportGap == 0 ) IO.ScreenOut( _SnrStart, blockNum, _BitError, _FrameError );
}
IO.FileOut( _SnrStart, blockNum, _BitError, _FrameError );
_SnrStart += _SnrStep;
}
}
/******************************************************************************************
function : Data generation for the N users
******************************************************************************************/
void DataGen( )
{
int i;
for( i=0; i<_DataLen; i++ )
_RawData[i] = Rnd.RandomInt( ) % 2;
}
/******************************************************************************************
function : The Major Process of different layers should be included here
input : ChipSnr is the signal to noise ratio of each chip
******************************************************************************************/
void Simulator( double sigma )
{
int i;
for( i=0; i<_Nr*(_FrameLen+_PathNum-1); i++ ) _Sb[i].Re = _Sb[i].Im = 0;
DataGen( );
Channel.ChannelSetup( _ChannelType );
AESE.GetChannelInfo( _ChannelType );
TransmitterSide( );
Channel.AWGN( sigma, &_Sb[0], _Nr*(_FrameLen+_PathNum-1) );
ReceiverSide( (float) (sigma*sigma) );
}
/******************************************************************************************
function : Transmitter
******************************************************************************************/
void TransmitterSide( )
{
int nt, nr, i,m ;
//int XXXX[DD];
Spc.Encoder( &_ProcessingData[0].i, &_RawData[0] );
ChipInterleaver.Interleaver( &_ProcessingData[0].i );
m=0;
for (nt=0; nt<_Nt; nt++) for (i=0; i<_NBit*_FrameLen; i++ )
{ _ProcessingData[m].i = After_Int[nt][i];
m++;}
for( nr=0; nr<_Nr; nr++ ) for( i=nt=0; nt<_Nt; nt++, i+=(_NBit*_FrameLen) ) // if Nr>1, error
AESE.Encoder( nt, nr, &_ProcessingData[i].i, &_Sb[nr*(_FrameLen+_PathNum-1)] );
}
void ReceiverSide( float s2 )
{
int it;
AESE.PreDetectionSetup( _ChannelType, s2 );
Spc.PreDecode( );
for( it=0; it<_ItNum; it++ )
{
AESE.Input( s2, &_Sb[0], &_ProcessingData[0].f );
Product_Extrinsic( &_ProcessingData[0].f );
Spc.Decoder( 0, &_ProcessingData[0].f, "ParityRequire" );
ErrorCounter( it, &_ProcessingData[0].f );
Division_Extrinsic( &_ProcessingData[0].f );
AESE.Output( s2, &_ProcessingData[0].f );
}
}
void ErrorCounter( int it, float *input )
{
int i, tmp, Temp_BitError[100];
Temp_BitError[it]=0;
for( tmp=i=0; i<_DataLen; i++ )
if( _RawData[i] != STEP( input[i] ) )
{
_BitError[it] += 1; tmp = 1; Temp_BitError[it]+= 1;
}
_FrameError[it] += tmp;
//printf("Temp_BitError[it] = %d,%d, %f\n", it,Temp_BitError[it],(float)Temp_BitError[it]/DATALEN );
}
void Division_Extrinsic( float *input )
{
int i,j, m;
float temp[NT][CODEWORDLEN] ;
for ( j=0; j<NT; j++ )
for( i=0; i<_NBit*_FrameLen; i++ )
EXTRIN_Chip[j][i] =input[i]- EXTRIN_Chip[j][i]; ///???????????
// EXTRIN_Chip[j][i] =RClip3( (double) input[i] / (double) EXTRIN_Chip[j][i] ); ///???????????
for ( j=0; j<NT; j++ )
for( i=0; i<_NBit*_FrameLen; i++ )
temp[j][Interleaver_ST[j][i]] = EXTRIN_Chip[j][i];
m=0;
for ( j=0; j<NT; j++ )
for( i=0; i<_NBit*_FrameLen; i++ )
{
input[m] = temp[j][i];
m++;
}
}
void Product_Extrinsic(float *input )
{
int i,j,k,s, m;
float temp[NT][CODEWORDLEN] ;
float tmp;
m=0;
for (j=0; j<NT; j++ )
{
m=j *_NBit ; s=0;
for ( i=0; i< _FrameLen; i++ )
{
for (k=0; k<_NBit; k++ )
{
temp[j][s] = input[m]; s++;
m++;
}
m =m+ (NT-1) * _NBit;
}
}
for ( j=0; j<NT; j++ )
for( i=0; i<_NBit*_FrameLen; i++ )
EXTRIN_Chip[j][i]=temp[j][Interleaver_ST[j][i]] ;
for( i=0; i<_NBit*_FrameLen; i++ )
{
tmp = 0.0;
for ( j=0; j<NT; j++ )
tmp += EXTRIN_Chip[j][i];
input[i] = tmp;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -