gaussian noise #224

Open
arturoc opened this Issue Aug 26, 2010 · 27 comments

Comments

Projects
None yet
7 participants
@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Dec 2, 2011

Member

source here: https://github.com/andyr0id/ofxGaussian
It's just a couple lines, could be checked and added to ofMath, if needed

Member

bilderbuchi commented Dec 2, 2011

source here: https://github.com/andyr0id/ofxGaussian
It's just a couple lines, could be checked and added to ofMath, if needed

@ghost ghost assigned bilderbuchi Mar 26, 2012

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Jun 7, 2012

Member

I think I'll implement this, and maybe also the slightly better Ziggurat algorithm. But while I was browsing through the random number functions, I noticed some wonky things:
e.g. randNum = rand()/(RAND_MAX + 1.0); this will never give 1. Is it by design that we have functions which are 0 to 1(exclusive), and analogously for the other functions, when the sdtlib function is 0 to RAND_MAX (inclusive)?
Judging from git blame, mostly @ofTheo and @ofZach wrote that code afaict.

Member

bilderbuchi commented Jun 7, 2012

I think I'll implement this, and maybe also the slightly better Ziggurat algorithm. But while I was browsing through the random number functions, I noticed some wonky things:
e.g. randNum = rand()/(RAND_MAX + 1.0); this will never give 1. Is it by design that we have functions which are 0 to 1(exclusive), and analogously for the other functions, when the sdtlib function is 0 to RAND_MAX (inclusive)?
Judging from git blame, mostly @ofTheo and @ofZach wrote that code afaict.

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Jul 2, 2012

Member

So @ofTheo and @ofZach, any input?

Member

bilderbuchi commented Jul 2, 2012

So @ofTheo and @ofZach, any input?

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Jul 16, 2012

Member

So @ofTheo and @ofZach, any input?

Member

bilderbuchi commented Jul 16, 2012

So @ofTheo and @ofZach, any input?

@ofTheo

This comment has been minimized.

Show comment
Hide comment
@ofTheo

ofTheo Jul 16, 2012

Contributor

@bilderbuchi so what you are saying is ofRandom(0, myVec.size()) will never = myVec.size() ?
and likewise ofRandom(0, 1) will never be 1.0 ?

@bilderbuchi if you want to do the implementation, that sounds good!

Contributor

ofTheo commented Jul 16, 2012

@bilderbuchi so what you are saying is ofRandom(0, myVec.size()) will never = myVec.size() ?
and likewise ofRandom(0, 1) will never be 1.0 ?

@bilderbuchi if you want to do the implementation, that sounds good!

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Jul 16, 2012

Member

I haven't confirmed this in code yet, but yes, RAND_MAX/(RAND_MAX+1) can never yield 1. If this is not by design I can correct it but I wasn't sure if there is some hidden design reason behind this, which is why I asked.

Member

bilderbuchi commented Jul 16, 2012

I haven't confirmed this in code yet, but yes, RAND_MAX/(RAND_MAX+1) can never yield 1. If this is not by design I can correct it but I wasn't sure if there is some hidden design reason behind this, which is why I asked.

@ofTheo

This comment has been minimized.

Show comment
Hide comment
@ofTheo

ofTheo Jul 16, 2012

Contributor

I always wrote code assuming it could be 1 - but maybe @ofZach or @arturoc might know more?
this could be a separate issue as changing it could have some big implications.

but def go ahead on the gaussian noise!

Contributor

ofTheo commented Jul 16, 2012

I always wrote code assuming it could be 1 - but maybe @ofZach or @arturoc might know more?
this could be a separate issue as changing it could have some big implications.

but def go ahead on the gaussian noise!

@ofZach

This comment has been minimized.

Show comment
Hide comment
@ofZach

ofZach Jul 16, 2012

Contributor

I think this may be a mistake, and worth looking at a fix for. (and also, looking at a few different implementations of random across platforms / environments just to be sure). I just took a look and alot of the random() implementations out there do seem to be written [0,1), ie from 0 and up to but not including 1. googling for "rand()/(RAND_MAX + 1.0)" is pretty interesting, and leads to alot of examples, which I guess this is based off of.

