Line data Source code
1 : // Struct Randn
2 : // This struct can be used for sampling normal distribution function
3 : // on unbounded domain.
4 : //
5 : #ifndef IPPL_RANDN_H
6 : #define IPPL_RANDN_H
7 :
8 : #include "Random/Distribution.h"
9 : #include "Random/Utility.h"
10 :
11 : namespace ippl {
12 : namespace random {
13 :
14 : /*!
15 : * @struct randn
16 : * @brief Functor to generate random numbers from a normal distribution.
17 : *
18 : * This functor can be used to generates random numbers from a normal distribution with
19 : * mean 0 and standard deviation 1.
20 : *
21 : * @tparam T Data type of the random numbers.
22 : * @tparam GeneratorPool Type of the random number generator pool.
23 : * @tparam Dim Dimensionality of the random numbers.
24 : */
25 : template <typename T, unsigned Dim>
26 : struct randn {
27 : using view_type =
28 : typename ippl::detail::ViewType<ippl::Vector<double, Dim>, 1>::view_type;
29 : using GeneratorPool = typename Kokkos::Random_XorShift64_Pool<>;
30 :
31 : // Output View for the random numbers
32 : view_type v;
33 :
34 : // The GeneratorPool
35 : GeneratorPool rand_pool;
36 :
37 : T mu[Dim];
38 : T sd[Dim];
39 : /*!
40 : * @brief Constructor for the randn functor.
41 : *
42 : * @param v_ Output view for the random numbers.
43 : * @param rand_pool_ The random number generator pool.
44 : * @param mu The array of means in each dimension
45 : * @param sd The array of standard deviation in each dimension
46 : */
47 0 : KOKKOS_INLINE_FUNCTION randn(view_type v_, GeneratorPool rand_pool_, T* mu_p, T* sd_p)
48 0 : : v(v_)
49 0 : , rand_pool(rand_pool_) {
50 0 : for (unsigned int i = 0; i < Dim; i++) {
51 0 : mu[i] = mu_p[i];
52 0 : sd[i] = sd_p[i];
53 : }
54 0 : }
55 :
56 : KOKKOS_INLINE_FUNCTION randn(view_type v_, GeneratorPool rand_pool_)
57 : : v(v_)
58 : , rand_pool(rand_pool_) {
59 : for (unsigned int i = 0; i < Dim; i++) {
60 : mu[i] = 0.0;
61 : sd[i] = 1.0;
62 : }
63 : }
64 :
65 : /*!
66 : * @brief Getter function for mean in idx dimension
67 : *
68 : * @param idx The index indicating the dimension.
69 : */
70 : KOKKOS_INLINE_FUNCTION const T& getMu(unsigned int idx) const { return mu[idx]; }
71 :
72 : /*!
73 : * @brief Getter function for the standard deviation in idx dimension
74 : *
75 : * @param idx The index indicating the dimension.
76 : */
77 : KOKKOS_INLINE_FUNCTION const T& getSd(unsigned int idx) const { return sd[idx]; }
78 :
79 : /*!
80 : * @brief Operator to generate random numbers.
81 : *
82 : * @param i Index for the random numbers.
83 : */
84 0 : KOKKOS_INLINE_FUNCTION void operator()(const size_t i) const {
85 : // Get a random number state from the pool for the active thread
86 0 : typename GeneratorPool::generator_type rand_gen = rand_pool.get_state();
87 :
88 0 : for (unsigned d = 0; d < Dim; ++d) {
89 0 : v(i)[d] = mu[d] + sd[d] * rand_gen.normal(0.0, 1.0);
90 : }
91 :
92 : // Give the state back, which will allow another thread to acquire it
93 0 : rand_pool.free_state(rand_gen);
94 0 : }
95 : };
96 : } // namespace random
97 : } // namespace ippl
98 :
99 : #endif
|