random/value_distribution.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief `ValueDistribution`, a clamped distribution a parameter is drawn from. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include <limits> | ||
| 6 | |||
| 7 | namespace terraingen { | ||
| 8 | |||
| 9 | /// A distribution a parameter is drawn from, clamped to [`min`, `max`]. | ||
| 10 | struct ValueDistribution { | ||
| 11 | /// The family of the distribution, which sets the meaning of `a` and `b`. | ||
| 12 | enum class Kind { | ||
| 13 | Constant, ///< Always `a`. | ||
| 14 | Uniform, ///< Uniform on [`a`, `b`]. | ||
| 15 | Normal, ///< Mean `a`, standard deviation `b`. | ||
| 16 | LogNormal, ///< Median `a`, standard deviation of the natural logarithm `b`. | ||
| 17 | }; | ||
| 18 | 241 | Kind kind = Kind::Constant; ///< The family. | |
| 19 | 241 | double a = 0.0; ///< First parameter, per `kind`. | |
| 20 | 241 | double b = 0.0; ///< Second parameter, per `kind`. | |
| 21 | 241 | double min = -std::numeric_limits<double>::infinity(); ///< Lower clamp. | |
| 22 | 241 | double max = std::numeric_limits<double>::infinity(); ///< Upper clamp. | |
| 23 | |||
| 24 | /// A value drawn from two independent uniforms `u1` and `u2` in [0, 1) (Box-Muller for the | ||
| 25 | /// normal kinds), clamped to [`min`, `max`]. | ||
| 26 | double Sample(double u1, double u2) const; | ||
| 27 | |||
| 28 | /// The smallest value `Sample` can return. | ||
| 29 | double Lowest() const; | ||
| 30 | |||
| 31 | /// The largest value `Sample` can return. | ||
| 32 | double Highest() const; | ||
| 33 | |||
| 34 | /// Memberwise equality. | ||
| 35 | 241 | bool operator==(const ValueDistribution&) const = default; | |
| 36 | }; | ||
| 37 | |||
| 38 | /// A standard normal from two independent uniforms `u1` and `u2` in [0, 1) by the Box-Muller | ||
| 39 | /// transform: sqrt(-2 ln(1 - `u1`)) cos(2 pi `u2`). | ||
| 40 | double StandardNormal(double u1, double u2); | ||
| 41 | |||
| 42 | /// Checks a value distribution. | ||
| 43 | /// @throws std::invalid_argument for parameters that are not finite, a uniform with `b` < `a`, a | ||
| 44 | /// negative standard deviation, a log-normal with a non-positive median, `min` above `max`, or a | ||
| 45 | /// normal or log-normal without a finite `max`. | ||
| 46 | void ValidateValueDistribution(const ValueDistribution& distribution); | ||
| 47 | |||
| 48 | } // namespace terraingen | ||
| 49 |