IMP logo
IMP Reference Guide  2.17.0
The Integrative Modeling Platform
random_utils.h
Go to the documentation of this file.
1 /**
2  * \file IMP/random_utils.h
3  * \brief Random number utility functions used by IMP.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_RANDOM_UTILS_H
10 #define IMPKERNEL_RANDOM_UTILS_H
11 
12 #include <IMP/kernel_config.h>
13 #include <IMP/Vector.h>
14 #include <IMP/random.h>
15 #ifdef IMP_KERNEL_CUDA_LIB
16 // #warning "random_utils - kernel CUDA_LIB!"
17 #include "IMP/internal/random_number_generation_cuda.h"
18 #else
19 // #warning "random_utils - kernel CUDA_BOOST!"
20 #include "IMP/internal/random_number_generation_boost.h"
21 #endif
22 
23 #include <boost/random/mersenne_twister.hpp>
24 #include <boost/random/uniform_real.hpp>
25 
26 // #include <ctime> // DEBUG
27 //#include <sys/time.h> // DEBUG
28 
29 IMPKERNEL_BEGIN_NAMESPACE
30 
31 //! Fill the double array with random normally distributed values.
32 /** The pre-allocated array is filled with n double numbers with
33  random normally distributed values with specified mean and
34  standard deviation.
35 
36  @param v vector array that will be resized to n
37  @param n size of array
38  @param mean mean of normal distribution
39  @param stddev standard deviation
40 
41  @note Implementation relies on random_number_generator (a boost
42  random number generator), or on the CUDA random number
43  generator if kernel is built with IMP_KERNEL_CUDA_LIB cmake
44  flag. Either is initially seeded with get_random_seed().
45 */
46 template<typename RealType>
48 (Vector<RealType>& v, unsigned int n,
49  RealType mean=0.0, RealType stddev=1.0)
50 {
51  if(n==0) return;
52  if(n>v.size())
53  v.resize(n);
54  // struct timeval start_time; // DEBUG
55  //struct timeval t_time; // DEBUG
56  //gettimeofday(&start_time, 0); // DEBUG
57 #ifdef IMP_KERNEL_CUDA_LIB
58  IMPcuda::kernel::internal::init_gpu_rng_once(get_random_seed());
59  IMPcuda::kernel::internal::get_random_numbers_normal_cuda
60  (&v[0], n, mean, stddev);
61 #else
62  internal::get_random_numbers_normal_boost(&v[0], n, mean, stddev);
63 #endif
64  // gettimeofday(&t_time, 0); // DEBUG
65  // double time_diff_sec= (double)( (t_time.tv_sec - start_time.tv_sec)
66  // + 0.000001 * (t_time.tv_usec - start_time.tv_usec) ); // DEBUG
67  // std::cout << "get_random_numbers_uniform_cuda(" << n
68  // << ") " << time_diff_sec << " seconds" << std::endl; // DEBUG
69 
70 }
71 
72 //! Fill the float array with random uniformly distributed values.
73 /** Fill a pre-allocated array of n float numbers with random uniformly
74  distributed values in the [0..1) range.
75 
76  @param v vector array that will be resized to n
77  @param n size of array
78 
79  @note Implementation relies on random_number_generator (a boost
80  random number generator), or on the CUDA random number generator
81  if kernel is built with CUDA flag. Either is initially seeded with
82  get_random_seed().
83  */
84 template<typename RealType>
86 (Vector<RealType>& v, unsigned int n)
87 {
88  if(n==0) return;
89  if(n>v.size())
90  v.resize(n);
91 #ifdef IMP_KERNEL_CUDA_LIB
92  IMPcuda::kernel::internal::init_gpu_rng_once(get_random_seed());
93  IMPcuda::kernel::internal::get_random_numbers_uniform_cuda (&v[0], n);
94 #else
95  internal::get_random_numbers_uniform_boost(&v[0], n);
96 #endif
97 }
98 
99 //! Return a uniformly distributed float number in range [0..1)
100 /** @note the random number is retrieved from a cache of random
101  numbers generated using GPU if compiled with CUDA, or from boost
102  without a cache otherwise.
103  */
105 
106 //! Return a uniformly distributed float number in range [min..max)
107 /** @note the random number is retrieved from a cache of random
108  numbers generated using GPU if compiled with CUDA, or from boost
109  without a cache otherwise.
110  */
111 float get_random_float_uniform(float min, float max);
112 
113 //! Return a uniformly distributed double number in range [0..1)
114 /** @note the random number is retrieved from a cache of random
115  numbers generated using GPU if compiled with CUDA, or from boost
116  without a cache otherwise.
117  */
119 
120 //! Return a uniformly distributed double number in range [min..max)
121 /** @note the random number is retrieved from a cache of random
122  numbers generated using GPU if compiled with CUDA, or from boost
123  without a cache otherwise.
124  */
125 double get_random_double_uniform(double min, double max);
126 
127 /************ implementation of inline functions *******/
128 
129 inline float
131 {
132  // use cache only with cuda
133 #ifdef IMP_KERNEL_CUDA_LIB
134  const static unsigned int cache_n=20000000;
135  static IMP::Vector<float> cache;
136  static unsigned int i=0;
137  if(i>=cache.size()){
138  get_random_numbers_uniform(cache, cache_n);
139  i=0;
140  }
141  return cache[i++];
142 #else
143  static boost::uniform_real<float> rand(0.0, 1.0);
144  return rand(random_number_generator);
145 #endif
146 }
147 
148 inline float
149 get_random_float_uniform(float min, float max)
150 {
151  // use cache only with cuda
152 #ifdef IMP_KERNEL_CUDA_LIB
153  return get_random_float_uniform()*(max-min)+min;
154 #else
155  ::boost::uniform_real<float> rand(min, max);
156  return rand(random_number_generator);
157 #endif
158 }
159 
160 
161 inline double
163 {
164 #ifdef IMP_KERNEL_CUDA_LIB
165  const static unsigned int cache_n=2000000;
166  static IMP::Vector<double> cache;
167  static unsigned int i=0;
168  if(i>=cache.size()){
169  get_random_numbers_uniform(cache, cache_n);
170  i=0;
171  }
172  return cache[i++];
173 #else
174  static boost::uniform_real<double> rand(0.0, 1.0);
175  return rand(random_number_generator);
176 #endif
177 }
178 
179 inline double
180 get_random_double_uniform(double min, double max)
181 {
182 #ifdef IMP_KERNEL_CUDA_LIB
183  return get_random_double_uniform()*(max-min)+min;
184 #else
185  ::boost::uniform_real<double> rand(min, max);
186  return rand(random_number_generator);
187 #endif
188 }
189 
190 
191 
192 IMPKERNEL_END_NAMESPACE
193 
194 #endif /* IMPKERNEL_RANDOM_UTILS_H */
void get_random_numbers_uniform(Vector< RealType > &v, unsigned int n)
Fill the float array with random uniformly distributed values.
Definition: random_utils.h:86
A more IMP-like version of the std::vector.
Definition: Vector.h:40
boost::uint64_t get_random_seed()
Return the initial random seed.
double get_random_double_uniform(double min, double max)
Return a uniformly distributed double number in range [min..max)
Definition: random_utils.h:180
float get_random_float_uniform(float min, float max)
Return a uniformly distributed float number in range [min..max)
Definition: random_utils.h:149
A class for storing lists of IMP items.
void get_random_numbers_normal(Vector< RealType > &v, unsigned int n, RealType mean=0.0, RealType stddev=1.0)
Fill the double array with random normally distributed values.
Definition: random_utils.h:48
Random number generators used by IMP.
RandomNumberGenerator random_number_generator
A shared non-GPU random number generator.