HILA
Loading...
Searching...
No Matches
random.h
1#ifndef RANDOM_H_
2#define RANDOM_H_
3
4namespace hila {
5
6constexpr bool device_rng_off = false;
7constexpr bool device_rng_on = true;
8
9
10/**
11 *@brief Seed random generators with 64-bit unsigned value.
12 * On MPI shuffles the seed so that different MPI ranks are seeded with different values.
13 */
14void seed_random(uint64_t seed, bool device_rng = true);
15
16/**
17 *@brief Check if RNG is seeded already
18 */
19bool is_rng_seeded();
20
21/**
22 *@brief Initialize host (CPU) random number generator separately, done implicitly by `seed_random()`
23 */
24void initialize_host_rng(uint64_t seed);
25
26/**
27 *@brief Initialize device random number generator on GPUs, if application run on GPU platform.
28 * No effect on other archs.
29 */
30void initialize_device_rng(uint64_t seed);
31
32/**
33 *@brief Free GPU RNG state, does nothing on non-GPU archs.
34 */
35void free_device_rng();
36
37///
38///
39
40/**
41 *@brief Check if the RNG on GPU is allocated and ready to use.
42 */
43bool is_device_rng_on();
44
45
46/////////////////////////////////////////////////////////////////////////////////////////////////
47
48// It is important that the random number generators random(), gaussrand() and gaussrand2()
49// are marked as "loop function" and "contains rng", because hilapp does not have a view
50// inside them from all compilation units - although hila::random() has special treatment
51
52
53/**
54 * @brief Real valued uniform random number generator.
55 * @details Returns an uniform double precision random number in interval \f$[0,1)\f$.
56 * This function can be called from outside or inside site loops (on GPU if the device rng is initialized).
57 *
58 * Uses
59 * [std::uniform_real_distribution](https://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution)
60 *
61 * @return double
62 */
63#pragma hila contains_rng loop_function
64double random();
65
66// alias for host (CPU) rng, used in GPU code generation. Must not be used inside onsites() {}. This
67// routine is not normally needed in user code, instead use standard hila::random().
68double host_random();
69
70#pragma hila contains_rng loop_function
71
72/**
73 * @brief Gaussian random generation routine
74 */
75double gaussrand();
76
77
78/**
79 *@brief `hila::gaussrand2` returns 2 Gaussian distributed random numbers with variance \f$1.0\f$.
80 *@details Useful because Box-Muller algorithm computes 2 values at the same time.
81 */
82#pragma hila contains_rng loop_function
83double gaussrand2(double &out2);
84
85/**
86 *@brief Check if RNG is initialized, do what the name says.
87 */
89
90/**
91 *@brief Template function `const T & hila::random(T & var)`
92 * sets the argument to a random value, and return a constant reference to it.
93 *@details For example
94 *\code{.cpp}
95 * Complex<double> c;
96 * auto n = hila::random(c).abs();
97 *\endcode
98 *sets the variable `c` to complex random value and calculates its absolute value.
99 *`c.real()` and `c.imag()` will be \f$\in [0,1)\f$.
100 *
101 *For hila classes relies on the existence of method `T::random()` (i.e. `var.random()`),
102 *this function typically sets the argument real numbers to interval \f$[0,1)\f$ if `type T` is arithmatic.
103 *if T is more commplicated classes such as `SU<N,T>`-matrix, this function sets the argument to
104 * valid random `SU<N,T>`.
105 *
106 * Advantage of this function over class function `T::random()` is that the argument can be
107 * of elementary arithmetic type.
108 */
109template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
110T random(out_only T &val) {
111 val = hila::random();
112 return val;
113}
114
115template <typename T, std::enable_if_t<!std::is_arithmetic<T>::value, int> = 0>
116T &random(out_only T &val) {
117 val.random();
118 return val;
119}
120
121/**
122 *@brief Template function `T hila::random<T>()` without argument.
123 *@details This is used to generate random value for `type T` without defined variable.
124 *Example:
125 *\code{.cpp}
126 * auto n = hila::random<Complex<double>>().abs();
127 *\endcode
128 * calculates the norm of a random complex value.
129 *`hila::random<double>()` is functionally equivalent to `hila::random()`
130 */
131template <typename T>
133 T val;
134 hila::random(val);
135 return val;
136}
137
138
139/**
140 * @brief Template function
141 * `const T & hila::gaussian_random(T & variable,double width=1)`
142 * @details Sets the argument to a gaussian random value, and return a constant reference to it.
143 * Optional second argument width sets the \f$variance=width^{2}\f$ (\f$default==1\f$)
144 *
145 * For example:
146 * \code {.cpp}
147 * Complex<double> c;
148 * auto n = sqr(hila::gaussian_random(c));
149 * \endcode
150 * sets the variable `c` to complex gaussian random value and stores its square in `n`.
151 *
152 * This function is for hila classes relies on the existence of method `T::gaussian_random()`.
153 * The advantage for this function over class function `T::random()` is that the argument can be
154 * of elementary arithmetic type.
155 * @return T by reference
156 */
157template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
158T gaussian_random(out_only T &val, double w = 1.0) {
159 val = hila::gaussrand() * w;
160 return val;
161}
162
163template <typename T, std::enable_if_t<!std::is_arithmetic<T>::value, int> = 0>
164T &gaussian_random(out_only T &val, double w = 1.0) {
165 val.gaussian_random(w);
166 return val;
167}
168
169
170/**
171 *@brief Template function
172 * `T hila::gaussian_random<T>()`,generates gaussian random value of `type T`, with variance \f$1\f$.
173 *@details For example,
174 *\code{.cpp}
175 * auto n = hila::gaussian_random<Complex<double>>().abs();
176 *\endcode
177 *calculates the norm of a gaussian random complex value.
178 *
179 *@note there is no width/variance parameter, because of danger of confusion
180 *with above `hila::gaussian_random(value)`
181 */
182template <typename T>
184 T val;
186 return val;
187}
188
189
190} // namespace hila
191
192
193#endif
Invert diagonal + const. matrix using Sherman-Morrison formula.
Definition array.h:920
T gaussian_random()
Template function T hila::gaussian_random<T>(),generates gaussian random value of type T,...
Definition random.h:183
void initialize_device_rng(uint64_t seed)
Initialize device random number generator on GPUs, if application run on GPU platform....
Definition hila_gpu.cpp:70
void free_device_rng()
Free GPU RNG state, does nothing on non-GPU archs.
Definition hila_gpu.cpp:106
bool is_device_rng_on()
Check if the RNG on GPU is allocated and ready to use.
Definition hila_gpu.cpp:57
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:120
double gaussrand()
Gaussian random generation routine.
Definition random.cpp:212
void seed_random(uint64_t seed, bool device_rng=true)
Seed random generators with 64-bit unsigned value. On MPI shuffles the seed so that different MPI ran...
Definition random.cpp:86
bool is_rng_seeded()
Check if RNG is seeded already.
Definition random.cpp:239
void initialize_host_rng(uint64_t seed)
Initialize host (CPU) random number generator separately, done implicitly by seed_random()
Definition random.cpp:61
double gaussrand2(double &out2)
hila::gaussrand2 returns 2 Gaussian distributed random numbers with variance .
Definition random.cpp:177
void check_that_rng_is_initialized()
Check if RNG is initialized, do what the name says.
Definition random.cpp:252