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

📄 main.cpp

📁 IDMA的基本的C++的仿真图
💻 CPP
字号:
//*******************************************************************************/
//              Interleave-Division Multiple-Access (IDMA)
//
//  This is a simulation program for uncoded IDMA system with BPSK modulation
//	and real channel. For details, please refer to this paper:
//	W. K. Leung, Lihai Liu and Li Ping, "Interleaving-based multiple access
//	and iterative chip-by-chip multi-user detection," IEICE Trans. on Commun.,
//	vol. E86-B, pp. 3634-3637, Dec. 2003.
//	or http://www.ee.cityu.edu.hk/~liping/Research/Journal/idma.pdf
//
//																W.K.Leung
//																April 2005
//*******************************************************************************/
#include <stdio.h>  
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include "define.h"

const int		_NUser		= NUSER;
const int		_DataLen	= DATALEN;
const int		_SpreadLen	= SPREADLEN;
const int		_ChipLen	= CHIPLEN;
const int		_ItNum		= ITNUM;
const int		_Block		= BLOCK;
const int		_EbNoNum	= EBNONUM;
const double	_EbNoStart	= EBNOSTART;
const double	_EbNoStep	= EBNOSTEP;

int		Data[NUSER][DATALEN];
int		ScrambleRule[NUSER][CHIPLEN];
double	Ber[ITNUM];
double	H[NUSER], H2[NUSER];	// H2[.] = H[.] * H[.]
double	Chip[NUSER][CHIPLEN];
double	Tx[NUSER][CHIPLEN];
double	Rx[CHIPLEN];
double	SpreadSeq[SPREADLEN];
double	TotalMean[CHIPLEN];
double	TotalVar[CHIPLEN];
double	Mean[NUSER][CHIPLEN];
double	Var[NUSER][CHIPLEN];
double	AppLlr[NUSER][DATALEN];
double	Ext[NUSER][CHIPLEN];

void	Transmitter( );
void	Channel( double sigma );
double	RandFloat( );
void	Receiver( double sigma );
void	Initialization( double sigma );
void	DeSpreader( int nuser, double *appllr, double *chip );
void	EnergyProfile( );
double	ErrorCounter( );

void main( )
{
	int i, j, nuser, tmp, block;
	double snr, sigma, ebno, error;

	// Setup the energy level of each user.
	 EnergyProfile( );

	// Generate the spreading sequence: {+1, -1, +1, -1, ... }.
	for( i=0; i<_SpreadLen; i++ ) SpreadSeq[i] = 1 - 2 * ( i % 2 );

	// Generate the interleaving index.
	for( nuser=0; nuser<_NUser; nuser++ ) 
	{
		for( i=0; i<_ChipLen; i++ ) ScrambleRule[nuser][i] = i;
		for( i=0; i<_ChipLen-1; i++ ) 
		{
			j = i + ( rand() * rand() ) % ( _ChipLen - i );
			tmp = ScrambleRule[nuser][i];
			ScrambleRule[nuser][i] = ScrambleRule[nuser][j];
			ScrambleRule[nuser][j] = tmp;
		}
	}

	printf("IDMA: User#=%i, DataLen=%i, SpreadLen=%i and It#=%i\n", _NUser, _DataLen, _SpreadLen, _ItNum );
	// The simulation process.
	for( i=0; i<_EbNoNum; i++ )
	{
		ebno = _EbNoStart + (double) i * _EbNoStep;
		snr = pow( 10, ebno / 10 ) / (double) _SpreadLen;
		sigma = sqrt( 0.5 / snr );

		error = 0;
		for( block=1; block<=_Block; block++ )
		{
			Transmitter( );
			Channel( sigma );
			Receiver( sigma );
			error += ErrorCounter( );
			printf("Block#=%6i, EbNo=%2.2fdB, BER=%1.3e%c", block, ebno, error / (double) (_NUser * _DataLen * block ), 0x0d );
		}
		printf("\n");
	}
}

void Transmitter( )
{
	int i, j, m, nuser;
	double tmp;

	// Data Generation.
	for( nuser=0; nuser<_NUser; nuser++ ) for( i=0; i<_DataLen; i++ )
		Data[nuser][i] = rand() % 2;

	// Spreading process.
	for( nuser=0; nuser<_NUser; nuser++ ) for( m=i=0; i<_DataLen; i++ )
	{
		tmp = 1 - ( 2 * Data[nuser][i] );
		for( j=0; j<_SpreadLen; j++ ) Chip[nuser][m++] = tmp * SpreadSeq[j];
	}

	// Interleaving process.
	for( nuser=0; nuser<_NUser; nuser++ ) for( i=0; i<_ChipLen; i++ )
		Tx[nuser][i] = Chip[nuser][ScrambleRule[nuser][i]];
}

void Channel( double sigma )
{
	int i, nuser;

	for( i=0; i<_ChipLen; i++ )
	{
		// Additive white Gaussian noise.
		Rx[i] = sigma * sqrt( -2.0 * log( RandFloat() ) ) * cos( 6.283185307 * RandFloat() );

		// Multiple access channel and energy scaling.
		for( nuser=0; nuser<_NUser; nuser++ ) Rx[i] += H[nuser] * Tx[nuser][i];
	}
}

// Serial receiver
void Receiver( double sigma )
{
	int i, j, m, nuser, it;

	Initialization( sigma );

	for( it=0; it<_ItNum; it++ ) for( nuser=0; nuser<_NUser; nuser++ )
	{
		// Produce the LLR values for the de-interleaved chip sequence.
		for( i=0; i<_ChipLen; i++ )	
		{
			TotalMean[i] -= Mean[nuser][i];
			TotalVar[i] -= Var[nuser][i];
			Chip[nuser][ScrambleRule[nuser][i]] = 2 * H[nuser] * ( Rx[i] - TotalMean[i] ) / TotalVar[i];
		}

		// De-spreading operation.
		DeSpreader( nuser, &AppLlr[nuser][0], &Chip[nuser][0] );

		// Feed the AppLlr to decoder, if there is a FEC codec in the system.

		// Spreading operation: Produce the extrinsic LLR for each chip
		for( m=i=0; i<_DataLen; i++ ) for( j=0; j<_SpreadLen; j++, m++ )
			Ext[nuser][m] = SpreadSeq[j] * AppLlr[nuser][i] - Chip[nuser][m];

		// Update the statistic variable together with the interleaving process.
		for( i=0; i<_ChipLen; i++ )
		{
			Mean[nuser][i] = H[nuser] * tanh( Ext[nuser][ScrambleRule[nuser][i]] / 2 );
			Var[nuser][i] = H2[nuser] - Mean[nuser][i] * Mean[nuser][i];
			TotalMean[i] += Mean[nuser][i];
			TotalVar[i] += Var[nuser][i];
		}
	}
}

/*
// Parallel receiver
void Receiver( double sigma )
{
	int i, j, m, nuser, it;
	double s2 = sigma * sigma;

	Initialization( sigma );

	for( it=0; it<_ItNum; it++ )
	{
		for( nuser=0; nuser<_NUser; nuser++ )
		{
			// Produce the LLR values for the de-interleaved chip sequence.
			for( i=0; i<_ChipLen; i++ )	
				Chip[nuser][ScrambleRule[nuser][i]]
					= 2 * H[nuser] * ( Rx[i] - ( TotalMean[i] - Mean[nuser][i] ) ) / ( TotalVar[i] - Var[nuser][i] );
	
			// De-spreading operation.
			DeSpreader( nuser, &AppLlr[nuser][0], &Chip[nuser][0] );

			// Feed the AppLlr to decoder, if there is a FEC codec in the system.

			// Spreading operation: Produce the extrinsic LLR for each chip
			for( m=i=0; i<_DataLen; i++ ) for( j=0; j<_SpreadLen; j++, m++ )
				Ext[nuser][m] = SpreadSeq[j] * AppLlr[nuser][i] - Chip[nuser][m];
		}
	
		// Update the statistic variable together with the interleaving process.
		for( i=0; i<_ChipLen; i++ )
		{
			TotalMean[i] = 0;
			TotalVar[i] = s2;
		}
		for( nuser=0; nuser<_NUser; nuser++ ) for( i=0; i<_ChipLen; i++ )
		{
			Mean[nuser][i] = H[nuser] * tanh( Ext[nuser][ScrambleRule[nuser][i]] / 2 );
			Var[nuser][i] = H2[nuser] - Mean[nuser][i] * Mean[nuser][i];
			TotalMean[i] += Mean[nuser][i];
			TotalVar[i] += Var[nuser][i];
		}
	}
}
*/

void DeSpreader( int nuser, double *appllr, double *chip )
{
	int i, j, m;

	for( m=i=0; i<_DataLen; i++ )
	{
		appllr[i] = SpreadSeq[0] * chip[m++];
		for( j=1; j<_SpreadLen; j++ ) appllr[i] += SpreadSeq[j] * chip[m++];
	}
}

double ErrorCounter( )
{
	int i, nuser;
	double e = 0;

	for( nuser=0; nuser<_NUser; nuser++ ) for( i=0; i<_DataLen; i++ )
		e += ( Data[nuser][i] != STEP( AppLlr[nuser][i] ) );

	return e;
}

void Initialization( double sigma )
{
	int i, nuser;
	double s2 = sigma * sigma;

	for( i=0; i<_ChipLen; i++ )
	{
		TotalMean[i] = 0;
		TotalVar[i] = s2;
	}
	for( nuser=0; nuser<_NUser; nuser++ ) for( i=0; i<_ChipLen; i++ )
	{
		Mean[nuser][i] = 0;
		Var[nuser][i] = H2[nuser];
		TotalVar[i] += H2[nuser];			
	}
}

double RandFloat( )
{
	// Generate a uniform distributed varable in the interval (0,1).
	return (double) ( rand() + 1 ) / (double) ( RAND_MAX + 2 );
}

⌨️ 快捷键说明

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