Generating very large Random numbers using Boost library - c++

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>.

Related

Filling a vector of bytes with random bytes

I wanted to fill a std::vector<BYTE> with random or pseudo-random bytes of data. I have written (in other word, find it) the following source code in the stackoverflow but it doesn't compile in my Visual Studio.
#include <Windows.h>
#include <vector>
#include <random>
#include <climits>
#include <algorithm>
#include <functional>
using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, BYTE>;
int main()
{
random_bytes_engine rbe;
std::vector<BYTE> data(1000);
std::generate(data.begin(), data.end(), std::ref(rbe));
}
When I try to compile the above code Visual studio give me the following errors:
Error C2338 note: char, signed char, unsigned char, char8_t, int8_t,
and uint8_t are not allowed Messaging
Error C2338 invalid template argument for independent_bits_engine:
N4659 29.6.1.1 [rand.req.genl]/1f requires one of unsigned short,
unsigned int, unsigned long, or unsigned long long Messaging.
The BYTE type, which is just an alias for unsigned char, is not an allowed type for UIntType parameter of
template<class Engine, std::size_t W, class UIntType>
class independent_bits_engine;
The standard, [rand.req.genl]/1.f, reads:
Throughout this subclause [rand], the effect of instantiating a template:
...
that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long.
The answer from Evg is correct.
If you really want to have random bytes only, I would use a custom generator function that generates values between [-128, 127] or any desired range.
For instance:
#include <iostream>
#include <Windows.h>
#include <vector>
#include <random>
#include <algorithm>
#include <limits>
int main()
{
std::random_device r;
std::default_random_engine randomEngine(r());
std::uniform_int_distribution<int> uniformDist(CHAR_MIN, CHAR_MAX);
std::vector<BYTE> data(1000);
std::generate(data.begin(), data.end(), [&uniformDist, &randomEngine] () {
return (BYTE) uniformDist(randomEngine);
});
for (auto i : data) {
std::cout << int(i) << std::endl;
}
return 0;
}
References:
https://en.cppreference.com/w/cpp/numeric/random
https://en.cppreference.com/w/cpp/algorithm/generate
Just do this instead:
using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, 32, uint32_t>;
Turns the engine into a 32-bit random number generator, but using it to initialize a vector of BYTEs works just fine.

rand() function generates the next number by ascending to the previous number

Please check code given below. The random number it generates for each execution is the increment of the previous generated number in the previous execution.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
srand(time(NULL));
cout<<"\n Random Number : "<<rand()<<endl;
cin.get();
return 1;
}
Please executeit for 5-6 times and you will see that the random numbers are increasing for each execution and they are very close to each other.
Note : Please use CodeBlocks or Visual studio to check it, not the online compilers.
Actually I found a way to solve my problem but still it might not be an answer to my question.
Anyway the problem is not about srand() or rand() functions but it is about the function time(NULL). Since I am trying to run this code on Windows, instead of using time(NULL) as a parameter for srand(), I used GetTickCount() and now it generates random numbers properly for each execution.
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
int main()
{
srand(GetTickCount());
cout<<"\n Random Number : "<<rand();
cout<<"\n";
cin.get();
return 1;
}

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);
}

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.