In communication system simulator, a Gaussian noise generator is generally computed using the box Muller law. This method allows noising both amplitude and phase a given complex value. It is defined with these two equations:
/* noiseblk Scicos Gaussian random generator block
* Type 4 simulation function ver 1.0 - scilab-3.0
* 22 décembre 2004 - IRCOM GROUP - Author : A.Layec
*/
/* REVISION HISTORY :
* $Log$
*/
#include "scicos_block.h"
#include <math.h>
#include <stdlib.h> /*pour RAND_MAX*/
#define M_PI 3.14159265358979323846
/* noiseblkv_c routine de calcul d'échantillons bruités par la méthode "Box Muller Law"
*
* Entrées :
* n : taille des vecteurs
* typ : type de sortie (0:cos/1:sin)
* sig : vecteurs des variances
* mean : vecteurs des moyennes
* Sorties :
* y : vecteur des sorties
*
* dépendances
* math.h
*/
void noiseblkv_c(int *n,int *typ,double *sig,double *mean,double *y_i,double *y_q)
{
/*déclaration des variables*/
int i;
double rand1, rand2;
double rand_m;
double ampl, phase;
/*récupération de la valeur de RAND_MAX*/
rand_m=RAND_MAX;
for(i=0;i<(*n);i++)
{
/*calcul rand1*/
rand1=rand()/rand_m;
/*test rand1*/
while((rand1<=0)||(rand1>=1)) rand1=rand()/rand_m;
/*calcul rand2*/
rand2=rand()/rand_m;
/*test rand2*/
while((rand2<=0)||(rand2>=1)) rand2=rand()/rand_m;
/*Calcul amplitude et phase*/
ampl=sig[i]*sqrt(-log(rand1));
phase=2*M_PI*rand2;
/*Calcul y*/
switch(*typ)
{
case 0 :
{
y_i[i]=mean[i]+ampl*cos(phase);
break;
}
case 1 :
{
y_q[i]=mean[i]+ampl*sin(phase);
break;
}
case 2 :
{
y_i[i]=mean[i]+ampl*cos(phase);
y_q[i]=mean[i]+ampl*sin(phase);
break;
}
}
}
return;
}
void noiseblk(scicos_block *block,int flag)
{
/*Déclaration des variables*/
double *y1,*y2;
int ny,typ;
/*récupération de l'adresses des ports réguliers*/
y1=(double *)block->outptr[0];
/*récupère taille de sortie*/
ny=block->outsz[0];
/*récupère le type de générateur*/
typ=block->ipar[1];
if(flag==6)
{
srand(block->ipar[0]);
}
else if(flag==1)
{
switch(typ)
{
case 0 :
{
/*Appel noiseblk_c*/
noiseblkv_c(&ny,&typ,&block->rpar[0],&block->rpar[ny],&y1[0],y2);
break;
}
case 1 :
{
/*Appel noiseblk_c*/
noiseblkv_c(&ny,&typ,&block->rpar[0],&block->rpar[ny],y2,&y1[0]);
break;
}
case 2 :
{
/*récupération de l'adresse de sortie*/
y2=(double *)block->outptr[1];
/*Appel noiseblk_c*/
noiseblkv_c(&ny,&typ,&block->rpar[0],&block->rpar[ny],&y1[0],&y2[0]);
break;
}
}
}
}