C++: generate gaussian distribution - c++

I would like to know if in C++ standard libraries there is any gaussian distribution number generator, or if you have any code snippet to pass.
Thanks in advance.

The standard library does not. Boost.Random does, however. I'd use that if I were you.

C++ Technical Report 1 adds support for random number generation. So if you're using a relatively recent compiler (visual c++ 2008 GCC 4.3), chances are that it is available out of the box.
See here for sample usage of std::tr1::normal_distribution (and many more).

The GNU Scientific Libraries has this feature. GSL - Gaussian Distribution

The answer to this question changes with C++11 which has the random header which includes std::normal_distribution. Walter Brown's paper N3551, Random Number Generation in C++11 is probably one of the better introductions to this library.
The following code demonstrates how to use this header (see it live):
#include <iostream>
#include <iomanip>
#include <map>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::normal_distribution<> dist(2, 2);
std::map<int, int> hist;
for (int n = 0; n < 10000; ++n) {
++hist[std::floor(dist(e2))];
}
for (auto p : hist) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/200, '*') << '\n';
}
}
I provide a more general set of examples to random number generation in C++11 in my answer to C++ random float number generation with an example in Boost and using rand() as well.

Related

Restrict random number generation to a range using <random> [duplicate]

This question already has answers here:
Generating a random integer from a range
(14 answers)
Closed 9 years ago.
I'm generating random numbers in C++11. When I run my code
using namespace std;
static std::mt19937_64 rng;
int main() {
rng.seed(11);
std::cout << rng() << std::endl;
}
It returns random numbers. However, I would like to restrict this to a range of numbers, say 1-1000. How would I do this, using the new <random> file/library introduced in C++11?
Use std::uniform_int_distribution from <random>.
Example:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(1, 1000);
std::cout << dis(gen) << '\n';
}
The <random> header includes a lot of other distributions that you can use. You can check it out here

Square root of a 100 digit number in C++

'unsigned long long' can solve upto 15 digits.
Is there a way to find square-root of a 100 digit number?
You could also use Boost.Multiprecision library. This library provides wrappers for some popular multiprecision implementations.
#include <iostream>
#include <string>
#include <utility>
#include <boost/multiprecision/mpfr.hpp>
int main()
{
std::string s(100, '0');
s.at(0) = '1';
boost::multiprecision::mpfr_float_100 f(std::move(s));
boost::multiprecision::mpfr_float_100 sqrt = boost::multiprecision::sqrt(f);
std::cout << sqrt.str() << std::endl;
return 0;
}
Definitely. One easy way would be to use the GNU multi-precision library's mpz_sqrt() function.
This question isnt really related to C++, but here is a list of methods you can use http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
Depending on if its homework or not you might be able to use a premade lib to handle bignums

problems with C++11-library and g++ 4.4.7

I am working on a server with GCC version 4.4.7, and I am forced to work with this version unfortunately. I want to make use of the <random> library of C++0x, but I read here that in this version uniform_real_distribution is called uniform_real. When I try to call this function and normal_distribution, I don't get useful output. See this example:
#include <random>
#include <iostream>
using namespace std;
int main()
{
typedef std::mt19937 Engine;
typedef std::uniform_real<double> Dis1;
typedef std::normal_distribution<double> Dis2;
Engine eng(0);
Dis1 dis1(0, 1);
cout << dis1(eng) << endl; //OUTPUTS 3.49921e+09
Dis2 dis2(0, 1);
cout << dis2(eng) << endl; //STALLS, NO OUTPUT
return 0;
}
I compile with g++44 -std=c++0x main.cpp and I have shown what output I get. What is the issue here?
C++11 support in gcc 4.4 is rather sparse.
The release notes for gcc 4.5 include
Improved experimental support for the upcoming ISO C++ standard,
C++0x
specifically mentioning <random>.

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.

How to generate random numbers in C++ using <random> header members?

I learned to program in C# and have started to learn C++. I'm using the Visual Studio 2010 IDE. I am trying to generate random numbers with the distribution classes available in <random>. For example I tried doing the following:
#include <random>
std::normal_distribution<double> *normal = new normal_distribution<double>(0.0, 0.0);
std::knuth_b *engine = new knuth_b();
std::variate_generator<knuth_b, normal_distribution<double>> *rnd;
rnd = new variate_generator<knuth_b, normal_distribution<double>>(engine, normal);
The last line gives a compiler error:
IntelliSense: no instance of constructor "std::tr1::variate_generator<_Engine, _Distrib>::variate_generator [with _Engine=std::tr1::knuth_b, _Distrib=std::tr1::normal_distribution]" matches the argument list
My arguments look ok to me, what am I doing wrong? When the variate_generator class here is instantiated, which method do you call to get the next random number i.e. .NET's System.Random.Next()?
There is no variate_generator in C++0x, but std::bind works just as well. The following compiles and runs in GCC 4.5.2 and MSVC 2010 Express:
#include <random>
#include <functional>
#include <iostream>
int main()
{
std::normal_distribution<> normal(10.0, 3.0); // mean 10, sigma 3
std::random_device rd;
std::mt19937 engine(rd()); // knuth_b fails in MSVC2010, but compiles in GCC
std::function<double()> rnd = std::bind(normal, engine);
std::cout << rnd() << '\n';
std::cout << rnd() << '\n';
std::cout << rnd() << '\n';
std::cout << rnd() << '\n';
}
PS: avoid new when you can.
ALERT: Note that the above solution binds a copy of the engine, not a reference to the engine. Thus, if you also do:
std::function rnd2 = std::bind(normal, engine);
then the rnd object and the rnd2 object will produce the exact same sequence of random numbers.