I want to be able to generate random values between 0.0 and 1.0
I've tried to use
std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(0.0, 1.0);
float myrand = distribution(generator);
Generating random value in a loop gives me always these values:
0.000022
0.085032
0.601353
0.891611
0.967956
0.189690
0.514976
0.398008
0.262906
0.743512
0.089548
What can I do to really get random values?
Doesn't seem that random if I always get the same ones.
// 1-st variant: using time() function for seed random distribution
std::default_random_engine generator(time(0));
std::uniform_real_distribution<double> distribution(first, last);
return distribution(generator);
If open multiple programs, with the same random number generator they will all output the same results, because they have the same value of seed which is time.
This issue solved by using random device, in the below code:
// 2-nd variant:
std::uniform_real_distribution<double> distribution(first, last);
std::random_device rd;
std::default_random_engine generator(rd());
return distribution(generator);
If you are referring to the fact that you get the same results for each execution of the program, that's because you need to provide a seed based on some naturally random value (e.g. some number input by the user, or the number of milliseconds elapsed since the computer was turned on, or since January 1, 1970, etc.):
#include <random>
std::default_random_engine generator;
generator.seed( /* ... */ );
// ^^^^^^^^^
// Provide some naturally random value here
std::uniform_real_distribution<float> distribution(0.0, 1.0);
float myrand = distribution(generator);
I have found another good solution...
double Generate(const double from, const double to)
{
std::random_device rd;
return std::bind(
std::uniform_real_distribution<>{from, to},
std::default_random_engine{ rd() })();
}
Modifying the nice solution above into a class to avoid constant
instantiation of the distribution and generator.
#include <random>
using namespace std;
class RangeRandGenerator {
uniform_real_distribution<double> dist;
random_device rd;
default_random_engine gen;
public:
RangeRandGenerator( double from, double to ) :
dist(from, to), gen(rd()) {}
double get() {
return dist(gen);
}
};
Related
Here is an example to draw random numbers from a binomial distribution with std::binomial_distribution
#include <random>
int main ()
{
std::mt19937 eng(14);
std::binomial_distribution<size_t> dist(28,0.2);
size_t randomNumber = dist(eng);
return 0;
}
I am failing to find a similar example for boost. I went through this documentation, which explains how to compute PDF, CDF and others from a boost::math::binomial object but they are not talking about sampling a random number.
Should I write a binary search myself based on the CDF that boost::math::binomial will compute for me or can boost directly return random numbers?
Thanks to this link from #Bob__, here is a simple working example
#include <random>
#include <boost/random.hpp>
int main ()
{
std::mt19937 eng;
boost::random::binomial_distribution<int> dist(28,0.2);
int randomNumber = dist(eng);
return 0;
}
For some reason, it would not compile with size_t, so I used int (see #Bob__'s comment below for more information).
Hi I have a simulation I'm runnning in which I get random numbers from a uniform and normal distributions easily:
#include <iostream>
#include "MersenneTwister.h"
using namespace std;
int main()
{
MTRand mtrand1;
double r1,r2;
r1 = mtrand.rand(); // from a uninform dist.
r2 = mtrand1.randNorm(); //from a normal dist.
}
I would like to use this random number generator to obtain a random number from a poisson distribution with mean 'A'.
Any idea about how to implement this procedure using the MersseneTwister code?
the code can be found here:
https://gcc.gnu.org/bugzilla/attachment.cgi?id=11960. and it is widely used.
You can use the standard library
#include<random>
double mean = 3.1415926;
std::mt19937 mt{std::random_device{}()};
std::poisson_distribution<> pd{mean};
auto n = pd(mt); // get a number
Do note that seeding with std::random_device is unlikely to be satisfactory.
I have a .arff file which contains a list of float numbers. I need to add to every number a gaussian noise, which in MATLAB would be:
m = m+k*randn(size(m)
where m is one of the numbers in the list and k is a standard deviation and has value 0.1. What is the C++ equivalent to randn()?
Could you please provide an example?
Use std::normal_distribution with an appropriate generator (std::default_random_engine will usually work). See http://en.cppreference.com/w/cpp/numeric/random for details on all of the random number generation facilities of the C++ standard library.
(live example)
#include <iostream>
#include <iterator>
#include <random>
int main() {
// Example data
std::vector<double> data = {1., 2., 3., 4., 5., 6.};
// Define random generator with Gaussian distribution
const double mean = 0.0;
const double stddev = 0.1;
std::default_random_engine generator;
std::normal_distribution<double> dist(mean, stddev);
// Add Gaussian noise
for (auto& x : data) {
x = x + dist(generator);
}
// Output the result, for demonstration purposes
std::copy(begin(data), end(data), std::ostream_iterator<double>(std::cout, " "));
std::cout << "\n";
return 0;
}
Output:
0.987803 1.89132 3.06843 3.89248 5.00333 6.07448
Further considerations
For decent statistical properties, you'll probably want to choose the std::mersenne_twister_engine generator (or, for convenience, the std::mt19937 predefined version), and seed it using std::random_device:
std::mt19937 generator(std::random_device{}());
[Note: Seeding from std::random_device is a good practice to get into; if you use the current time as a seed, you can end up with the same seed value across multiple generators (e.g. when initialising several generators in a very short period of time). std::random_device will obtain entropy from the system, if available.]
In order to avoid passing the generator to the distribution every time, you can do something like:
auto dist = std::bind(std::normal_distribution<double>{mean, stddev},
std::mt19937(std::random_device{}()));
which you can then use as follows:
double val = dist();
(Live example with these modifications)
The c++ standard now includes several distributions for random numbers.
You are looking for std::normal_distribution.
In the documentation you can also find a code sample
// construct a trivial random generator engine from a time-based seed:
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator (seed);
std::normal_distribution<double> distribution (0.0,1.0);
std::cout << "some Normal-distributed(0.0,1.0) results:" << std::endl;
for (int i=0; i<10; ++i)
std::cout << distribution(generator) << std::endl;
The parameters given to the constructor, std::normal_distribution, are first mean (0.0) and standard-deviation (1.0).
I was trying to generate 100 uniform random variable from 0.0 to 1.0.
I used the time based seed to generate it but the number generated seems repeated a few before changing to another one. Was there any better way to simualte without repeating?
Output was like:
0.33456, 0.33456, 0.33456, 0.11256, 0.11256, 0.11256, 0.94092, 0.94092, ...
Real UniformDistributionGenerator(double range_from, double range_to) {
Real uniform_r_v = 0.0;
unsigned seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::mt19937 generator(seed);
std::uniform_real_distribution<double> distribution(range_from, range_to);
uniform_r_v = distribution(generator);
return uniform_r_v;
}
The simplest solution: static std::mt19937 generator(seed);
Seeded once per program run, as it should be.
I'm doing a shuffle and it gets done very often on a small array. Could be anything from 1 - 10 elements.
I've tried the accepted answer in this question:
Is this C implementation of Fisher-Yates shuffle correct?
Unfortunately it's extremely slow.
I need a faster way of doing this and avoiding modulo bias which I'm seeing. Any suggestions?
EDIT:
Sorry I should point out that it's not the shuffle that's slow, it's the method used to generate a random int range. i.e. rand_int(). I'm using a Mersenne twister algorithm and RAND_MAX in my case is UINT_MAX to help out. This of course makes it slower when n is much smaller than RAND_MAX
I've also found 2 implementations of a rand_int type function.
static int rand_int(int n) {
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
do {
rnd = rand();
} while (rnd >= limit);
return rnd % n;
}
The following is much much faster. But, does it avoid the modulo bias problem?
int rand_int(int limit) {
int divisor = RAND_MAX/(limit);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
Edit
To address the basic question on avoiding the modulo bias with rand() see http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx.
In short, you can't get truly uniform other than skipping non-domain random numbers1; The article lists some formulae to get a smaller bias (int r = rand() / ( RAND_MAX / N + 1 ) eg) without sacrificing more performance.
1 See Java's implementation of Random.nextInt(int):
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#nextInt(int)
Using C++
You should be able to use std::random_shuffle (from <algorithm> header);
If you must roll your own shuffle implementation, I suggest using std::random (TR1, C++0x or Boost). It comes with a number of generators and distributions, with varying performance characteristics.
#include <random>
std::mt19937 rng(seed);
std::uniform_int_distribution<int> gen(0, N); // uniform, unbiased
int r = gen(rng);
Refer to the boost documentation for a good overview of Boost Random generator and distribution characteristics:
http://www.boost.org/doc/libs/1_47_0/doc/html/boost_random/reference.html#boost_random.reference.generators
Here is a sample of doing std::random_shuffle using Boost Random, directly:
#include <algorithm>
#include <functional>
#include <vector>
#include <boost/random.hpp>
struct Rng
{
Rng(boost::mt19937 &rng) : _rng(rng) {}
unsigned operator()(unsigned i)
{
boost::uniform_int<> dist(0, i - 1);
return dist(_rng);
}
private:
boost::mt19937 &_rng;
};
boost::mt19937 state;
std::random_shuffle(v.begin(), v.end(), Rng(state));