this is a really informative article:
http://www.azillionmonkeys.com/qed/random.html

at any rate, this seems wrong to me, and worth looking at a fix for.

Contributor

ofZach commented Jul 16, 2012

I think this may be a mistake, and worth looking at a fix for. (and also, looking at a few different implementations of random across platforms / environments just to be sure). I just took a look and alot of the random() implementations out there do seem to be written [0,1), ie from 0 and up to but not including 1. googling for "rand()/(RAND_MAX + 1.0)" is pretty interesting, and leads to alot of examples, which I guess this is based off of.

this is a really informative article:
http://www.azillionmonkeys.com/qed/random.html

at any rate, this seems wrong to me, and worth looking at a fix for.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Jul 16, 2012

Member

:) was going to post the same link

Member

arturoc commented Jul 16, 2012

:) was going to post the same link

@ofZach

This comment has been minimized.

Show comment
Hide comment
@ofZach

ofZach Jul 16, 2012

Contributor

actually, I'd have to dig back to older version of OF to check if this memory is true, but I think early on we had done random earlier on using %, and there was a link to this article in the code saying, let's fix this :) So this article is likely why we went with the RAND_MAX + 1....

Contributor

ofZach commented Jul 16, 2012

actually, I'd have to dig back to older version of OF to check if this memory is true, but I think early on we had done random earlier on using %, and there was a link to this article in the code saying, let's fix this :) So this article is likely why we went with the RAND_MAX + 1....

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Jul 17, 2012

Member

ok, got enough to work with/look up for now, thanks guys. :-)

Member

bilderbuchi commented Jul 17, 2012

ok, got enough to work with/look up for now, thanks guys. :-)

@bilderbuchi bilderbuchi referenced this issue in openframeworks/ofBook Feb 4, 2014

Merged

adds math chapters, unnumbered #14

@bilderbuchi bilderbuchi modified the milestones: 0.9.0, 0.9.1 Sep 3, 2014

@kylemcdonald kylemcdonald modified the milestones: 0.9.3, 0.9.1 Dec 6, 2014

@kylemcdonald

This comment has been minimized.

Show comment
Hide comment
@kylemcdonald

kylemcdonald Dec 11, 2014

Contributor

speaking of RNGs, i saw this was released recently http://www.pcg-random.org/

it has a feature-heavy c++ implementation, but there's also this version:

https://github.com/imneme/pcg-c-basic
https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.h
https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c

which is supposed to be super fast, and a good RNG implementation (see comparison on home page).

Contributor

kylemcdonald commented Dec 11, 2014

speaking of RNGs, i saw this was released recently http://www.pcg-random.org/

it has a feature-heavy c++ implementation, but there's also this version:

https://github.com/imneme/pcg-c-basic
https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.h
https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c

which is supposed to be super fast, and a good RNG implementation (see comparison on home page).

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 10, 2015

Contributor

How should we name this feature? ofGaussian with an overloaded function? or is this meant to replace the ofRandom functions?

Contributor

DomAmato commented Aug 10, 2015

How should we name this feature? ofGaussian with an overloaded function? or is this meant to replace the ofRandom functions?

@kylemcdonald

This comment has been minimized.

Show comment
Hide comment
@kylemcdonald

kylemcdonald Aug 10, 2015

Contributor

i'm think the api would just be ofRandomGaussian(float mean = 0., float std = 1.) and it would not replace ofRandom.

Contributor

kylemcdonald commented Aug 10, 2015

i'm think the api would just be ofRandomGaussian(float mean = 0., float std = 1.) and it would not replace ofRandom.

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 11, 2015

Contributor

Since there was discussion of moving to the light weight pcg random, they have a c++ implementation. its pretty simple, like 3 files

https://github.com/imneme/pcg-cpp

Contributor

DomAmato commented Aug 11, 2015

Since there was discussion of moving to the light weight pcg random, they have a c++ implementation. its pretty simple, like 3 files

https://github.com/imneme/pcg-cpp

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 11, 2015

