//*******************************************************************************/
// Interleave-Division Multiple-Access (IDMA)
//
// This is a simulation program for uncoded IDMA system with BPSK modulation
// and real channel. The performance of Monte Carlo simulation depends on the
// seed of the random number generator, the random interleavers, and the number
// of blocks simulated. For details, please refer to the following 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,
// (http://www.ee.cityu.edu.hk/~liping/Research/Journal/idma.pdf).
//
// Note that the curves for user numbers K=110 and K=120 in the above paper
// were generated using 30 iterations and information block length = 512.
// We aplogize for the inaccurate description on the simulation setting
// for K=110 and K=120 in the above paper.
//
// W.K.Leung
// April 2005
// May 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 RandDouble( );
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;
// Perform this for-loop more times may increase the randomness of the interleaver.
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( );
// We only report the average BER of all users.
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( RandDouble() ) ) * cos( 6.283185307 * RandDouble() );
// 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];
}
}
// Generate a uniform distributed varable in the interval (0,1).
double RandDouble( )
{
// We suggest user to replace a better random number gene
评论0