alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
NormalReal.hpp
Go to the documentation of this file.
1/* Copyright 2025 Mehmet Yusufoglu, Tim Hanel
2 * SPDX-License-Identifier: MPL-2.0
3 */
4#pragma once
5
6#include "alpaka/math.hpp"
9
10#include <cmath>
11
13{
14 namespace internal
15 {
16 /**
17 * @brief Scalar Box–Muller transform for floating-point types.
18 *
19 * Generates independent standard normal samples from a uniform
20 * scalar engine. The implementation caches the second sample so
21 * that a pair of uniforms yields two normal values.
22 *
23 * Ref.: G. E. P. Box and M. E. Muller, "A Note on the Generation of Random Normal Deviates,"
24 */
25 template<std::floating_point T_Fp>
26 struct BoxMuller
27 {
28 using result_type = T_Fp;
29
30 template<concepts::UniformStdEngine T_Rng>
31 constexpr T_Fp operator()(T_Rng& rng)
32 {
33 // Re-use cached second sample
35 {
37 return m_secondRngNumber;
38 }
39 // Generate two uniform floats in (0,1)
40 constexpr auto uniformDist = UniformReal{T_Fp{0}, T_Fp{1}, interval::oo};
41
42 T_Fp u1 = uniformDist(rng);
43 T_Fp u2 = uniformDist(rng);
44
45 // Box-Muller transform
46 T_Fp r = math::sqrt(T_Fp{-2} * math::log(u1));
47 T_Fp theta = T_Fp{2} * static_cast<T_Fp>(M_PI) * u2;
48 T_Fp z0 = r * math::cos(theta);
49 T_Fp z1 = r * math::sin(theta);
50
53 return z0;
54 }
55
56 private:
59 };
60 } // namespace internal
61
62 /**
63 * @brief Used to sample floating-point values from a normal(-/gaussian) distribution.
64 *
65 * Usage is analogous to std::normal_distribution<T_Result> @see
66 * https://en.cppreference.com/w/cpp/numeric/random/normal_distribution.html
67 * -> Generates N(mean, stddev).
68 * Is using the Box-Muller method of generating normal distributed random numbers from a uniform distribution.
69 *
70 * @note: currently supports 32 and 64 bit floating point types.
71 */
72 template<std::floating_point T_Result>
74 {
75 using result_type = T_Result;
76
77 /**
78 * @brief Constructs normal(-/gaussian) distribution with given parameters.
79 *
80 * @param mean Mean of the target normal distribution.
81 * @param stdDev Standard deviation of the target normal distribution.
82 *
83 * The default is N(0,1). The distribution is sampled using the Box-Muller method.
84 * This implementation keeps an internal state, therefore each
85 * thread/worker must use its own instance to avoid data races
86 * when the same object is accessed concurrently by multiple
87 * workers.
88 *
89 * Usage is otherwise analogous to std::normal_distribution<T_Result> @see
90 * https://en.cppreference.com/w/cpp/numeric/random/normal_distribution.html
91 */
92 constexpr explicit NormalReal(T_Result mean = T_Result{0}, T_Result stdDev = T_Result{1})
93 : m_mean(mean)
94 , m_stdDev(stdDev)
95 {
96 }
97
98 /** Selects a value from a normal (-/gaussian) distribution for the configured (mean,stdDev) settings.
99 *
100 * @param engine a random engine conforming to the `UniformRandomEngine` concept
101 * (currently accepts stdlib uniform engines and alpaka engines included in the alpaka::rand::engine namespace)
102 * @return a floating-point value sampled from the configured distribution.
103 */
104 template<concepts::UniformStdEngine T_Engine>
105 constexpr result_type operator()(T_Engine& engine)
106 {
107 return m_impl(engine) * m_stdDev + m_mean;
108 }
109
110 private:
111 // current implementation
113 // box muller has a state and must therefore be an accessible field.
117 };
118
119} // namespace alpaka::rand::distribution
constexpr auto sin(auto const &arg)
Definition math.hpp:21
constexpr auto sqrt(auto const &arg)
Definition math.hpp:159
constexpr auto cos(auto const &arg)
Definition math.hpp:178
constexpr auto log(auto const &arg)
Computes the natural (base e) logarithm of arg.
Definition math.hpp:208
constexpr OO oo
Interval-tag (a, b) object instance.
Definition interval.hpp:54
constexpr result_type operator()(T_Engine &engine)
Selects a value from a normal (-/gaussian) distribution for the configured (mean,stdDev) settings.
internal::BoxMuller< T_Result > T_Impl
constexpr NormalReal(T_Result mean=T_Result{0}, T_Result stdDev=T_Result{1})
Constructs normal(-/gaussian) distribution with given parameters.
Select a floating-point value from a uniform interval.
Scalar Box–Muller transform for floating-point types.