Contributor
float ofRandomGaussian(float mean, float stddev) {
std::default_random_engine generator;
std::normal_distribution<float> distribution(mean, stddev);
return distribution(generator);
}

normal distributions were added in c++11 and I believe all of our platforms are now c++11 compliant?
http://www.cplusplus.com/reference/random/normal_distribution/

Contributor

DomAmato commented Aug 11, 2015

float ofRandomGaussian(float mean, float stddev) {
std::default_random_engine generator;
std::normal_distribution<float> distribution(mean, stddev);
return distribution(generator);
}

normal distributions were added in c++11 and I believe all of our platforms are now c++11 compliant?
http://www.cplusplus.com/reference/random/normal_distribution/

@kylemcdonald

This comment has been minimized.

Show comment
Hide comment
@kylemcdonald

kylemcdonald Aug 11, 2015

Contributor

yes, i think that's correct. though i'd look at how the seed for ofRandom works, reinitializing it on every call might be a problem?

regardless, if you could write a short example to demonstrate behavior and submit a PR that'd be great.

Contributor

kylemcdonald commented Aug 11, 2015

yes, i think that's correct. though i'd look at how the seed for ofRandom works, reinitializing it on every call might be a problem?

regardless, if you could write a short example to demonstrate behavior and submit a PR that'd be great.

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 12, 2015

Contributor

I dont think that the seeding works because it deals with a different subset of code. std::normal_distribution requires the header to be included and an engine to be created. We could create a static initialization. I think we would need multiple functions though because in order to set the parameters of the distribution (if someone decides to change it like how it is posted above) you have to create a new parameter and pass it in.

like so:

static std::default_random_engine generator;
static std::normal_distribution<float> distribution(0, 1);

float ofRandomGaussian(float mean, float stddev) {
    std::normal_distribution<float>::param_type _param(mean, stddev);
    distribution.param(_param);
    return distribution(generator);
}

float ofRandomGaussian() {
    //this assumes the parameters dont change just get another number from the distribution
    return distribution(generator);
 }
Contributor

DomAmato commented Aug 12, 2015

I dont think that the seeding works because it deals with a different subset of code. std::normal_distribution requires the header to be included and an engine to be created. We could create a static initialization. I think we would need multiple functions though because in order to set the parameters of the distribution (if someone decides to change it like how it is posted above) you have to create a new parameter and pass it in.

like so:

static std::default_random_engine generator;
static std::normal_distribution<float> distribution(0, 1);

float ofRandomGaussian(float mean, float stddev) {
    std::normal_distribution<float>::param_type _param(mean, stddev);
    distribution.param(_param);
    return distribution(generator);
}

float ofRandomGaussian() {
    //this assumes the parameters dont change just get another number from the distribution
    return distribution(generator);
 }
@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 12, 2015

Contributor

also c++11 added in a lot more random features:

bernoulli_distribution
binomial_distribution
cauchy_distribution
chi_squared_distribution
discrete_distribution
exponential_distribution
extreme_value_distribution
fisher_f_distribution
gamma_distribution
geometric_distribution
lognormal_distribution
negative_binomial_distribution
normal_distribution
piecewise_constant_distribution
piecewise_linear_distribution
poisson_distribution
student_t_distribution
uniform_int_distribution
uniform_real_distribution
weibull_distribution

Contributor

DomAmato commented Aug 12, 2015

also c++11 added in a lot more random features:

bernoulli_distribution
binomial_distribution
cauchy_distribution
chi_squared_distribution
discrete_distribution
exponential_distribution
extreme_value_distribution
fisher_f_distribution
gamma_distribution
geometric_distribution
lognormal_distribution
negative_binomial_distribution
normal_distribution
piecewise_constant_distribution
piecewise_linear_distribution
poisson_distribution
student_t_distribution
uniform_int_distribution
uniform_real_distribution
weibull_distribution

@kylemcdonald

This comment has been minimized.

Show comment
Hide comment
@kylemcdonald

kylemcdonald Aug 12, 2015

Contributor

