3.6.0
Freundlich's C++ toolkit
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 =
generator_type generator(
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.

using uniform_int =
int
>
>;

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.

using variate =
generator_type,
uniform_int
>;
variate rng(
fcppt::make_ref(generator),
uniform_int(
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)
{
20U, // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
[&rng]{
<< rng()
<< FCPPT_TEXT(' ');
}
);
}

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

using normal =
double
>
>;
using variate =
generator_type,
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.

int,
my_type
);
using distribution =
my_type
>
>;

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

variate rng(
generator
),
distribution(
distribution::param_type::max(my_type(10)) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
)
);

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

10U, // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
[&rng]{
// Outputs objects of type my_type
<< rng()
<< FCPPT_TEXT(' ');
}
);

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<
int
>;
meter,
radius
);
using distribution =
radius
>
>;

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

variate rng(
fcppt::make_ref(generator),
distribution(
radius(0 * boost::units::si::meter)
),
distribution::param_type::max(
radius(10 * boost::units::si::meter) // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
)
)
);

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

10U, // NOLINT(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
[&rng]{
<< rng().get().value()
<< FCPPT_TEXT(' ');
}
);

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>;
Type;
// A static function that converts to the base type
undecorate(decorated_type const &_value)
{
return
_value.value();
}
// A static function that converts from the base type
static decorated_type
{
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 =
my_enum
>
>;

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

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
fcppt::random::distribution::parameters::make_uniform_enum
fcppt::random::distribution::parameters::uniform_int< Enum > make_uniform_enum()
Definition: make_uniform_enum.hpp:34
fcppt::make_ref
fcppt::reference< Type > make_ref(Type &_ref) noexcept
Convenience function to create references.
Definition: make_ref.hpp:28
FCPPT_MAKE_STRONG_TYPEDEF
#define FCPPT_MAKE_STRONG_TYPEDEF(type, name)
Creates a new strong typedef using strong_typedef.
Definition: make_strong_typedef.hpp:21
fcppt::random::distribution::parameters::normal
Parameters class for normal distributions.
Definition: normal_decl.hpp:40
fcppt::random::generator::seed_from_chrono
Seed seed_from_chrono()
Creates a seed from a chrono clock.
Definition: seed_from_chrono.hpp:42
fcppt::math::vector::length
std::enable_if_t< std::is_floating_point< T >::value, T > length(fcppt::math::vector::object< T, N, S > const &_vec)
Calculates the length of a vector.
Definition: length.hpp:82
fcppt::type_iso
Conversions between isomorphic types.
Definition: decorate.hpp:16
fcppt::algorithm::repeat
void repeat(Count const _count, Function const &_function)
Calls a function a number of times.
Definition: repeat.hpp:37
fcppt::random::variate
Combines a generator and a distribution.
Definition: variate_decl.hpp:35
fcppt::random::distribution::basic
A wrapper for distributions.
Definition: basic_decl.hpp:38
fcppt::type_iso::undecorate
fcppt::type_iso::undecorated_type< Type > undecorate(Type const &_value)
Undecorates a value.
Definition: undecorate.hpp:33
fcppt::random::distribution::parameters::uniform_int
Parameters class for uniform int distributions.
Definition: uniform_int_decl.hpp:39
fcppt::random::generator::mt19937
fcppt::random::generator::basic_pseudo< std::mt19937 > mt19937
Definition: mt19937_fwd.hpp:28
fcppt::container::grid::min
fcppt::strong_typedef< fcppt::container::grid::pos< SizeType, Size >, fcppt::container::grid::min_tag > min
The start type of a pos range.
Definition: min_fwd.hpp:41
fcppt::type_iso::undecorated_type
typename fcppt::type_iso::detail::undecorated_type< Type >::type undecorated_type
The undecorated type.
Definition: undecorated_type.hpp:33
fcppt::io::cout
FCPPT_DETAIL_SYMBOL fcppt::io::ostream & cout()
Returns either std::cout or std::wcout, depending on fcppt::char_type.
FCPPT_TEXT
#define FCPPT_TEXT(x)
A macro to wrap a narrow character literal so it results in a fcppt::char_type[] array.
Definition: text.hpp:19
fcppt::random::distribution::decorated_value
Result decorated_value(Type const &_value)
Calculates the decorated value.
Definition: decorated_value.hpp:31
fcppt::log::level::fcppt_maximum
@ fcppt_maximum
The maximum value of the enumeration.