© Peter Van Weert and Marc Gregoire 2016
Peter Van Weert and Marc GregoireC++ Standard Library Quick Reference10.1007/978-1-4842-1876-1_1

1. Numerics and Math

Peter Van Weert and Marc Gregoire2
(1)
Kessel-Lo, Belgium
(2)
Meldert, Belgium
 
Electronic supplementary material
The online version of this chapter (doi:10.​1007/​978-1-4842-1876-1_​1) contains supplementary material, which is available to authorized users.

Common Mathematical Functions            <cmath>

The <cmath> header defines an extensive collection of common math functions in the std namespace. Unless otherwise specified, all functions are overloaded to accept all standard numerical types, with the following rules for determining the return type:
  • If all arguments are float, the return type is float as well. Analogous for double and long double inputs.
  • If mixed types or integers are passed, these numbers are converted to double, and a double is returned as well. If one of the inputs is a long double, long double is used instead.

Basic Functions

Function
Description
abs(x)
fabs(x)
Returns the absolute value of x. <cstdlib> defines abs(), labs(), and llabs() for int types; that abs() has return type int, which is different from the abs() in <cmath> (double).
fmod(x, y)
remainder(x, y)
Returns the remainder of $$ 
aisebox{1ex}{$x$}!left/ !
aisebox{-1ex}{$y$}
ight. $$. For fmod(), the result always has the same sign as x; for remainder(), that is not necessarily true. E.g.: mod(1,4) = rem(1,4) = 1, but mod(3,4) = 3 and rem(3,4) = -1.
remquo(x, y, *q)
Returns the same value as remainder(). q is a pointer to an int and receives a value with the sign of $$ 
aisebox{1ex}{$x$}!left/ !
aisebox{-1ex}{$y$}
ight. $$ and at least the last three bits of the integral quotient itself (rounded to the nearest).
fma(x, y, z)
Computes $$ left(x*y
ight)+z $$ in an accurate (better precision and rounding properties than a naive implementation) and efficient (uses a single hardware instruction if possible) manner.
fmin(x, y)
fmax(x, y)
Returns the minimum or maximum of x and y.
fdim(x, y)
Returns the positive difference, i.e. $$ left{egin{array}{c}hfill x-y  if x>yhfill \ {}hfill +0  if xle yhfill end{array}
ight. $$.
nan(string)
nanf(string)
nanl(string)
Returns a quiet (non-signaling) NaN (not a number) of type double, float, respectively long double, if available (0 otherwise). The string parameter is an implementation-dependent tag that can be used to differentiate between different NaN values. Both "" and nullptr are valid and result in a generic quiet NaN.

Exponential and Logarithmic Functions

Function
Formula
Function
Formula
Function
Formula
exp(x)
e x
exp2(x)
2 x
expm1(x)
$$ {e}^x-1 $$
log(x)
$$ ln x={ log}_ex $$
log10(x)
log10 x
log2(x)
log2 x
log1p(x)
$$ ln left(1+x
ight) $$
    

Power Functions

Function
Formula
Function
Formula
pow(x, y)
x y
sqrt(x)
$$ sqrt{x} $$
hypot(x, y)
$$ sqrt{x^2+{y}^2} $$
cbrt(x)
$$ sqrt[3]{x} $$

Trigonometric and Hyperbolic Functions

All basic trigonometric (sin(), cos(), tan(), asin(), acos(), atan()) and hyperbolic functions (sinh(), cosh(), tanh(), asinh(), acosh(), atanh()) are provided. The lesser-known trigonometric function atan2() is provided as well. It is used to compute the angle between a vector (x,y) and the positive X axis, with atan2(y,x) similar to atan(y/x) except that its result correctly reflects the quadrant the vector is in (and that it also works if x is 0). Essentially, by dividing y by x in atan(y/x), you lose information regarding the sign of x and y.

Error and Gamma Functions

Function
Formula
Function
Formula
erf(x)
$$ frac{2}{sqrt{pi }}{displaystyle underset{0}{overset{x}{int }}}{e}^{-{t}^2}dt $$
tgamma(x)
$$ Gamma (x)={displaystyle underset{0}{overset{infty }{int }}}{t}^{x-1}{e}^{-t}dt $$
erfc(x)
$$ frac{2}{sqrt{pi }}{displaystyle underset{x}{overset{infty }{int }}}{e}^{-{t}^2}dt=1-mathrm{e}mathrm{r}mathrm{f}(x) $$
lgamma(x)
ln(|Γ(x)|)

Integral Rounding of Floating-Point Numbers

Function
Description
ceil(x)
floor(x)
Rounds up / down to an integer. That is: returns the nearest integer that is not less / not greater than x.
trunc(x)
Returns the nearest integer not greater in absolute value than x.
round(x)
lround(x)
llround(x)
Returns the integral value nearest to x, rounding halfway cases away from zero. The return type of round() is based as usual on the type of x, whereas lround() returns long, and llround() returns long long.
nearbyint(x)
Returns the integral value nearest to x as a floating-point type. The current rounding mode is used: see round_style in the section on arithmetic type properties later in this chapter.
rint(x)
lrint(x)
llrint(x)
Returns the integral value nearest to x, using the current rounding mode. The return type of rint() is based as usual on the type of x, whereas lrint() returns long, and llrint() returns long long.

Floating-Point Manipulation Functions

Function
Description
modf(x, *p)
Breaks the value of x into an integral and a fractional part. The latter is returned and the former is stored in p, both with the same sign as x. The return type is based on that of x as usual, and p must point to a value of the same type as this return type.
frexp(x, *exp)
Breaks the value of x into a normalized fraction with an absolute value in the range [0.5, 1) or equal to zero (the return value), and an integral power of 2 (stored in exp), with $$ x= fraction*{2}^{exp} $$.
logb(x)
Returns the floating-point exponent of x, that is: log radix |x|, with radix the base used to represent floating-point values (2 for all standard numerical types; hence the name: binary logarithm).
ilogb(x)
Same as logb(x), but the result is truncated to a signed int.
ldexp(x, n)
Returns x * 2 n (with n an int).
scalbn(x, n)
scalbln(x, n)
Returns x * radix n (with n an int for scalbn() and a long for scalbln()). radix is the base used to represent floating-point values (2 for all standard C++ numerical types).
nextafter(x, y)
nexttoward(x, y)
Returns the next representable value after x in the direction of y. Returns y if x equals y. For nexttoward(), the type of y is always long double.
copysign(x, y)
Returns a value with the absolute value of x and the sign of y.

Classification and Comparison Functions

Function
Description
fpclassify(x)
Classifies the floating-point value x: returns an int equal to FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, or an implementation-specific category.
isfinite(x)
Returns true if x is finite, i.e. normal, subnormal (denormalized), or zero, but not infinite or NaN.
isinf(x)
Returns true if x is positive or negative infinity.
isnan(x)
Returns true if x is NaN.
isnormal(x)
Returns true if x is normal, i.e. neither zero, subnormal (denormalized), infinite, nor NaN.
signbit(x)
Returns a non-zero value if x is negative.
isgreater(x, y)
isgreaterequal(x, y)
isless(x, y)
islessequal(x, y)
islessgreater(x, y)
Compares x and y. The names are self-explanatory, except islessgreater() which returns true if x < y || x > y. Note that this is not the same as !=, as e.g. nan("") != nan("") is true, but not islessgreater(nan(""), nan("")).
isunordered(x, y)
Returns whether x and y are unordered, i.e. whether one or both are NaN.

Error Handling

The mathematical functions from <cmath> can report errors in two ways depending on the value of math_errhandling (defined in <cmath>, although not in the std namespace). It has an integral type and can have one of the following values or their bitwise OR combination:
  • MATH_ERRNO: Use the global errno variable (see Chapter 8).
  • MATH_ERREXCEPT: Use the floating-point environment, <cfenv>, not further discussed in this book.

Fixed-Width Integer Types        <cstdint>

The <cstdint> header contains platform-dependent typedefs for integer types with different and more portable width requirements than the fundamental integer types:
  • std::(u)int X _t, an (unsigned) integer of exactly X bits (X = 8, 16, 32, or 64). Present only if supported by the target platform.
  • std::(u)int_least X _t, the smallest (unsigned) integer type of at least X bits (X = 8, 16, 32, or 64).
  • std::(u)int_fast X _t, the fastest (unsigned) integer type of at least X bits (X = 8, 16, 32, or 64).
  • std::(u)intmax_t, the largest supported (unsigned) integer type.
  • std::(u)intptr_t, (unsigned) integer type large enough to hold a pointer. These typedefs are optional.
The header further defines macros for the minimum and maximum values of these (and some other) types: for instance, INT_FAST_8_MIN and INT_FAST_8_MAX for std::int_fast8_t. The standard C++ way of obtaining these values, though, is with the facilities of <limits> discussed next.

Arithmetic Type Properties         <limits>

The std::numeric_limits<T> template class offers a multitude of static functions and constants to obtain properties of a numeric type T. It is specialized for all fundamental numeric types, both integral and floating-point, and hence can be used to inspect properties of all their aliases as well, such as size_t or those of the previous section. The various members offered are listed next. Functions are only and always used to obtain a T value; whereas Booleans, ints, and enum values are defined as constants.
Member
Description
is_specialized
Indicates whether the template is specialized for the given type. If false, zero-initialized values are used for all other members.
min(), max()
Returns the minimum/maximum finite representable number. Rather unexpectedly, for floating-point numbers min() returns the smallest positive number that can be represented (cf. lowest()).
lowest()
Returns the lowest finite representable number. Same as min() except for floating-point types, where lowest() returns the lowest negative number, which for float and double equals -max().
radix
The base used to represent values (2 for all C++ numerical types, but specific platforms can support e.g. native decimal types).
digits
The number of digits in base radix (i.e., generally the number of bits) representable, excluding any sign bit for integer types. For floating-point types, the number of digits in the mantissa.
digits10
The number of significant decimal digits that the type can represent without loss, e.g. when converting from text and back. Equal to ⌊digits * log10(radix)⌋ for integers: for char, e.g., it equals 2, because it cannot represent all values with three decimal digits. For floating-point numbers, it equals  $$ left( digits-1
ight)*{ log}_{10}(radix) $$.
is_signed
Identifies signed types. All standard floating-point types are signed, Booleans are not, and for char and wchar_t it is unspecified.
is_integer
Identifies integer types (includes Booleans and character types).
is_exact
Identifies types with exact representations. Same as is_integer for all standard types, but there exist e.g. third-party rational number representations that are exact but not integer.
is_bounded
Identifies types with finite representations. true for all standard types, but libraries exist that offer types with arbitrary precision.
is_modulo
Identifies modulo types, meaning if the result of a +, -, or * operation would fall outside the range [min(), max()], the resulting value differs from the real value by an integral multiple of max() - min() + 1. Usually true for integers; false for floating-point types.
traps
Identifies types that have at least one value that would cause a trap (exception) when used as an operand for an arithmetic operation. For example, division by 0 always causes a trap. Usually true for all standard integer types, except bool. Usually false for all floating-point types.
The following members are relevant only for floating-point types. For integer types, they always equal or return zero:
Member
Description
max_digits10
The number of decimal digits needed to represent any value of the type without loss, e.g. when converting to text and back. Use (at least) max_digits10 precision when converting floating-point numbers to text, and it will give the exact same value again when parsed back (9 for float, 17 for double, 22 for long double).
min_exponent10, min_exponent, max_exponent10, max_exponent
The lowest negative (for min_*) or highest positive (for max_*) integer n such that 10 n (for *10) or $$ radi{x}^{n-1} $$ (otherwise) is a valid normalized floating-point value.
epsilon()
The difference between 1.0 and the next representable value.
round_error()
The maximum rounding error as defined in ISO/IEC 10967-1.
is_iec599
Identifies types conforming to all IEC 599/IEEE 754 requirements. Usually true for all standard floating-point types.
has_infinity
Identifies types that can represent positive infinity. Usually true for all standard floating-point types.
infinity()
Returns the value for positive infinity. Only meaningful if has_infinity is true.
has_quiet_NaN,
has_signaling_NaN
Identifies types that can represent the special value for a quiet or signaling NaN. Usually true for all standard floating-point types. Using a signaling NaN in operations results in an exception; using a quiet NaN does not.
quiet_NaN(), signaling_NaN()
Returns the value for a quiet or signaling NaN. Only meaningful if has_quiet_NaN respectively has_signaling_NaN is true.
tinyness_before
Identifies types that perform a check for underflow before performing any rounding.
round_style
Contains the rounding style as a std::float_round_style value: round_indeterminate, round_toward_zero, round_to_nearest, round_toward_infinity, or round_toward_neg_infinity. All integer types are required to round toward zero. The standard floating-point types usually round to nearest.
has_ denorm
Identifies types that can represent denormalized values (special values smaller than min() that exist to deal with underflow). Has type std::float_denorm_style, with values denorm_absent, denorm_present (most common), and denorm_indeterminate.
denorm_min()
Returns the smallest positive denormalized value if has_denorm != std::denorm_absent, and min() otherwise.
has_denorm_loss
Identifies types for which loss of precision is detected as denormalization loss rather than as an inexact result (advanced option that should be false; dropped in IEEE 754-2008).

Complex Numbers         <complex>

The std::complex<T> type, defined for at least T equal to float, double, and long double, is used to represent complex numbers as follows:
A417649_1_En_1_Figa_HTML.gif
All expected operators are available: +, -, *, /, +=, -=, *=, /=, =, ==, and !=, including overloads with a floating-point operand (which is then treated as a complex number with a zero imaginary part), and the >> and << operators for interaction with the streams of Chapter 5.
The std::literals::complex_literals namespace defines convenient literal operators for creating complex<T> numbers: i, if, and il, creating values with T equal to double, float, and long double respectively. Using this, the c value in the previous example, e.g., could have been created with: 'auto c = 1.f + 2if;'.
The header furthermore defines the complex equivalents of several of the basic math functions seen earlier: pow(), sqrt(), exp(), log(), and log10(), as well as all trigonometric and hyperbolic functions: sin(), cos(), tan(), asin(), acos(), atan(), sinh(), cosh(), tanh(), asinh(), acosh(), and atanh().
Besides these, the following complex-specific non-member functions exist:
Function
Description
Definition
real() / imag()
Non-member getters
real / imag
abs()
The modulus or magnitude
$$ sqrt{rea{l}^2+ima{g}^2} $$
norm()
The norm
$$ rea{l}^2+ima{g}^2 $$
arg()
The phase or argument
atan2(imag, real)
conj()
The conjugate
$$ left( real, - imag
ight) $$
polar()
Construction from polar coordinates (m, φ) (= magnitude and phase)
$$ mleft( cos upvarphi +i  sin upvarphi 
ight) $$
proj()
Projection onto the Riemann sphere
$$ left(infty, pm 0
ight) $$ if infinite real or imag; else (real, imag)

Compile-Time Rational Numbers      <ratio>

The std::ratio<Numerator, Denominator=1> template type from the <ratio> header represents a rational number. What makes it peculiar is that it does so at the type level rather than the usual value level (std::complex numbers are an example of the latter). Although ratio values can be default-constructed, this is rarely the intention. Rather, the ratio type is generally used as type argument for other templates. For example, the std::chrono::duration<T, Period=std::ratio<1>> template explained in Chapter 2 may be instantiated as duration<int,ratio<1,1000>>, for instance, to represent a duration of milliseconds, or as duration<int,ratio<60>> for a duration of minutes.
Convenience typedefs exist for all standard SI ratios: std::kilo for instance is defined as ratio<1000> and std::centi as ratio<1,100>. The full list is atto ($$ {10}^{-18} $$), femto ($$ {10}^{-15} $$), pico ($$ {10}^{-12} $$), nano ($$ {10}^{-9} $$), micro ($$ {10}^{-6} $$), milli ($$ {10}^{-3} $$), centi ($$ {10}^{-2} $$), deci ($$ {10}^{-1} $$), deca (101), hecto (102), kilo (103), mega (106), giga (109), tera (1012), peta (1015), and exa (1018); and for platforms with an integer type that is wider than 64-bit, yocto ($$ {10}^{-24} $$), zepto ($$ {10}^{-21} $$), zetta (1021), and yotta (1024).
All ratio types define two static members num and den, containing the numerator and denominator of the rational number, but after normalization. The ratio’s type member equals the ratio type of this normalized rational number.
Arithmetic operations with ratios are possible, but they are again at the type level: the std::ratio_add template, for instance, takes two ratio types as template arguments and evaluates to the type that corresponds to the sum of these rational numbers. The ratio_subtract, ratio_multiply, and ratio_divide templates are analogous. To compare two ratio types, similar ratio_xxx templates are provided with xxx equal, not_equal, less, less_equal, greater, or greater_equal.
The following example clarifies ratio arithmetic (<typeinfo>, discussed in Chapter 2, must be included when using the typeid operator):
A417649_1_En_1_Figb_HTML.gif

Random Numbers        <random>

The <random> library provides powerful random-number-generation facilities that supersede the flawed C-style rand() function from <cstdlib>. Central concepts are random number generators and distributions. A generator is a function object that generates random numbers in a predefined range in a uniformly distributed way—that is, each value in said range has, in principle, the same probability of being generated. A generator is generally passed to a distribution functor to generate random values distributed according to some chosen statistical distribution. This could for instance be another, user-specified uniform distribution:
A417649_1_En_1_Figc_HTML.gif
When multiple values are to be generated, it is more convenient to bind the generator and distribution, for example using the facilities of <functional> (Chapter 2):
std::function<int()> roller = std::bind(distribution, generator);
for (int i = 0; i < 100; ++i) std::cout << roller() << ' ';

Random Number Generators

The library defines two types of generators: random number engines that generate pseudorandom numbers, and one true non-deterministic random number generator, std::random_device.

Pseudorandom Number Engines

Three families of pseudorandom number engines are provided in the form of generic class templates with various numeric type parameters:
  • std::linear_congruential_ engine : Uses a minimal amount of memory (one integer) and is reasonably fast, but generates low-quality random numbers.
  • std::mersenne_twister_ engine : Produces the highest quality pseudorandom numbers at the expense of a larger state size (the state of the predefined mt19937 Mersenne twister, for example, consists of 625 integers). Still, because they are also the fastest generators, these engines should be your default choice if size is of no concern.
  • std::subtract_with_carry_ engine : Although an improvement over the linear congruential engines in terms of quality (but not speed), these engines have much lower quality and performance than a Mersenne twister. Their state size is more moderate, though (generally 96 bytes).
All these engines provide a constructor that accepts an optional seed to initialize the engine. Seeding is explained later. They also have a copy constructor and support the following operations:
Operation
Description
seed(value)
Reinitializes the engine by seeding it with a given value
operator()
Generates and returns the next pseudorandom number
discard(n)
Generates n pseudorandom numbers and discards them
min()
max()
Returns the minimum and maximum values that the engine can possibly generate
== / !=
Compares the internal state of two engines (non-member operators)
<< / >>
Serialization to/from streams: see Chapter 5 (non-member operators)
All three engine templates require a series of numerical template parameters. Because choosing the appropriate parameters is best left to experts, several predefined instantiations exist for each family. Before we discuss these, though, we first need to introduce random number engine adaptors.
Engine Adaptors
The following function objects adapt the output of an underlying engine:
  • std::discard_block_engine<e,p,r>: For each block of p > 0 numbers generated by the underlying engine e, it discards all but r kept values (with p >= r > 0).
  • std::independent_bits_engine<e,w>: Generates random numbers of w > 0 bits even if the underlying engine e produces numbers with a different width.
  • std::shuffle_order_engine<e,k>: Delivers the numbers of the underlying engine e in a different, randomized order. Keeps a table of k > 0 numbers, each time returning and replacing a random one of those.
All the adaptors have a similar set of constructors: a default constructor, one with a seed that is forwarded to the wrapped engine, and constructors that accept an lvalue or rvalue reference to an existing engine to copy or move.
Adaptors support the exact same operations as the wrapped engines, plus these:
Operation
Description
seed()
Reinitializes the underlying engine by seeding it with a default seed
base()
Returns a const reference to the underlying engine
Predefined Engines
Based on the previous engines and adaptors, the library provides the following predefined engines that you should use instead of using the engines and/or adaptors directly. The mathematical parameters for these have been defined by experts:
  • minstd_rand0 / minstd_rand are linear_congruential_engines that generate std::uint_fast32_t numbers in [0, 231-1).
  • knuth_b equals shuffle_order_engine<minstd_rand0,256>.
  • mt19937 / mt19937_64 are mersenne_twister_engines generating uint_fast32_t / uint_fast64_t numbers.
  • ranlux24_base / ranlux48_base are rarely used standalone (see the next bullet) but are subtract_with_carry_engines that generate uint_fast32_t / uint_fast64_t numbers.
  • ranlux24 / ranlux48 are ranlux24_base / ranlux48_base engines adapted by a discard_block_engine.
Tip
Because choosing between all the previous predefined engines can be daunting, an implementation must also offer a std::default_random_engine that should be good enough for most applications (it may be a typedef for one of the others).

Non-Deterministic Random Number Generator

A random_device, in principle, does not generate pseudorandom numbers, but truly non-deterministic uniformly distributed random numbers. How it accomplishes this is implementation dependent: it could for example use special hardware on your CPU to generate numbers based on some physical phenomenon. If the random_device implementation cannot generate true non-deterministic random numbers, it is allowed to fall back to one of the pseudorandom number engines discussed earlier. To detect this, use its entropy() method: it returns a measure of the quality of the generated numbers, but zero if a pseudorandom number engine is used.
random_device is non-copyable and has but one constructor that accepts an optional implementation-specific string to initialize it. It has member functions operator(), min(), and max() analogous to the ones provided by the engines. Unlike with pseudorandom number engines, though, its operator() may throw an std::exception if it failed to generate a number (due to hardware failure, for example).
Although a random_device generates true random numbers, possibly cryptographically secure (check your library documentation), it is typically slower than any pseudorandom engine. It is therefore common practice to seed a pseudorandom engine using a random_device, as explained in the next section.

Seeding

All pseudorandom number engines have to be seeded with an initial value. If you set up an engine with the same seed, then you always get the same sequence of generated numbers. Although this could be useful for debugging or for certain simulations, most of the time you want a different unpredictable sequence of numbers to be generated on each run. That is why it is important to seed your engine with a different value each time the program is executed. This has to be done once (for example, at construction time). The recommended way of doing this is with a random_device, but as you saw earlier, this may also just generate pseudorandom numbers. A popular alternative is to seed with the current time (see Chapter 2). For example:
std::random_device seeder;
const auto seed = seeder.entropy() ? seeder() : std::time(nullptr);
std::default_random_engine generator(
   static_cast<std::default_random_engine::result_type>(seed));

Random Number Distributions

Up to now, we have only talked about generating random numbers that are uniformly distributed in the full range of 32- or 64-bit unsigned integers. The library provides a large collection of distributions you can use to fit this distribution, range, and/or value type to your needs. Their names will sound familiar if you are fluent in statistics. Describing all the math behind them falls outside the scope of this book, but the following sections briefly describe the available distributions (some in more detail than others). For each distribution, we show the supported constructors. For details on these distributions and their parameters, we recommend that you consult a mathematical reference.

Uniform Distributions

uniform_int_distribution<Int=int>(Int a=0, Int b=numeric_limits<Int>::max())
uniform_real_distribution<Real = double>(Real a = 0.0, Real b = 1.0)
  • Generates uniformly distributed integer/floating-point numbers in the range [a, b] (both inclusive).
Real generate_canonical<Real, size_t bits, Generator>(Generator&)
  • This is the only distribution that is defined as a function instead of a functor. It generates numbers in the range [0.0, 1.0) using the given Generator as the source of the randomness. The bits parameter determines the number of bits of randomness in the mantisse.

Bernoulli Distributions

bernoulli_distribution(double p = 0.5)
  • Generates random Boolean values with p equal to the probably of generating true.
binomial_distribution<Int = int>(Int t = 1, double p = 0.5)
negative_binomial_distribution<Int = int>(Int k = 1, double p = 0.5)
geometric_distribution<Int = int>(double p = 0.5)
  • Generate random non-negative integral values according to a certain probability density function.

Normal Distributions

normal_distribution<Real = double>(Real mean = 0.0, Real stddev = 1.0)
  • Generates random numbers according to a normal, also called Gaussian, distribution. The parameters specify the expected mean and standard deviation stddev. In Figure 1-1, μ represents the mean and σ the standard deviation.
    A417649_1_En_1_Fig1_HTML.jpg
    Figure 1-1.
    Probability distributions for some example normal and Poisson distributions, plotting the probability (between 0 and 1) that a value is generated
lognormal_distribution<Real = double>(Real mean = 0.0, Real stddev = 1.0)
chi_squared_distribution<Real = double>(Real degrees_of_freedom = 1.0)
cauchy_distribution<Real = double>(Real peak_location = 0., Real scale = 1.)
fisher_f_distribution<Real = double>(Real dof_num = 1., Real dof_denom = 1.)
student_t_distribution<Real = double>(Real degrees_of_freedom = 1.0)
  • Some more advanced normal-like distributions.

Poisson Distributions

poisson_distribution<Int = int>(double mean = 1.0)
exponential_distribution<Real = double>(Real lambda = 1.0)
gamma_distribution<Real = double>(Real alpha = 1.0, Real beta = 1.0)
weibull_distribution<Real = double>(Real a = 1.0, Real b = 1.0)
extreme_value_distribution<Real = double>(Real a = 0.0, Real b = 1.0)
  • Various distributions related to the classical Poisson distribution. The latter is illustrated in Figure 1-1, where λ is the mean (which for this distribution equals the variance). The Poisson distribution generates integers, so the connecting lines are there for illustration purposes only.

Sampling Distributions

Discrete Distribution
A discrete distribution requires a set of count weights and generates random numbers in the range [0, count). The probability of a value depends on its weight. The following constructors are provided:
discrete_distribution<Int = int>()
discrete_distribution<Int = int>(InputIt first, InputIt last)
discrete_distribution<Int = int>(initializer_list<double> weights)
discrete_distribution<Int = int>(size_t count, double xmin, double xmax,
                                 UnaryOperation op)
The default constructor initializes the distribution with a single weight of 1.0. The second and third constructors initialize it with a set of weights given as an iterator range, discussed in Chapter 3, or as an initializer_list, discussed in Chapter 2. And the last one initializes it with count weights generated by calling the given unary operation. The following formula is used:
$$ weigh{t}_i= opleft( xmin+i*delta +frac{delta }{2}
ight) $$ with $$ delta =frac{xmax- xmin}{count} $$
Piecewise Constant Distribution
A piecewise constant distribution requires a set of intervals and a weight for each interval. It generates random numbers that are uniformly distributed in each of the intervals. The following constructors are provided:
piecewise_constant_distribution<Real = double>()
  • The default constructor initializes the distribution with a single interval with boundaries 0.0 and 1.0 and weight 1.0.
piecewise_constant_distribution<Real = double>(
   InputIt1 firstBound, InputIt1 lastBound, InputIt2 firstWeight)
  • Initializes the distribution with intervals whose bounds are taken from the firstBound, lastBound iterator range and whose weights are taken from the range starting at firstWeight.
piecewise_constant_distribution<Real = double>(
    initializer_list<Real> bounds, UnaryOperation weightOperation)
  • Initializes the distribution with intervals whose bounds are given as an initializer_list and whose weights are generated by the given unary operation.
piecewise_constant_distribution<Real = double>(size_t count,
    Real xmin, Real xmax, UnaryOperation weightOperation)
  • Initializes the distribution with count uniform intervals over the range [xmin, xmax] and weights generated by the given unary operation.
The piecewise_constant_distribution has methods intervals() and densities() returning the interval boundaries and the probability densities for the values in each interval.
Piecewise Linear Distribution
A piecewise linear distribution, as implemented by piecewise_linear_distribution, is similar to a piecewise constant one but has a linear probability distribution in each interval instead of a uniform one. It requires a set of intervals and a set of weights for each interval boundary. It also provides intervals() and densities() methods. The set of constructors is analogous to those discussed in the previous section, but one extra weight is required because each boundary needs a weight instead of each interval.
Example
A417649_1_En_1_Figd_HTML.gif
The graph on the left in Figure 1-2 shows the number of times a specific value has been generated when generating a million values using the previous code. In the graph, you clearly see the piecewise_constant_distribution with intervals (1,20), (20,40), (40,60), and (60,80) with interval weights 1, 3, 1, and 3.
A417649_1_En_1_Fig2_HTML.jpg
Figure 1-2.
Difference between a piecewise constant and piecewise linear distribution
The graph on the right shows a piecewise_linear_distribution with the same intervals and boundary weights 1, 3, 1, 3, and 1. Notice that you require one extra weight compared to the piecewise_constant_distribution because you specify the weights for the boundaries instead of for the intervals.
If you use a piecewise_linear_distribution with intervals of different sizes, the graph is not continuous. That is because the weights are given for the boundaries of an interval, so if the beginning has a weight of 3 and the end has a weight of 1, the value at the beginning of the interval is three times more likely to be generated than the value at the end. Therefore, if the interval is for example twice as long, all probabilities are twice as small as well, including those of the bounds.

Numeric Arrays            <valarray>

std:: valarray is a container-like class for storing and efficiently manipulating dynamic arrays of numeric values. A valarray has built-in support for multidimensional arrays and for efficiently applying most mathematical operations defined in <cmath> to each element. Types stored in a valarray must essentially be an arithmetic or pointer type or a class that behaves similarly, such as std::complex. Thanks to these restrictions, some compilers are able to optimize valarray calculations more than when working with other containers.
std::valarray provides the following constructors :
Constructor
Description
valarray()
valarray(count)
Constructs an empty valarray or one with count zero-initialized / default-constructed elements.
valarray(const T& val, n)
valarray(const T* vals, n)
Constructs a valarray with n copies of val or n copies from the vals array.
valarray(initializer_list)
Constructs a valarray and initializes it with the values from the initializer list.
valarray(const x _array<T>&)
Constructor that converts between x _array<T> and valarray<T>, where x can be slice, gslice, mask, or indirect. All four types are discussed later.
valarray(const valarray&)
valarray(valarray&&)
Copy and move constructors.
Here is an example:
A417649_1_En_1_Fige_HTML.gif
A valarray supports the following operations :
Operation
Description
operator[]
Retrieves a single element or a part, i.e. a slice_array, gslice_array, mask_array, or indirect_array, discussed later.
operator=
Copy, move, and initializer list assignment operators. You can also assign an instance of the element type: all elements in the valarray will be replaced with a copy of it.
operator+, -, , !
Applies unary operations to each element. Returns a new valarray with the result (operator! returns valarray<bool>).
operator+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
Applies these operations to each element. Input is either ‘const T&’ or an equally long ‘const valarray<T>&’. In the latter case, the operator is piecewise applied.
swap()
Swaps two valarrays.
size()
resize(n,val=T())
Returns or changes the number of elements. When resizing, you can specify the value to assign to new elements; they are zero-initialized by default.
sum(), min(), max()
Returns the sum, minimum, and maximum of all elements.
shift(int n)
cshift(int n)
Returns a new valarray of the same size, in which elements are shifted by n positions. If n < 0, elements are shifted to the left. Elements shifted out are zero-initialized for shift(), whereas cshift() performs a circular shift.
apply(func)
Returns a new valarray where each element is calculated by applying the given unary function to the current elements.
The following non-member functions are supported as well:
Operation
Description
swap()
Swaps two valarrays
begin(), end()
Returns begin and end iterators (cf. Chapters 3 and 4)
abs()
Returns a valarray with the absolute values
operator+, -, *, /, %,
&, |, ^, <<, >>, &&, ||
Applies these binary operators to a valarray and a value, or to each element of two equally long valarrays
operator==, !=,  <, <=, >, >=
Returns a valarray<bool> where each element is the result of comparing elements of two valarrays, or the elements of one valarray with a value
There is also support for applying exponential (exp(), log(), and log10()), power (pow() and sqrt()), trigonometric (sin(), cos(), …), and hyperbolic (sinh(), cosh(), and tanh()) functions to all elements at once. These non-member functions return a new valarray with the results.

std::slice

This represents a slice of a valarray. A std::slice itself does not contain or refer to any elements; it simply defines a sequence of indexes. These indexes are not necessarily contiguous. It has three constructors: slice(start, size, stride), a default constructor equivalent to slice(0,0,0), and a copy constructor. Three getters are provided: start(), size(), and stride(). To use slice, create one and pass it to operator[] of a valarray. This selects size() elements from the valarray starting at position start(), with a given stride() (step size). If called on a const valarray, the result is a valarray with copies of the elements. Otherwise, it is a slice_array with references to the elements.
slice_array supports fewer operations than a valarray but can be converted to a valarray using the valarray<const slice_array<T>&) constructor. slice_array has the following three assignment operators:
void operator=(const T& value) const
void operator=(const valarray<T>& arr) const
const slice_array& operator=(const slice_array& arr) const
Operators +=, -=, *=, /=, %=, &=, |=, ^=, <<=, and >>= are provided as well. These operators require a right-hand-side operand of the same type as the valarray to which the slice_array refers, and they apply the operator to the elements referred to by the slice_array. For example:
A417649_1_En_1_Figf_HTML.gif
One use case for slices is to select rows or columns from valarrays that represent matrices. They can also be used to implement matrix algorithms such as matrix multiplication.