I see, in that case the original version makes sense I think :) my
intuition was just that creating an object might be "slow" and there could
be some faster way, but send a PR and maybe someone else has more insight :)

I don't think any of the other distributions are common enough for our
usual applications to include.

On Wednesday, August 12, 2015, Dominic Amato notifications@github.com
wrote:

also c++11 added in a lot more random features:

bernoulli_distribution
binomial_distribution
cauchy_distribution
chi_squared_distribution
discrete_distribution
exponential_distribution
extreme_value_distribution
fisher_f_distribution
gamma_distribution
geometric_distribution
lognormal_distribution
negative_binomial_distribution
normal_distribution
piecewise_constant_distribution
piecewise_linear_distribution
poisson_distribution
student_t_distribution
uniform_int_distribution
uniform_real_distribution
weibull_distribution


Reply to this email directly or view it on GitHub
#224 (comment)
.

Contributor

kylemcdonald commented Aug 12, 2015

I see, in that case the original version makes sense I think :) my
intuition was just that creating an object might be "slow" and there could
be some faster way, but send a PR and maybe someone else has more insight :)

I don't think any of the other distributions are common enough for our
usual applications to include.

On Wednesday, August 12, 2015, Dominic Amato notifications@github.com
wrote:

also c++11 added in a lot more random features:

bernoulli_distribution
binomial_distribution
cauchy_distribution
chi_squared_distribution
discrete_distribution
exponential_distribution
extreme_value_distribution
fisher_f_distribution
gamma_distribution
geometric_distribution
lognormal_distribution
negative_binomial_distribution
normal_distribution
piecewise_constant_distribution
piecewise_linear_distribution
poisson_distribution
student_t_distribution
uniform_int_distribution
uniform_real_distribution
weibull_distribution


Reply to this email directly or view it on GitHub
#224 (comment)
.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 12, 2015

Member

we should be using thread_local storage for this so this calls are thread safe. although thread_local statics are not yet well supported by clang and old versions of gcc so you'll need to use:

#if HAS_TLS
static thread_local std::default_random_engine generator;
static thread_local std::normal_distribution<float> distribution(0, 1);
#else
static std::default_random_engine generator;
static std::normal_distribution<float> distribution(0, 1);
#endif

not sure if using an anonymous namespace instead of static would allow to use thread_local under clang:

namespace{
thread_local std::default_random_engine generator;
thread_local std::normal_distribution<float> distribution(0, 1);
}

also perhaps we shouldn't be wrapping things like this that are available in the std and are not that difficult to use and instead just have examples on how to used them

Member

arturoc commented Aug 12, 2015

we should be using thread_local storage for this so this calls are thread safe. although thread_local statics are not yet well supported by clang and old versions of gcc so you'll need to use:

#if HAS_TLS
static thread_local std::default_random_engine generator;
static thread_local std::normal_distribution<float> distribution(0, 1);
#else
static std::default_random_engine generator;
static std::normal_distribution<float> distribution(0, 1);
#endif

not sure if using an anonymous namespace instead of static would allow to use thread_local under clang:

namespace{
thread_local std::default_random_engine generator;
thread_local std::normal_distribution<float> distribution(0, 1);
}

also perhaps we shouldn't be wrapping things like this that are available in the std and are not that difficult to use and instead just have examples on how to used them

@bilderbuchi

This comment has been minimized.

Show comment
Hide comment
@bilderbuchi

bilderbuchi Aug 12, 2015

Member

also perhaps we shouldn't be wrapping things like this that are available in the std and are not that difficult to use and instead just have examples on how to used them

that also sounds like a sensible approach.

Member

bilderbuchi commented Aug 12, 2015

also perhaps we shouldn't be wrapping things like this that are available in the std and are not that difficult to use and instead just have examples on how to used them

that also sounds like a sensible approach.

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 12, 2015

Contributor

Still I wonder if we shouldn't port more of openframeworks over to C++11 standards and utilize the other random distribution engines. Pretty much all of ofRandom can be done using uniform_int_distribution or uniform_real_distribution since right now we are using rand() which is then put through a series of operations because of this http://www.azillionmonkeys.com/qed/random.html and in ofMath.h its even stated

