Branch data 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
|