4.4.1
Freundlich's C++ toolkit
Loading...
Searching...
No Matches
Classes | Functions
fcppt.random

Description

Random number generators and distributions.

Introduction

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.

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.

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.

Using Random

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.

using generator_type = fcppt::random::generator::mt19937;
generator_type generator(fcppt::random::generator::seed_from_chrono<generator_type::seed>());

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.

variate rng(
fcppt::make_ref(generator),
uniform_int(
uniform_int::param_type::min(0),
uniform_int::param_type::max(
10) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
));
print_values(rng);

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:

template <typename Rng>
void print_values(Rng &rng)
{
fcppt::algorithm::repeat(20U, [&rng] { std::cout << rng() << ' '; });
std::cout << '\n';
}

Using different distributions works similar to using a uniform int distribution, for example a normal distribution can be used like this:

using normal =
variate rng(
fcppt::make_ref(generator),
normal(
normal::param_type::mean(0.),
normal::param_type::stddev(
5.) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
));
print_values(rng);

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.

Conversion of types

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.

using distribution = fcppt::random::distribution::basic<

Notice, that the distribution's min and max parameter also turned into strong typedefs my_type.

variate rng(
fcppt::make_ref(generator),
distribution(
distribution::param_type::min(my_type(0)), distribution::param_type::max(my_type(10))));

Also, operator() of the variate object returns strong typedefs.

fcppt::algorithm::repeat(10U, [&rng] { std::cout << rng() << ' '; });

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

using meter = boost::units::quantity<boost::units::si::length, int>;
using distribution = fcppt::random::distribution::basic<

The distribution's parameters now need additional constructs to create the right types.

variate rng(
fcppt::make_ref(generator),
distribution(
distribution::param_type::min(radius(0 * boost::units::si::meter)),
distribution::param_type::max(radius(10 * boost::units::si::meter))));

Finally, we output the values generated. value() is a function that extracts the underlying value of a boost::units::quantity

fcppt::algorithm::repeat(10U, [&rng] { std::cout << rng().get().value() << ' '; });

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:

namespace mine
{
template <typename Type>
class my_type
{
public:
explicit my_type(Type const _value) : value_(_value) {}
[[nodiscard]] Type value() const { return this->value_; }
private:
Type value_;
};
}

In order to use it with fcppt, you can provide the following specialization:

#include <fcppt/type_iso/transform.hpp>
namespace fcppt::type_iso
{
template <typename Type>
struct transform<mine::my_type<Type>>
{
using decorated_type = mine::my_type<Type>;
using undecorated_type = Type;
// A static function that converts to the base type
static undecorated_type undecorate(decorated_type const &_value) { return _value.value(); }
// A static function that converts from the base type
static decorated_type decorated_value(undecorated_type const &_value)
{
return decorated_type(_value);
}
};
}

Random enums

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:

enum class my_enum
{
value1,
value2,
value3,
fcppt_maximum = value3
};

You can then declare a uniform int distribution for the enum:

using uniform_enum = fcppt::random::distribution::basic<

fcppt::random::distribution::parameters::make_uniform_enum can then be used to initialize the uniform int distribution:

variate rng(
fcppt::make_ref(generator),
uniform_enum(fcppt::random::distribution::parameters::make_uniform_enum<my_enum>()));

Header files

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

Contains fcppt::random::generator::seed_from_chrono

Classes

class  fcppt::random::distribution::basic< Parameters >
 A wrapper for distributions. More...
 
class  fcppt::random::distribution::parameters::normal< FloatType >
 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< FloatType >
 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.
 

Function Documentation

◆ seed_from_chrono()

template<typename Seed >
Seed fcppt::random::generator::seed_from_chrono ( )

Creates a seed from a chrono clock.

Creates a seed of type Seed from a chrono clock.

Template Parameters
SeedThe seed type of a pseudo random number generator. Its value_type must be an integral type.
Note
If you use this function, you must link to boost.chrono
Returns
The seed