\warning Many ofRandom-style functions wrap rand() which is not reentrant
/// or thread safe. To generate random numbers simultaneously in multiple
/// threads, consider using c++11 uniform_real_distribution.

maybe ofMath needs a facelift?

Contributor

DomAmato commented Aug 12, 2015

Still I wonder if we shouldn't port more of openframeworks over to C++11 standards and utilize the other random distribution engines. Pretty much all of ofRandom can be done using uniform_int_distribution or uniform_real_distribution since right now we are using rand() which is then put through a series of operations because of this http://www.azillionmonkeys.com/qed/random.html and in ofMath.h its even stated

\warning Many ofRandom-style functions wrap rand() which is not reentrant
/// or thread safe. To generate random numbers simultaneously in multiple
/// threads, consider using c++11 uniform_real_distribution.

maybe ofMath needs a facelift?

@ofTheo

This comment has been minimized.

Show comment
Hide comment
@ofTheo

ofTheo Aug 13, 2015

Contributor

actually this was suggested recently.
see: #3890

also if you want to read the worlds longest issue discussing random :)
#3842

Contributor

ofTheo commented Aug 13, 2015

actually this was suggested recently.
see: #3890

also if you want to read the worlds longest issue discussing random :)
#3842

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 13, 2015

Contributor

no kidding, I got worried when I looked to see how far I had made it into the thread and was only about 1/3rd of the way through.

Is there a preference to how its handled? I can test it on osx but obviously my main platform is windows. I will see how the thread local statics work and report back.

Contributor

DomAmato commented Aug 13, 2015

no kidding, I got worried when I looked to see how far I had made it into the thread and was only about 1/3rd of the way through.

Is there a preference to how its handled? I can test it on osx but obviously my main platform is windows. I will see how the thread local statics work and report back.

@DomAmato

This comment has been minimized.

Show comment
Hide comment
@DomAmato

DomAmato Aug 13, 2015

Contributor

btw i've been dumping tests into a branch on my fork and will submit separate PR for each feature set but for those curious its here:
https://github.com/DomAmato/openFrameworks/tree/OFTinkering

Contributor

DomAmato commented Aug 13, 2015

btw i've been dumping tests into a branch on my fork and will submit separate PR for each feature set but for those curious its here:
https://github.com/DomAmato/openFrameworks/tree/OFTinkering

@arturoc arturoc modified the milestones: 0.10.0, 0.9.1 Nov 9, 2015

@edap

This comment has been minimized.

Show comment
Hide comment
@edap

edap Dec 18, 2017

Contributor

I was looking for a gaussian distribution function a while ago, and I ended up with:

// #include <random>
//  std::default_random_engine generator;
//  std::normal_distribution<float> distribution;


float ofxEnvelope::ofRandomGaussian(float mean, float stddev) {
    std::normal_distribution<float>::param_type _param(mean, stddev);
    distribution.param(_param);
    return distribution(generator);
}

But today I've find out that GLM has already everything we need, https://github.com/g-truc/glm/blob/0.9.6.3/glm/gtc/random.hpp, and since we are now using it, why not simply integrate the gaussian random distribution method from there? I think that also a sphericalRand and a diskRand methods would be pretty helpful. I can take care of the PR if we are agree.

Ping @arturoc @ofTheo

Contributor

edap commented Dec 18, 2017

I was looking for a gaussian distribution function a while ago, and I ended up with:

// #include <random>
//  std::default_random_engine generator;
//  std::normal_distribution<float> distribution;


float ofxEnvelope::ofRandomGaussian(float mean, float stddev) {
    std::normal_distribution<float>::param_type _param(mean, stddev);
    distribution.param(_param);
    return distribution(generator);
}

But today I've find out that GLM has already everything we need, https://github.com/g-truc/glm/blob/0.9.6.3/glm/gtc/random.hpp, and since we are now using it, why not simply integrate the gaussian random distribution method from there? I think that also a sphericalRand and a diskRand methods would be pretty helpful. I can take care of the PR if we are agree.

Ping @arturoc @ofTheo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment