Random number generation and encapsulation - c++

I'm trying to generate random numbers with boost, and I'm having trouble getting it to work in a way that keeps everything encapsulated. I've got this piece of code in main(), which allows me to use roll() to generate a random number from [0,1)
boost::mt19937 rng(seed);
boost::uniform_01<> uniform_p;
boost::variate_generator< boost::mt19937, boost::uniform_01<> >
roll(rng, uniform_p);
Now I want to stick this in its own header/cpp file, with one function to obtain a seed and create roll, and others that call roll. But nothing can seem to see roll, and I'm pretty sure it will go out of scope after the function that calls it goes out of scope. I've tried playing around with static and extern, I've tried making roll part of a class so it won't go out of scope, but nothing seems to work.

How about having seed and rool functions declared in .h file, and their implementation in .cpp file. You could use static scoped_ptr to store helper objects i .cpp module and initialize them after static initialization phase. Thread-safety is another thing to keep in mind in this solution.

The following is a Matlab-like interface which I like to use for the generation of random numbers. You have to call seed() before using rand(). As Greg pointed out, scoped_ptr is handy to store the static variables (the Mersenne twister and the variate generator) which are needed. For thread-safety, protect these ressources with mutexes.
random.hpp
#ifndef RANDOM_HPP
#define RANDOM_HPP
void seed(unsigned s);
double rand();
#endif // RANDOM_HPP
random.cpp
#include "random.hpp"
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/scoped_ptr.hpp>
static boost::scoped_ptr<boost::mt19937> twister;
static boost::scoped_ptr<boost::variate_generator<boost::mt19937&,
boost::uniform_01<> > > vargen;
void seed(unsigned s)
{
twister.reset(new boost::mt19937(s));
vargen.reset(new boost::variate_generator<boost::mt19937&,
boost::uniform_01<> >(
*twister, boost::uniform_01<>()));
}
double rand()
{
assert(vargen.get() != 0);
return (*vargen)();
}
main.cpp
#include "random.hpp"
#include <iostream>
int main()
{
seed(42);
for (int i = 0; i < 10; ++i)
std::cout << rand() << std::endl;
return 0;
}

Related

Can I temporarily disable random / srand in c++?

I have a very large codebase that uses srand and rand that I need to debug. The random executions make debugging difficult, since bugs occur randomly too. Is there any way to temporary make the library execute deterministically so I can debug the code?
If you can add a file in the include chain, you can put this in that file:
#define rand() (4)
Not very pretty, but could help.
reference
There is no standard way to disable srand. In some implementations you can redefine it to do nothing and it will work, but that's an ORD violation:
extern "C" void srand(unsigned) noexcept {
// Nothing
}
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main() {
srand((unsigned)time(0));
printf("%d\n", rand());
}
It works in GCC in my testing and prints the same number every time. You probably can use it to debug your code but it's surely not appropriate for production use.

Unexpected value using random number generator as a function in C++

C++ beginner here with a problem using a functions. Please help!
I am trying to make a random number generator function that I can call from within int main to cout a randomly generated float between 0.0 and 1.0 to my screen. When I create the generator in int main and cout it runs fine and returns a float just the way I want, but when I put the same code in a function and call it in int main I get some mix of letters and numbers that makes no sense.
I understand that I could just use the code in the way it works and ignore it but at this point I really want to know why it's not working the way I'm trying to make it work. I've looked all over for the answer and feel as if I'm missing some really basic knowledge about the way functions work in C++.
Why is the code that works perfectly fine in int main returning gobbledygook when called from a function?
Random number generator in function (returns nonsense):
#include <iostream>
#include <random>
#include <ctime>
using namespace std;
float roll();
int main(){
cout<<roll<<endl;
system("PAUSE");
return 0;
}
float roll(){
default_random_engine generator;
uniform_real_distribution<float> distribution(0.0f,1.0f);
return distribution(generator);
}
Random number generator in int main (this one returns a float):
#include <iostream>
#include <random>
#include <ctime>
using namespace std;
int main()
{
default_random_engine generator;
uniform_real_distribution<float> distribution(0.0f,1.0f);
float roll = distribution(generator);
cout<<roll<<endl;
system("PAUSE");
return 0;
}
This is wrong:
cout<<roll<<endl;
You want:
cout<<roll()<<endl;
You want to call the function.
You just put the name of function which means just the address of it. Call it by using as defined.
For more information please check the tutorial.
#include <iostream>
#include <random>
#include <ctime>
using namespace std;
float roll();
int main(){
cout<<roll();<<endl;
system("PAUSE");
return 0;
}
float roll(){
default_random_engine generator;
uniform_real_distribution<float> distribution(0.0f,1.0f);
return distribution(generator);
}

Generating very large Random numbers using Boost library

I am using boost library for generating very very large Random numbers in the range [0-2^32-1]. But boost library is not working well with this range. It just displaying an error message "Assertion failed min_arg<=max_arg"
Kindly help me out ! here is the code:
#include <iostream>
#include <ctime>
#include <cmath>
#include "boost/random.hpp"
#include <stdint.h>
using namespace std;
int main()
{
long double rangeMin = 0;
long long int rangeMax = (pow(2.0,32.0)-1);
typedef boost::uniform_int<> NumberDistribution;
typedef boost::mt19937 RandomNumberGenerator;
typedef boost::variate_generator<RandomNumberGenerator&,
NumberDistribution> Generator;
NumberDistribution distribution(rangeMin, rangeMax);
RandomNumberGenerator generator;
Generator numberGenerator(generator, distribution);
generator.seed(time(0)); // seed with the current time
cout << numberGenerator() <<endl;
return 0;
}
As per documentation, the default value of the template parameter of boost::uniform_int is int. If you want to generate long long int's, you'll need to use boost::uniform_int<long long int>.

efficient generation of numbers with Boost

I wish to generate more than 10^8 random numbers with Boost. They must be normally distributed with standard deviation 1 and mean 0. Here is my MWE:
#include <iostream>
#include <vector>
#include <time.h>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>
using namespace std;
int main()
{
typedef boost::mt19937 ENG;
typedef boost::normal_distribution<double> DIST;
typedef boost::variate_generator<ENG,DIST> GEN;
ENG eng;
DIST dist(0,1);
GEN gen(eng,dist);
gen.engine().seed(time(0));
vector<double> nums;
for(int i=0; i<500; i++)
{
nums.push_back(gen());
}
return 0;
}
I have 2 questions in this regard:
Is the approach I am using to seed the engine correct? Or do I need to seed it before each number?
Is my method efficient? Or is there a better way?
EDIT Note that there is no bottleneck in the code as such. I am just wondering if my approach is correct from a professional point of view
I should say that the numbers (all of them) have to be scaled by a proper constant afterwards. My plan is to use a for-loop for this.
Best,
Niles.

How to make boost::exponential_distribution work?

I have been playing with Boost.Random for a day now, and while boost::uniform_int_distribution<> works well, I am having trouble with boost::exponential_distribution<>.
A simple program is worth a thousand words:
#include <iostream>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/exponential_distribution.hpp>
int main() {
boost::mt19937 gen;
boost::exponential_distribution<> dis;
std::cout << dis(gen) << "\n";
return 0;
}
Compiled with Clang 3.0, using Boost 1.39.1 (no, I cannot upgrade Boost).
The output is invariably the same: nan.
I could not find any reported issue so I guess it's me not using the library correctly... Any clue would be appreciated.
Given a random number r, uniformly distributed on [0,1), -log(r) is distributed on (0,infinity) with the distribution exp(-x).
The former is boost::uniform_01().
If you need a distribution p exp(-px), then it's -(1/p)log(r).
In both cases here log(x) is a natural log (base e).
UPD: Using boost::variate_generator seems to work for me (boost 1.43):
#include <iostream>
#include<boost/random.hpp>
int main() {
boost::mt19937 rng(11u);
boost::variate_generator< boost::mt19937&, boost::exponential_distribution<> > rndm(rng, boost::exponential_distribution<>()) ;
std::cout<<rndm()<<"\n";
}
I did not check the distribution though.