std::gslice

gslice stands for generalized slice. Instead of having a single value for the size and stride, a gslice has a valarray<size_t> for sizes and one for strides. The default constructor is equivalent to gslice(0, valarray<size_t>(), valarray<size_t>()), and a copy constructor is provided as well. Just as with std::slice, getters start(), size(), and stride() are available. Analogous to slice, a gslice is used by passing it to operator[] of valarray, returning either a valarray with copies or a gslice_array with references. A gslice_array supports a set of operations similar to those of a slice_array. How the different sizes and strides are used is best explained with an example:
A417649_1_En_1_Figg_HTML.gif
This example has two values for size and stride, so the gslice creates two slices. The first slice has the following parameters:
  • Start index = 1 (the first argument to the gslice constructor)
  • Size = 2 and stride = 5 (the first values in sizes and strides)
This slice therefore represents the indices {1, 6}. With this, two second-level slices are created, one for each of these indices. The indices from the first-level slice are used as starting indices for the two second-level slices. The first second-level slice therefore has these parameters
  • Start index = 1 (the first index of the first slice {1, 6})
  • Size = 3 and stride = 2 (second values from sizes and strides)
and the second has these parameters (note that both have the same size and stride parameters):
  • Start index = 6 (the second index of the first slice {1, 6})
  • Size = 3 and stride = 2 (second values from sizes and strides)
Concatenated, the second-level slices therefore represent these indices: {1,3,5, 6,8,10}. If there were a third level (that is, third values in sizes and strides), these indices would serve as starting indices for six third-level slices (all using those third values of sizes and strides). Because there is no third level, though, the corresponding values are simply selected from the valarray: {11,33,55, 66,88,111}.

std::mask_array

The operator[] on a valarray also accepts a valarray<bool>, similarly returning either a valarray with copies or a std::mask_array with references. This operator selects all elements from a valarray that have a true value in the corresponding position in the valarray<bool>. A mask_array supports a set of operations analogous to those of a slice_array. Here is an example:
A417649_1_En_1_Figh_HTML.gif

std::indirect_array

Finally, the operator[] on valarray accepts a valarray<size_t> as well, returning either a valarray with copies or a std::indirect_array with references. The valarray<size_t> specifies which indices should be selected. An indirect_array again supports a set of operations analogous to those of a slice_array. For example:
A417649_1_En_1_Figi_HTML.gif
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset