generate a random number in the C++ code

Asked by Raphaël Maurin

Hi all,
I need to generate a random number from a gaussian distribution in the C++ code of Yade.
For that, basing myself on http://www.cplusplus.com/reference/random/normal_distribution/
I wrote in the cpp file :
#include<random>
std::default_random_engine generator;
std::normal_distribution<double> distribution(0.0,1.0);
double number = distribution(generator);

When compiling, I get an error which I do not understand :

In file included from /usr/include/c++/4.6/random:35:0,
                 from /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:13:
/usr/include/c++/4.6/bits/c++0x_warning.h:32:2: erreur: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp: In member function ‘virtual void HydroForceEngine::action()’:
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:94:3: erreur: ‘default_random_engine’ is not a member of ‘std’
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:94:30: erreur: expected ‘;’ before ‘generator’
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:3: erreur: ‘normal_distribution’ is not a member of ‘std’
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:28: erreur: expected primary-expression before ‘double’
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:28: erreur: expected ‘;’ before ‘double’
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:109:27: erreur: ‘generator’ was not declared in this scope
/home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:109:36: erreur: ‘distribution’ was not declared in this scope
make[2]: *** [CMakeFiles/yade.dir/pkg/common/ForceEngine.cpp.o] Erreur 1
make[2]: *** Attente des tâches non terminées....
make[1]: *** [CMakeFiles/yade.dir/all] Erreur 2
make: *** [all] Erreur 2

Do you have an idea from where this error come from ?
If necessary I can put the whole code but I don't think it will bring something.

Raphaël

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Anton Gladky
Solved:
Last query:
Last reply:
Revision history for this message
Best Anton Gladky (gladky-anton) said :
#1

Hi,

are you using the latest trunk version?
There we have already enabled C++11, which you seems need for
the compilation of this code.

Cheers,

Anton

2014-08-18 13:56 GMT+02:00 Raphaël Maurin
<email address hidden>:
> New question #253257 on Yade:
> https://answers.launchpad.net/yade/+question/253257
>
> Hi all,
> I need to generate a random number from a gaussian distribution in the C++ code of Yade.
> For that, basing myself on http://www.cplusplus.com/reference/random/normal_distribution/
> I wrote in the cpp file :
> #include<random>
> std::default_random_engine generator;
> std::normal_distribution<double> distribution(0.0,1.0);
> double number = distribution(generator);
>
> When compiling, I get an error which I do not understand :
>
> In file included from /usr/include/c++/4.6/random:35:0,
> from /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:13:
> /usr/include/c++/4.6/bits/c++0x_warning.h:32:2: erreur: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp: In member function ‘virtual void HydroForceEngine::action()’:
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:94:3: erreur: ‘default_random_engine’ is not a member of ‘std’
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:94:30: erreur: expected ‘;’ before ‘generator’
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:3: erreur: ‘normal_distribution’ is not a member of ‘std’
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:28: erreur: expected primary-expression before ‘double’
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:95:28: erreur: expected ‘;’ before ‘double’
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:109:27: erreur: ‘generator’ was not declared in this scope
> /home/raphael/these/code/Yade/trunk/pkg/common/ForceEngine.cpp:109:36: erreur: ‘distribution’ was not declared in this scope
> make[2]: *** [CMakeFiles/yade.dir/pkg/common/ForceEngine.cpp.o] Erreur 1
> make[2]: *** Attente des tâches non terminées....
> make[1]: *** [CMakeFiles/yade.dir/all] Erreur 2
> make: *** [all] Erreur 2
>
>
> Do you have an idea from where this error come from ?
> If necessary I can put the whole code but I don't think it will bring something.
>
> Raphaël
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp

Revision history for this message
Raphaël Maurin (raphael-maurin) said :
#2

Hi Anton,
I was using the 29/06/2014 version, I updated and it solved the problem.
Thank you !
Raphaël

Revision history for this message
Raphaël Maurin (raphael-maurin) said :
#3

Thanks Anton Gladky, that solved my question.

Revision history for this message
Raphaël Maurin (raphael-maurin) said :
#4

One last thing, the random number generator using
#include<random>
std::default_random_engine generator;
std::normal_distribution<double> distribution(0.0,1.0);
double number = distribution(generator);

is pretty bad, I am able to see by eyes some number which are repeated many times...I don't like it much. Does someone knows a better way to generate random numbers in C++ ?

Thanks !

Raphaël

Revision history for this message
Jan Stránský (honzik) said :
#5

Hi Raphael,

to generate random number in the interval 0 to 1, I use

double random() { return (double)rand()/(double)RAND_MAX; }

for normal distribution I use Box-Muller method (see also [1,2])

// function generating normally distributed random numbers using Box-Muller
method
double randNormal (double mean, double stddev, double min=-1e200, double
max=1e200) {
   double r, u, v, c, ret;
   do {
      do {
         u = 2*(double)rand() / (double)RAND_MAX-1;
         v = 2*(double)rand() / (double)RAND_MAX-1;
         r = u*u + v*v;
      } while (r==0. || r>1.);
      c = sqrt(-2*log(r)/r);
      ret = mean + u*c*stddev;
   } while (ret <= min || ret >= max);
   return ret;
}

cheers
Jan

[1] http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
[2]
http://math60082.blogspot.cz/2013/03/c-coding-random-numbers-and-monte-carlo.html

2014-08-18 19:36 GMT+02:00 Raphaël Maurin <
<email address hidden>>:

> Question #253257 on Yade changed:
> https://answers.launchpad.net/yade/+question/253257
>
> Raphaël Maurin posted a new comment:
> One last thing, the random number generator using
> #include<random>
> std::default_random_engine generator;
> std::normal_distribution<double> distribution(0.0,1.0);
> double number = distribution(generator);
>
> is pretty bad, I am able to see by eyes some number which are repeated
> many times...I don't like it much. Does someone knows a better way to
> generate random numbers in C++ ?
>
> Thanks !
>
> Raphaël
>
> --
> You received this question notification because you are a member of
> yade-users, which is an answer contact for Yade.
>
> _______________________________________________
> Mailing list: https://launchpad.net/~yade-users
> Post to : <email address hidden>
> Unsubscribe : https://launchpad.net/~yade-users
> More help : https://help.launchpad.net/ListHelp
>

Revision history for this message
Bruno Chareyre (bruno-chareyre) said :
#6

I suspect the problem is in the generator, not in the distribution.
In other words, Box-Muller based on std::default_random_engine would be bad as well.

I guess you have seen the list of available generators [1]. Not sure which one is best but, for the one you tried it says:
"provides at least acceptable engine behavior for relatively casual, inexpert, and/or lightweight use"...

I have no idea what is used for std::rand(). It seems it is implementation dependent. It could be a wrapper of std::default_random_engine...

[1] http://www.cplusplus.com/reference/random/

Revision history for this message
Klaus Thoeni (klaus.thoeni) said :
#7

Hi,

 I am using boost's random number generators. I tested them and I am very happy. Have a look in the code [1] and here [2].

Cheers,
Klaus

[1] https://github.com/yade/trunk/blob/master/pkg/dem/WirePM.cpp
[2] http://www.boost.org/doc/libs/1_55_0/doc/html/boost_random.html

Revision history for this message
Raphaël Maurin (raphael-maurin) said :
#8

Thank you for your replies.

I just had a quick look at a review about random number generator in the chapter 7 of [1]. It is very interesting, and well detailed. They underline the fact that some usual generator proposed can be pretty bad, because the parametrization of the generators can be very important for the randomness.

In my case, the random number generation is important but not crucial so I am not looking for something perfect but good enough. It seems that the linear congruential generators, as the one you use Klaus are adapted to my use. The parametrization the generators minstd_rand0 proposed in boost library (variation of the one you are using : minstd_rand) is based on the parametrization proposed by Park and Miller, which is cited as an efficient parametrization by [1]. It is described as a "a good minimal standard" random number generator.

For people interested in more efficient generator, I think it is worth having a look at [1].

One last question Klaus, how did you test the random number generator exactly ?

Thank you all for the help !

Raphaël

[1] p.274 Numerical Recipes in C: The Art of Scientific Computing, Second Edition, William H. Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling. (1992)
http://www2.units.it/ipl/students_area/imm2/files/Numerical_Recipes.pdf

Revision history for this message
Klaus Thoeni (klaus.thoeni) said :
#9

Hi,

as far as I remember I did some simple tests by generating several set of numbers using different number generators and seed numbers. Then I did some simple statistics for each set in order to check their distributions.

HTH Klaus