4.6.0
Freundlich's C++ toolkit
|
Random number generators and distributions.
Random number generation support in C++03 is very poor, only consisting of std::rand
to draw pseudo random numbers between 0
and RAND_MAX
, and std::srand
to seed the generator. C++11 has much better facilities, which are outlined below.
Pseudo random number generators are classes that only produce random numbers. They have different trade-offs in randomness and speed. In a way, they are very similar to the functions provided by C++03: They must be seeded and produce random numbers in a certain range.
Distributions map random numbers drawn from a random number generator into a specific range, for example into the range of ints from 0
to 10
. They are a very important addition, because doing this by hand is not only hard but also very error-prone.
fcppt wraps some of the classes provided by C++11, because their interfaces are designed in a way that allow many mistakes to be made.
The pseudo random number generators are all copyable, although it is discouraged to do so. A generator should usually be shared with different distributions to ensure an overall diverse randomness.
Some of the random number generators as well as some of the distributions have very arbitrary default parameters that shouldn't be used accidentally.
It is not possible to easily integrate other types like the ones from Boost.Units or fcppt's strong typedefs (fcppt.strong_typedef).
To overcome this situation, fcppt wraps these classes, making the pseudo random number generators noncopyable, and removing all of the default parameters, replacing them by strong typedefs instead.
To actually draw random numbers, you have to create a (pseudo) random number generator first. Such a generator must be seeded, for example with a time value obtained from std::chrono.
fcppt wraps random distributions using the classes provided in fcppt::random::distribution::parameters. Each of these classes implements a scheme of parameter translation (like providing strong typedefs instead) and also tells which underlying distribution it uses. To create a distribution, you have to use fcppt::random::distribution::basic which gets a parameter class as its template argument.
fcppt::random::variate is a class that combines a generator and a distribution into a single callable class. A class like this had been proposed for C++11 but was removed later. In C++11, the general idiom for constructing such a class is to use a std::function
and std::bind
which comes at a slight overhead.
We are first going to create a variate object with a uniform int distribution.
print_values
is a function that draws 20 numbers and prints them. For example, the code could print: 5 7 3 7 6 8 9 5 7 9 7 10 1 6 5 6 3 2 5 0
.
print_values
is defined as follows:
Using different distributions works similar to using a uniform int distribution, for example a normal distribution can be used like this:
For example, the code could print: 0.441851 5.37344 -7.79767 1.89097 -2.03191 3.17695 3.55056 -1.17422 2.86699 -7.46394 5.63758 2.65694 1.35165 0.953806 4.9783 2.02385 4.69477 -2.96583 5.22453 4.10744
.
As mentioned in the introduction, it is hard to adapt C++11's distributions to other types like strong typedefs. fcppt provides the fcppt.type_iso library that has a customization point for such conversions.
In the following example, we are going to construct a uniform_int
distribution over a strong typedef to an int. The specialization used for this is located in fcppt/type_iso/strong_typedef.hpp
and must be included.
Notice, that the distribution's min and max parameter also turned into strong typedefs my_type
.
Also, operator()
of the variate object returns strong typedefs.
It is also possible to chain multiple of these classes together as we can see in the next example. This is automatically done by the random facility itself. Again, the corresponding specializations must be included.
The following example creates a distribution of strong typedef called radius which itself contains a type used to express distances from boost::units
The distribution's parameters now need additional constructs to create the right types.
Finally, we output the values generated. value()
is a function that extracts the underlying value of a boost::units::quantity
The following example shows how you can specialize fcppt::type_iso::transform in order to use your own types with a distribution.
Suppose you have created a simple type similar to a strong typedef that wraps its underlying type:
In order to use it with fcppt, you can provide the following specialization:
With the aforementioned type conversion, it's also possible to draw random enum values. As described in fcppt.enum, fcppt provides an abstraction over contiguous enums and their maximum values. Random builds on top of that and provides fcppt::random::distribution::parameters::make_uniform_enum that automatically creates parameters suited for a uniform int distribution that draws enum values from 0 to the maximum enum value.
Suppose you have the following enum definition:
You can then declare a uniform int distribution for the enum:
fcppt::random::distribution::parameters::make_uniform_enum can then be used to initialize the uniform int distribution:
Header file | Description |
---|---|
variate_fwd.hpp | Contains fcppt::random::variate's declaration. |
variate_decl.hpp | Contains fcppt::random::variate's definition. |
variate_impl.hpp | Contains the definition of fcppt::random::variate's member functions. |
variate.hpp | Contains all of fcppt::random::variate |
distribution/base_value.hpp | Contains fcppt::random::distribution::base_value |
distribution/base_type.hpp | Contains fcppt::random::distribution::base_type |
distribution/basic_fwd.hpp | Contains fcppt::random::distribution::basic's declaration. |
distribution/basic_decl.hpp | Contains fcppt::random::distribution::basic's definition. |
distribution/basic_impl.hpp | Contains the definition of fcppt::random::distribution::basic's member functions. |
distribution/basic.hpp | Contains all of fcppt::random::distribution::basic |
distribution/decorated_value.hpp | Contains fcppt::random::distribution::decorated_value |
distribution/parameters/make_uniform_enum.hpp | Contains fcppt::random::distribution::parameters::make_uniform_enum |
distribution/parameters/normal_fwd.hpp | Contains fcppt::random::distribution::parameters::normal's declaration. |
distribution/parameters/normal_decl.hpp | Contains fcppt::random::distribution::parameters::normal's definition. |
distribution/parameters/normal_impl.hpp | Contains the definition of fcppt::random::distribution::parameters::normal's member functions. |
distribution/parameters/normal.hpp | Contains all of fcppt::random::distribution::parameters::normal |
distribution/parameters/uniform_int_fwd.hpp | Contains fcppt::random::distribution::parameters::uniform_int's declaration. |
distribution/parameters/uniform_int_decl.hpp | Contains fcppt::random::distribution::parameters::uniform_int's definition. |
distribution/parameters/uniform_int_impl.hpp | Contains the definition of fcppt::random::distribution::parameters::uniform_int's member functions. |
distribution/parameters/uniform_int.hpp | Contains all of fcppt::random::distribution::parameters::uniform_int |
distribution/parameters/uniform_real_fwd.hpp | Contains fcppt::random::distribution::parameters::uniform_real's declaration. |
distribution/parameters/uniform_real_decl.hpp | Contains fcppt::random::distribution::parameters::uniform_real's definition. |
distribution/parameters/uniform_real_impl.hpp | Contains the definition of fcppt::random::distribution::parameters::uniform_real's member functions. |
distribution/parameters/uniform_real.hpp | Contains all of fcppt::random::distribution::parameters::uniform_real |
generator/basic_pseudo_fwd.hpp | Contains fcppt::random::generator::basic_pseudo's declaration. |
generator/basic_pseudo_decl.hpp | Contains fcppt::random::generator::basic_pseudo's definition. |
generator/basic_pseudo_impl.hpp | Contains the definition of fcppt::random::generator::basic_pseudo's member functions. |
generator/basic_pseudo.hpp | Contains all of fcppt::random::generator::basic_pseudo |
generator/minstd_rand_fwd.hpp | Contains fcppt::random::generator::minstd_rand's declaration. |
generator/minstd_rand_decl.hpp | Contains fcppt::random::generator::minstd_rand's definition. |
generator/minstd_rand_impl.hpp | Contains the definition of fcppt::random::generator::minstd_rand's member functions. |
generator/minstd_rand.hpp | Contains all of fcppt::random::generator::minstd_rand |
generator/seed_from_chrono.hpp |
Classes | |
class | fcppt::random::distribution::basic< Parameters > |
A wrapper for distributions. More... | |
class | fcppt::random::distribution::parameters::normal< IntType > |
Parameters class for normal distributions. More... | |
class | fcppt::random::distribution::parameters::uniform_int< IntType, Distribution > |
Parameters class for uniform int distributions. More... | |
class | fcppt::random::distribution::parameters::uniform_real< IntType > |
Parameters class for uniform real distributions. More... | |
class | fcppt::random::generator::basic_pseudo< Generator > |
A wrapper around pseudo random number generators. More... | |
class | fcppt::random::variate< Generator, Distribution > |
Combines a generator and a distribution. More... | |
Functions | |
template<typename Seed > | |
Seed | fcppt::random::generator::seed_from_chrono () |
Creates a seed from a chrono clock. | |
Seed fcppt::random::generator::seed_from_chrono | ( | ) |
Creates a seed from a chrono clock.
Creates a seed of type Seed from a chrono clock.
Seed | The seed type of a pseudo random number generator. Its value_type must be an integral type. |