Hello, Can somebody please tell me how to generate a noise signal on the basis of its statistical characteristics? i want to create a c++ function with the following syntax: ============================================================= valarray<double> GenerateNoise(int type,double* stats, size_t sample_size) ============================================================= arguments: type - GAUSSIAN, POISSON, UNIFORM stats - an array of moments stats[0] = mean stats[1] = variance sample_size - size of noise signal required ============================================================= return value: valarray<double> of size sample_size ============================================================= Now what i want to know is a good way to compute the noise values. I would prefer to compute these values in a flexible manner so that i can configure the noise type easily. ideas please. im trying on my own too but suggestions are definitely going to reduce the time ill take to finish this function. thankx siddharth
Random Noise generators
Started by ●January 17, 2005
Reply by ●January 17, 20052005-01-17
siddharth.vaghela@gmail.com wrote:> Hello, > Can somebody please tell me how to generate a noise signal on thebasis> of its statistical characteristics? > > i want to create a c++ function with the following syntax: > > ============================================================= > valarray<double> GenerateNoise(int type,double* stats, size_t > sample_size) > ============================================================= > arguments: > > type - GAUSSIAN, POISSON, UNIFORM > > stats - an array of moments > stats[0] = mean > stats[1] = variance > > sample_size - size of noise signal required > ============================================================= > return value: > > valarray<double> of size sample_size > ============================================================= > > Now what i want to know is a good way to compute the noise values. I > would prefer to compute these values in a flexible manner so that ican> configure the noise type easily. > > ideas please. im trying on my own too but suggestions are definitely > going to reduce the time ill take to finish this function. > thankx > > siddharthThe uniform dist is the easy one, you already have that in C. I think the function is called rand(). You basically needs to write a wrap-around that maps the uniform <0,1> distribution accourding to your mean/variance specification. The Gaussian distribution mapping function can be found, I think, in "Numerical Recipies in C". The Poisson distribution is a bit more awkward. First of all, I believe you need more than two moments to specify it. Second, it is not clear how to map a uniform distribution to a Poisson distribution. I remember I asked that question here a couple of years ago, but no one were able to help me with that one. Rune
Reply by ●January 17, 20052005-01-17
" type - GAUSSIAN, POISSON, UNIFORM " Siddharth, remember the proof of the theorem that there exists a random variable X for any left-continuous monotonic function F: R -> [0,1] such that X has distribution function F? It is constructive, ie. it shows how to construct X. The idea is to set X = F^-1(U), where U is a uniform random variable on [0,1]. There are some details to take care when calculating F^-1, the generalized inverse of F (this is called the transformation method). Another method is to look at the (continuous) density function f and and generate the random variable X with density f via a two-dimensional random variable which is uniformly distributed on the area under f (rejection method). The usual trick to generate a Gaussian random variable from a uniform random variable is by using the Central Limit Theorem. I've read here before that adding 12 unifromly distributed random variables gives a "close enough" approximation. You can calculate the density of this by convolution of the uniform distribution and thus bound the approximation error. Read all about it in Numerical Recipes (http://www.nr.com). Regards, Andor
Reply by ●January 17, 20052005-01-17
hey thank u.... i finally got my hands on the Numerical Recipes book :) so yes im developing the functions now. also im trying to build a class wrapper for the random sequence generators.
Reply by ●January 17, 20052005-01-17
Reply by ●January 17, 20052005-01-17
siddharth.vaghela@gmail.com wrote:> Hello, > Can somebody please tell me how to generate a noise signal on the basis > of its statistical characteristics?... There is a whole set of rngs in Csound (look via csounds.com), including poisson. Richard Dobson
Reply by ●January 18, 20052005-01-18
siddharth.vaghela@gmail.com wrote:> Hello, > Can somebody please tell me how to generate a noise signal on the basis > of its statistical characteristics? > > i want to create a c++ function with the following syntax: > > ============================================================= > valarray<double> GenerateNoise(int type,double* stats, size_t > sample_size) > ============================================================= > arguments: > > type - GAUSSIAN, POISSON, UNIFORM > > stats - an array of moments > stats[0] = mean > stats[1] = variance > > sample_size - size of noise signal required > ============================================================= > return value: > > valarray<double> of size sample_size > ============================================================= > > Now what i want to know is a good way to compute the noise values. I > would prefer to compute these values in a flexible manner so that i can > configure the noise type easily. > > ideas please. im trying on my own too but suggestions are definitely > going to reduce the time ill take to finish this function. > thankx > > siddharth >If your application allows use of open source code, then have a look at GNU Scientific Library (GSL) at http://www.gnu.org/software/gsl/ Also worth looking are the packages hosted on http://www.netlib.org Its simple enough to right functions to convert a uniform distribution to any arbirary one; but libraries like GSL do make a life a lot more easier. Using the Numerical Recipies book is also a good idea. Except that their calling convention sometimes is not favored. Also, many of functions in NR aren't the most optimum available (this I'm sure with regards to FFT where beating FFTW is difficult). Regards, Aditya Sane <Please remove NOSPAM before replying>
Reply by ●January 19, 20052005-01-19
Here is what i have written by myself: reference is the prbability book by Lyon Garcia. please let me know if i can make this basic class any better. class Random { public: double gaussian(const double& m = 0.0, const double& d = 1.0); int poisson(const double& a); int geometric(const double& p); int uniformDis(const int& i, const int& j); double expon(const double& a); inline double uniformCon(const double& a = 0.0, const double& b = 1.0); inline double uniform(); public: Random(); Random(const unsigned int& seed); virtual ~Random(); private: unsigned int seed; class InvalidParams {}; }; // Random.cpp: implementation of the Random class. // ////////////////////////////////////////////////////////////////////// #include "Random.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Random::Random(): seed(time(0)) //default seed set to system time state 0 { srand(seed); } Random::Random(const unsigned int& seed): seed(seed) //user defined seed { srand(seed); } Random::~Random() { } ////////////////////////////////////////////////////////////////////////// //Uniform Random Number Generator ////////////////////////////////////////////////////////////////////////// //Range: [0,1) ////////////////////////////////////////////////////////////////////////// inline double Random::uniform() { return ((double)rand()/(double)(RAND_MAX+1)); } ////////////////////////////////////////////////////////////////////////// //Continuous Uniform Random Number Generator ////////////////////////////////////////////////////////////////////////// //Range: [a,b] ////////////////////////////////////////////////////////////////////////// inline double Random::uniformCon(const double& a,const double& b) { return (a + (b - a)*uniform()); } ////////////////////////////////////////////////////////////////////////// //Discrete Uniform Random Number Generator ////////////////////////////////////////////////////////////////////////// //Range: [i,j] ////////////////////////////////////////////////////////////////////////// int Random::uniformDis(const int& i,const int& j) { return (i + (j - i + 1.0) * uniform()); } ////////////////////////////////////////////////////////////////////////// //Exponential Random Number Generator with parameter a ////////////////////////////////////////////////////////////////////////// double Random::expon(const double &a) { try { if (a == 0.0) throw InvalidParams(); return (-log(uniform())/a); } catch(InvalidParams) { cout << "INVALID PARAMETER TO EXPON() - DIVIDE BY ZERO ERROR" << endl; return 0.0; } } ////////////////////////////////////////////////////////////////////////// //Geometric Random Number Generator with parameter p ////////////////////////////////////////////////////////////////////////// //generates a geometric random variable S = {0,1,2,...} with parameter p ////////////////////////////////////////////////////////////////////////// int Random::geometric(const double &p) { try { if (p == 0.0) throw InvalidParams(); return ((int)(log(uniform())/log(1.0 - p))); } catch(InvalidParams) { cout << "INVALID PARAMETER TO GEOMETRIC() - DIVIDE BY ZERO ERROR" << endl; return 0; } } ////////////////////////////////////////////////////////////////////////// //Poisson Random Number generator with mean a ////////////////////////////////////////////////////////////////////////// int Random::poisson(const double &a) { int i; double u,p,f; i = 0; f = p = exp(-a); u = uniform(); while(f <= u) { p *= (a / (i + 1.0)); f += p; i++; } return i; } /////////////////////////////////////////////////////////////////////////// //Gaussian Random Number generator with mean m and std deviation d /////////////////////////////////////////////////////////////////////////// double Random::gaussian(const double &m, const double &d) { static double t = 0.0; double x,v1,v2,r; if (t == 0.0) { do { v1 = 2.0 * uniform() - 1.0; v2 = 2.0 * uniform() - 1.0; r = v1 * v1 + v2 * v2; } while (r >= 1.0); r = sqrt((-2.0 * log(r)) / r); t = v2 * r; return (m + v1 * r * d); } else { x = t; t = 0.0; return (m + x * d); } }
Reply by ●January 19, 20052005-01-19