📄 system.cpp
字号:
//**************************************************************//
// //
// August 2002 //
// by //
// Leung, Raymond Wai-Kong //
// //
// //
//**************************************************************//
#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <math.h>
#include "Global.h"
#include "ST.h"
extern Random Rnd;
extern RGCD AESE;
//Constant of Modular Arithmetic Generator
const int Random::A = 48271;
const int Random::M = 2147483647;
const int Random::Q = 44488;
const int Random::R = 3399;
//Constant of Wichmann/Hill Generator
const int Random::A1 = 171;
const int Random::A2 = 172;
const int Random::A3 = 170;
const int Random::M1 = 30269;
const int Random::M2 = 30307;
const int Random::M3 = 30323;
//Box-Muller Method
const double Random::pi2 = 6.2831853071795864;
//------------------------------Interleaver------------------------------------
//function : permutation
//input : *rule, length, scrnum
void Scramble( int *rule, int length, int scrnum )
{
int i, j, n, r, q;
int **buffer, *rbuffer;
q = (int) sqrt( length );
if( q*q < length ) q++;
rbuffer = new int [q];
buffer = new int* [q];
for( i=0; i<q; i++ ) buffer[i] = new int [q];
for( n=0, i=0; i<q; i++ ) for( j=0; j<q; j++ )
{
if( n < length ) buffer[i][j] = rule[n++];
else buffer[i][j] = -1;
}
for( n=0; n<scrnum; n++ )
{
for( i=0; i<q; i++ )
{
r = Rnd.RandomInt( ) % q;//r = rand( ) % q;//random variables
for( j=0; j<q; j++ ) rbuffer[j] = buffer[i][j];
for( j=0; j<q; j++ ) buffer[i][j] = rbuffer[(j+r)%q];
}
for( j=0; j<q; j++ )
{
r = Rnd.RandomInt( ) % q;//r = rand( ) % q;//random variables
for( i=0; i<q; i++ ) rbuffer[i] = buffer[i][j];
for( i=0; i<q; i++ ) buffer[i][j] = rbuffer[(i+r)%q];
}
}
for( n=0, i=0; i<q; i++ ) for( j=0; j<q; j++ )
if( buffer[i][j] > -1 ) rule[n++] = buffer[i][j];
for( i=0; i<q; i++ )
delete [] buffer[i];
delete [] buffer;
delete [] rbuffer;
}
//function : used in the EF-interleaver
//input : *x, length, shift
void CyclicShift( int *x, int length, int shift )
{
int j, m;
int *bf = new int [length];
for( m=shift, j=0; j<length-shift; j++ ) bf[j] = x[m++];
for( m=0, j=length-shift;j<length;j++) bf[j] = x[m++];
for(j=0;j<length;j++) x[j]=bf[j];
delete [] bf;
}
//----------------------------Input/Output function----------------------------------
//function : format an int data and place it in the string named string.
// use .FnInit( ) to initialize the function FnInit -- File name initialization
void IO::FnInit( )
{
ptrN = ptrT = 0;
}
//input : num -- Attach an int number to the file name
void IO::FnJoin( int num )
{
ptrN += sprintf( FileN + ptrN, "%d", num );
ptrT += sprintf( FileT + ptrT, "%d", num );
}
//input : num -- Attach a float number with only 2 decimal to the file name
void IO::FnJoin( float num )
{
ptrN += sprintf( FileN + ptrN, "%1.3f", num );
ptrT += sprintf( FileT + ptrT, "%1.3f", num );
}
//input : *prefix -- Attach a string to the file name
void IO::FnJoin( char *prefix )
{
ptrN += sprintf( FileN + ptrN, "%s", prefix );
ptrT += sprintf( FileT + ptrT, "%s", prefix );
}
void IO::FnEnd( )
{
ptrN += sprintf( FileN + ptrN, ".txt" );
ptrT += sprintf( FileT + ptrT, ".bin" );
}
//function : output the simulation parameters into the file
void IO::FileHeader( )
{
fstream file;
int i;
file.open( FileN, ios::out );
if( !file )
{
cout << "Error -- Cannot write the result into the file : Header" << endl;
exit (-1);
}
for( i=0; i<_NBit; i++ )
{
file << "ModeAng[" << i << "]=(" << AESE.ModAng[i].Re << "," << AESE.ModAng[i].Im << ")" << endl;
cout << "ModeAng[" << i << "]=(" << AESE.ModAng[i].Re << "," << AESE.ModAng[i].Im << ")" << endl;
}
file << _SimulationMode << endl; cout << _SimulationMode << endl;
file << _ChannelType << endl; cout << _ChannelType << endl;
file << "Nt = " << (int)_Nt << endl; cout << "Nt = " << (int)_Nt << endl;
file << "Path Number = " << (int)_PathNum << endl; cout << "Path Number = " << (int)_PathNum << endl;
file << "Nr = " << (int)_Nr << endl; cout << "Nr = " << (int)_Nr << endl;
file << "Data length = " << (int)_DataLen << endl; cout << "Data length = " << (int)_DataLen << endl;
file << "E-Fold Number = " << (int)EFOLDNUM << endl; cout << "E-Fold Number = " << (int)EFOLDNUM << endl;
file << "F-Fold Number = " << (int)FFOLDNUM << endl; cout << "F-Fold Number = " << (int)FFOLDNUM << endl;
file << "NestDim = " << (int)NESTDIM << endl; cout << "NestDim = " << (int)NESTDIM << endl;
file << "State Order = " << (int)POLYSTATEORDER << endl; cout << "State Order = " << (int)POLYSTATEORDER << endl;
file << "N-Polynomial = " << (int)NPOLY << endl; cout << "N-Polynomial = " << (int)NPOLY << endl;
file << "D-Polynomial = " << (int)DPOLY << endl; cout << "D-Polynomial = " << (int)DPOLY << endl;
file << "Frame Length = " << _FrameLen << endl; cout << "Frame Length = " << _FrameLen << endl;
file << "MinBlockNum = " << _MinBlockNum << endl; cout << "MinBlockNum = " << _MinBlockNum << endl;
file << "MaxBlockNum = " << _MaxBlockNum << endl; cout << "MaxBlockNum = " << _MaxBlockNum << endl;
file << "\t";
for( i=1; i<=_ItNum; i++ )
file << "It=" << i << "\t";
file << "\t";
for( i=1; i<=_ItNum; i++ )
file << "It=" << i << "\t";
file << endl;
file.close( );
}
//function : output the intermediate result in the screen
//input : Snr, BlockNum, *Error
void IO::ScreenOut( double snr, int blockNum, int *bitError, int *frameError )
{
int a=500;
if ( ( (float)blockNum/(float)a - blockNum/a ) < 0.00001)
{
cout << "e=" << bitError[_ItNum-1];
cout << ", snr=" << _SnrStart << "dB, ";
cout.setf( ios::scientific );
if( bitError[_ItNum-1] > 0 )
cout << " BER=" << (float) bitError[_ItNum-1] / (float) ( blockNum * _DataLen );
else
cout << " BER<" << 1 / (float) ( blockNum * _DataLen );
if( frameError[_ItNum-1] > 0 )
cout << " FER=" << (float) frameError[_ItNum-1] / (float) ( blockNum );
else
cout << " FER<" << 1 / (float) ( blockNum );
cout.unsetf( ios::scientific );
cout << " #k=" << blockNum << endl;
}
}
//function : output the result to the file of the simulation point
void IO::FileOut( float snr, int blockNum, int *bitError, int *frameError )
{
fstream file;
int i;
file.open( FileN, ios::app );
if( !file )
{
cout << "Cannot write the result into the file : Content" <<endl;
exit (-1);
}
file << snr << "\t";
file.setf( ios::scientific );
for( i=0; i<_ItNum; i++ )
file << ( bitError[i] / (float) ( blockNum * _DataLen ) ) << "\t";
file << "\t";
for( i=0; i<_ItNum; i++ )
file << ( frameError[i] / (float) blockNum ) << "\t";
file.unsetf( ios::scientific );
file << "#k=" << blockNum << endl;
file.close( );
}
void IO::ImportantEorrorMessage( char *message )
{
fstream file;
file.open( FileN, ios::app );
if( !file )
{
cout << "Cannot write the Important message into the file!!!" <<endl;
exit (-1);
}
file << message << endl;
cout << "ERROR -- " << message << endl;
}
void IO::SimStateWrite( float snr, int simpt, int blockNum, int w, int x, int y, int z, int *bitError, int *frameError )
{
fstream file;
int i;
file.open( FileT, ios::out );
if( !file )
{
cout << "Error -- Cannot write the result into the Bin file" << endl;
exit (-1);
}
file << snr << endl;
file << simpt << endl;
file << blockNum << endl;
file << w << endl;
file << x << endl;
file << y << endl;
file << z << endl;
for( i=0; i<_ItNum; i++ )
{
file << bitError[i] <<endl;
file << frameError[i] <<endl;
}
file.close( );
}
void IO::SimStateRead( float *snr, int *simpt, int *blockNum, int *w, int *x, int *y, int *z, int *bitError, int *frameError )
{
int i;
fstream file;
file.open( FileT, ios::in|ios::nocreate );
if( !file )
{
cout << "Error -- Cannot read the Bin file --> " << FileT << endl;
exit (-1);
}
file >> *snr;
file >> *simpt;
file >> *blockNum;
file >> *w;
file >> *x;
file >> *y;
file >> *z;
for( i=0; i<_ItNum; i++ )
{
file >> bitError[i];
file >> frameError[i];
}
file.close( );
}
void IO::ErrorMessage( char *message )
{
cout << "ERROR -- " << message << endl;
exit(-1);
}
//-------------------------------Random number generator--------------------------------------
//Modular Arithmetic Generator
void Random::SetState( int s )
{
StateS = s;
}
void Random::ReadState( int *s )
{
*s = StateS;
}
void Random::IntNextSate( int *s )
{
int tmpState = A * ( *s % Q ) - R * ( *s / Q );
if( tmpState >= 0 )
*s = tmpState;
else
*s = tmpState + M;
}
int Random::RandomInt( )
{
Random::IntNextSate( &StateS );
return StateS;
}
//Wichmann/Hill Generator
void Random::SetState( int x, int y, int z )
{
StateX = x;
StateY = y;
StateZ = z;
}
void Random::ReadState( int *x, int *y, int *z )
{
*x = StateX;
*y = StateY;
*z = StateZ;
}
void Random::DoubleNextState( int *x, int *y, int *z )
{
*x = ( *x * A1 ) % M1;
*y = ( *y * A2 ) % M2;
*z = ( *z * A3 ) % M3;
}
double Random::RandomDouble( )
{
double tmp;
Random::DoubleNextState( &StateX, &StateY, &StateZ );
tmp = (double) StateX / (double) M1 + (double) StateY / (double) M2 + (double) StateZ / (double) M3;
return tmp - (double) ( (int) tmp );//mod 1 operatoion
}
//Both Wichmann/Hill and Modular Arithmetic Generator
void Random::SetState( int s, int x, int y, int z )
{
StateS = s;
StateX = x;
StateY = y;
StateZ = z;
}
void Random::ReadState( int *s, int *x, int *y, int *z )
{
*s = StateS;
*x = StateX;
*y = StateY;
*z = StateZ;
}
//Box-Muller Method
float Random::RealNoise( double sigma )
{
double amp = sigma * sqrt( -2.0 * log( Random::RandomDouble( ) ) );
double angle = pi2 * Random::RandomDouble( );
return (float) ( amp * cos( angle ) );
}
Complex Random::ComplexNoise( double sigma )
{
Complex symbol;
double amp = sigma * sqrt( -2.0 * log( Random::RandomDouble( ) ) );
double angle = pi2 * Random::RandomDouble( );
symbol.Re = (float) ( amp * cos( angle ) );
symbol.Im = (float) ( amp * sin( angle ) );
return symbol;
}
Complex Random::RayleighGenerator( float p )
{
double angle = pi2 * Random::RandomDouble( );
double amp = sqrt( -log( Random::RandomDouble( ) ) ) / p;
Complex h;
h.Re = (float) ( amp * cos( angle ) );
h.Im = (float) ( amp * sin( angle ) );
return h;
}
Complex operator + ( const Complex& a, const Complex& b )
{
Complex result;
result.Re = a.Re + b.Re;
result.Im = a.Im + b.Im;
return result;
}
Complex operator - ( const Complex& a, const Complex& b )
{
Complex result;
result.Re = a.Re - b.Re;
result.Im = a.Im - b.Im;
return result;
}
Complex operator * ( const Complex& a, const Complex& b )
{
Complex result;
result.Re = a.Re * b.Re - a.Im * b.Im;
result.Im = a.Re * b.Im + a.Im * b.Re;
return result;
}
double LClip1( double x )
{
double A; A=70.0;
// if ( (x>40.0) ||(x<-40.0 ) )
// printf("rrrrrrrrrrrrrrrrrrrrrrr=========%20.10f\n",x); //?????????????????
if( x > A ) return A;
else if( x < -A ) return -A;
else return x;
}
/*
float LClip0( float x )
{
float A; A=8.0;
// if ( (x>40.0) ||(x<-40.0 ) )
// printf("rrrrrrrrrrrrrrrrrrrrrrr=========%20.10f\n",x); //?????????????????
if( x > A ) return A;
else if( x < -A ) return -A;
else return x;
}
float LClip2( float x )
{
if( x > (float) LTOOLARGE2 ) return (float) LTOOLARGE2;
else if( x < (float) LTOOSMALL2 ) return (float) LTOOSMALL2;
else return x;
}
float LClip3( float x )
{
if( x > (float) LTOOLARGE3 ) return (float) LTOOLARGE3;
else if( x < (float) LTOOSMALL3 ) return (float) LTOOSMALL3;
else return x;
}
float RClip1( double x )
{
if( x > (float) RTOOLARGE1 ) return (float) RTOOLARGE1;
else if( x < (float) RTOOSMALL1 ) return (float) RTOOSMALL1;
else return (float) x;
}
float RClip2( double x )
{
float tm;
tm=RTOOLARGE2;
if( x > (float) RTOOLARGE2 ) return (float) RTOOLARGE2;
else if( x < (float) RTOOSMALL2 ) return (float) RTOOSMALL2;
else return (float) x;
}
float RClip3( double x )
{
if( x > (float) RTOOLARGE3 ) return (float) RTOOLARGE3;
else if( x < (float) RTOOSMALL3 ) return (float) RTOOSMALL3;
else return (float) x;
}
float RClipT( double x )
{
if( ( 0.0 < x) && ( x < (float) TINY) ) return (float) TINY;
else if ( ((float) (-TINY) < x ) && ( x< 0.0 ) ) return (float) (-TINY);
else return (float) x;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -