January 28, 2011
C/C++ create random noise (gaussian noise/white noise)
I was amazed when use randn command at Matlab. randn command will generate random data every we call that command. After I search at google, I found how to make this happen. I get this code at seismic unix source code. This code will generate random noise or white noise with Gaussian method. Code for main.c is :
#include <stdio.h>
#include <stdlib.h>
#include "frannor.h"
int main(int argc, char **argv)
{
double *noise=NULL;
int i;
int ndata;
unsigned int seed;
if(argc!=2)
{
fprintf(stderr, "usage : random 5");
exit(0);
}
ndata = atoi(argv[1]);
if (-1 == (seed = (unsigned int) time((time_t *) NULL)))
{
fprintf(stderr, "time() failed to set seed");
exit(0);
}
srannor(seed); //seed random number generator
noise = (double*) calloc (ndata, sizeof(double));
for(i=0; i<ndata; i++) //create random data
{
/* Compute noise vector elements in [-1, 1] */
/* GAUSS METHOD. frannor gives elements in N(0,1)--ie. pos & negs */
noise[i] = (double) frannor();
}
for(i=0; i<ndata; i++)
printf("%3.2f ", noise[i]);
printf("\n");
free(noise); //free allocated memory
return(1);
}
This is code for frannor.h :
#ifndef FRANNOR_H_ #define FRANNOR_H_ #include <math.h> #define ABS(x) ((x) < 0 ? -(x) : (x)) #define AA 12.37586 #define Bsu 0.4878992 #define Csu 12.67706 #define C1 0.9689279 #define C2 1.301198 #define PC 0.01958303 #define XN 2.776994 #define OXN 0.3601016 #define NBITS 24 /* macro to generate a random number uni uniform on [0,1) */ #define UNI(uni) \ uni = u[i]-u[j]; if (uni<0.0) uni += 1.0; u[i] = uni; \ if (--i<0) i = 16; if (--j<0) j = 16 float frannor(void); void srannor (int seed); #endif /* FRANNOR_H_ */
This is code for frannor.c :
/* Copyright (c) Colorado School of Mines, 2010.*/
/* All rights reserved. */
/*********************** self documentation **********************/
/*****************************************************************************
FRANNOR - functions to generate a pseudo-random float normally distributed
with N(0,1); i.e., with zero mean and unit variance.
frannor return a normally distributed random float
srannor seed random number generator for normal distribution
******************************************************************************
Function Prototypes:
float frannor (void);
void srannor (int seed);
******************************************************************************
frannor:
Input: (none)
Returned: normally distributed random float
srannor:
Input:
seed different seeds yield different sequences of random numbers.
******************************************************************************
Notes:
Adapted from subroutine rnor in Kahaner, Moler and Nash (1988)
which in turn was based on an algorithm by
Marsaglia and Tsang (1984).
******************************************************************************
References:
"Numerical Methods and Software", D.
Kahaner, C. Moler, S. Nash, Prentice Hall, 1988.
Marsaglia G. and Tsang, W. W., 1984,
A fast, easily implemented method for sampling from decreasing or symmetric
unimodal density functions: SIAM J. Sci. Stat. Comput., v. 5, no. 2,
p. 349-359.
*****************************************************************************
Author: Dave Hale, Colorado School of Mines, 01/21/89
*****************************************************************************/
/**************** end self doc ********************************/
#include "frannor.h"
static float v[]={
0.3409450, 0.4573146, 0.5397793, 0.6062427, 0.6631691,
0.7136975, 0.7596125, 0.8020356, 0.8417227, 0.8792102, 0.9148948,
0.9490791, 0.9820005, 1.0138492, 1.0447810, 1.0749254, 1.1043917,
1.1332738, 1.1616530, 1.1896010, 1.2171815, 1.2444516, 1.2714635,
1.2982650, 1.3249008, 1.3514125, 1.3778399, 1.4042211, 1.4305929,
1.4569915, 1.4834526, 1.5100121, 1.5367061, 1.5635712, 1.5906454,
1.6179680, 1.6455802, 1.6735255, 1.7018503, 1.7306045, 1.7598422,
1.7896223, 1.8200099, 1.8510770, 1.8829044, 1.9155830, 1.9492166,
1.9839239, 2.0198430, 2.0571356, 2.0959930, 2.1366450, 2.1793713,
2.2245175, 2.2725185, 2.3239338, 2.3795007, 2.4402218, 2.5075117,
2.5834658, 2.6713916, 2.7769943, 2.7769943, 2.7769943, 2.7769943
};
/* internal state variables for uniform random number generator */
static int i=16,j=4;
static float u[]={
0.8668672834288, 0.3697986366357, 0.8008968294805,
0.4173889774680, 0.8254561579836, 0.9640965269077,
0.4508667414265, 0.6451309529668, 0.1645456024730,
0.2787901807898, 0.06761531340295, 0.9663226330820,
0.01963343943798, 0.02947398211399, 0.1636231515294,
0.3976343250467, 0.2631008574685
};
float frannor(void)
/**************************************************************************
return a normally distributed random float
***************************************************************************
Returned: normally distributed random float
**************************************************************************/
{
int k;
float uni,vni,rnor,x,y,s,bmbx,xnmx;
/* uni is uniform on [0,1) */
UNI(uni);
/* vni is uniform on [-1,1) */
vni = uni+uni-1.0;
/* k is in range [0,63] */
k = ((int)(u[i]*128))%64;
/* fast part */
rnor = vni*v[k+1];
if (ABS(rnor)<=v[k]) return rnor;
/* slow part */
x = (ABS(rnor)-v[k])/(v[k+1]-v[k]);
UNI(y);
s = x+y;
if (s<=C2) {
if (s<=C1) return rnor;
bmbx = Bsu-Bsu*x;
if (y<=Csu-AA*exp(-0.5*bmbx*bmbx)) {
if (exp(-0.5*v[k+1]*v[k+1])+y*PC/v[k+1] <=
exp(-0.5*rnor*rnor)) return rnor;
do {
UNI(y);
x = OXN*log(y);
UNI(y);
} while (-2.0*log(y)<=x*x);
xnmx = XN-x;
return (rnor>=0.0 ? ABS(xnmx) : -ABS(xnmx));
}
}
bmbx = Bsu-Bsu*x;
return (rnor>=0.0 ? ABS(bmbx) : -ABS(bmbx));
}
void srannor (int seed)
/*****************************************************************************
seed random number generator
******************************************************************************
Input:
seed different seeds yield different sequences of random numbers.
*****************************************************************************/
{
int ii,jj,ia,ib,ic,id;
float s,t;
i = 16;
j = 4;
ia=ABS(seed)%32707;
ib=1111;
ic=1947;
for (ii=0; ii<17; ii++) {
s = 0.0;
t = 0.5;
for (jj=0; jj<64; jj++) {
id = ic-ia;
if (id<0) {
id += 32707;
s += t;
}
ia = ib;
ib = ic;
ic = id;
t *= 0.5;
}
u[ii] = s;
}
}
To compile this source code, use command :
gcc main.c frannor.c -lm -o random
This is output from program :
toto@toto-laptop:/home/toto/$ ./random 6 0.08 1.78 -1.35 -1.03 1.62 0.07 toto@toto-laptop:/home/toto/$ ./random 6 1.12 1.32 0.73 -0.34 0.25 -0.58
7 Comments
Как домашние животные реагируют на музыку и громкие звуки?
Где лучше заказать продвижение сайта — на бирже фрилансеров или в агентстве?
Создание сайтов — кто несёт ответственность за баги, обнаруженные после финального запуска?
Как конкурентный анализ помогает, когда запускается SEO продвижение молодого сайта?
Как выбрать подрядчика для seo под ключ, чтобы не переплатить за воздух?
Как seo оптимизация сайта работает для мультиязычных проектов?