RandomWrapper.hpp
1 /*
2  * STRUMPACK -- STRUctured Matrices PACKage, Copyright (c) 2014, The
3  * Regents of the University of California, through Lawrence Berkeley
4  * National Laboratory (subject to receipt of any required approvals
5  * from the U.S. Dept. of Energy). All rights reserved.
6  *
7  * If you have questions about your rights to use or distribute this
8  * software, please contact Berkeley Lab's Technology Transfer
9  * Department at TTD@lbl.gov.
10  *
11  * NOTICE. This software is owned by the U.S. Department of Energy. As
12  * such, the U.S. Government has been granted for itself and others
13  * acting on its behalf a paid-up, nonexclusive, irrevocable,
14  * worldwide license in the Software to reproduce, prepare derivative
15  * works, and perform publicly and display publicly. Beginning five
16  * (5) years after the date permission to assert copyright is obtained
17  * from the U.S. Department of Energy, and subject to any subsequent
18  * five (5) year renewals, the U.S. Government igs granted for itself
19  * and others acting on its behalf a paid-up, nonexclusive,
20  * irrevocable, worldwide license in the Software to reproduce,
21  * prepare derivative works, distribute copies to the public, perform
22  * publicly and display publicly, and to permit others to do so.
23  *
24  * Developers: Pieter Ghysels, Francois-Henry Rouet, Xiaoye S. Li.
25  * (Lawrence Berkeley National Lab, Computational Research
26  * Division).
27  */
33 #ifndef RANDOM_WRAPPER_HPP
34 #define RANDOM_WRAPPER_HPP
35 
36 #include <memory>
37 #include <random>
38 #include <iostream>
39 
40 namespace strumpack {
41 
46  namespace random {
47 
52  enum class RandomEngine {
53  LINEAR,
54  MERSENNE
55  };
56 
62  inline std::string get_name(RandomEngine e) {
63  switch (e) {
64  case RandomEngine::LINEAR: return "minstd_rand";
65  case RandomEngine::MERSENNE: return "mt19937";
66  }
67  return "unknown";
68  }
69 
74  enum class RandomDistribution {
75  NORMAL,
77  UNIFORM
79  };
80 
86  inline std::string get_name(RandomDistribution d) {
87  switch (d) {
88  case RandomDistribution::NORMAL: return "normal(0,1)";
89  case RandomDistribution::UNIFORM: return "uniform[0,1]";
90  }
91  return "unknown";
92  }
93 
105  template<typename real_t> class RandomGeneratorBase {
106  public:
107  virtual ~RandomGeneratorBase() {}
108  virtual void seed(std::size_t s) = 0;
109  virtual void seed(std::seed_seq& s) = 0;
110  virtual void seed(std::uint32_t i, std::uint32_t j) = 0;
111  virtual real_t get() = 0;
112  virtual real_t get(std::uint32_t i, std::uint32_t j) = 0;
113  virtual int flops_per_prng() = 0;
114  };
115 
128  template<typename real_t, typename E, typename D>
129  class RandomGenerator : public RandomGeneratorBase<real_t> {
130  public:
134  RandomGenerator() : e(0) {}
135 
139  RandomGenerator(std::size_t s) : e(s) {}
140 
144  void seed(std::size_t s) { e.seed(s); d.reset(); }
145 
149  void seed(std::seed_seq& s) { e.seed(s); d.reset(); }
150 
156  void seed(std::uint32_t i, std::uint32_t j) {
157  std::seed_seq seq{i,j};
158  seed(seq);
159  }
160 
164  real_t get() { return d(e); }
165 
169  real_t get(std::uint32_t i, std::uint32_t j) {
170  std::seed_seq seq{i,j};
171  seed(seq);
172  return get();
173  };
174 
180  if (std::is_same<D,std::normal_distribution<real_t>>())
181  return 23;
182  if (std::is_same<D,std::uniform_real_distribution<real_t>>())
183  return 7;
184  std::cout << "ERROR: random distribution not recognized" << std::endl;
185  return 0;
186  }
187 
188  private:
189  E e;
190  D d;
191  };
192 
203  template<typename real_t> std::unique_ptr<RandomGeneratorBase<real_t>>
204  make_random_generator(std::size_t seed, RandomEngine e,
205  RandomDistribution d) {
206  if (e == RandomEngine::LINEAR) {
208  return std::unique_ptr<RandomGeneratorBase<real_t>>
209  (new RandomGenerator<real_t,std::minstd_rand,
210  std::normal_distribution<real_t>>(seed));
211  else if (d == RandomDistribution::UNIFORM)
212  return std::unique_ptr<RandomGeneratorBase<real_t>>
213  (new RandomGenerator<real_t,std::minstd_rand,
214  std::uniform_real_distribution<real_t>>(seed));
215  } else if (e == RandomEngine::MERSENNE) {
217  return std::unique_ptr<RandomGeneratorBase<real_t>>
218  (new RandomGenerator<real_t,std::mt19937,
219  std::normal_distribution<real_t>>(seed));
220  else if (d == RandomDistribution::UNIFORM)
221  return std::unique_ptr<RandomGeneratorBase<real_t>>
222  (new RandomGenerator<real_t,std::mt19937,
223  std::uniform_real_distribution<real_t>>(seed));
224  }
225  return NULL;
226  }
227 
238  template<typename real_t> std::unique_ptr<RandomGeneratorBase<real_t>>
240  return make_random_generator<real_t>(0, e, d);
241  }
242 
251  template<typename real_t> std::unique_ptr<RandomGeneratorBase<real_t>>
252  make_default_random_generator(std::size_t seed=0) {
253  return make_random_generator<real_t>
255  }
256 
257  } // end namespace random
258 } // end namespace strumpack
259 
260 #endif // RANDOM_WRAPPER
class to wrap the C++11 random number generator/distribution
Definition: RandomWrapper.hpp:105
Class for a random number generator.
Definition: RandomWrapper.hpp:129
RandomGenerator()
Definition: RandomWrapper.hpp:134
void seed(std::uint32_t i, std::uint32_t j)
Definition: RandomWrapper.hpp:156
int flops_per_prng()
Definition: RandomWrapper.hpp:179
RandomGenerator(std::size_t s)
Definition: RandomWrapper.hpp:139
void seed(std::seed_seq &s)
Definition: RandomWrapper.hpp:149
real_t get()
Definition: RandomWrapper.hpp:164
void seed(std::size_t s)
Definition: RandomWrapper.hpp:144
real_t get(std::uint32_t i, std::uint32_t j)
Definition: RandomWrapper.hpp:169
std::unique_ptr< RandomGeneratorBase< real_t > > make_default_random_generator(std::size_t seed=0)
Definition: RandomWrapper.hpp:252
RandomEngine
Random number engine.
Definition: RandomWrapper.hpp:52
RandomDistribution
Definition: RandomWrapper.hpp:74
std::string get_name(RandomEngine e)
Definition: RandomWrapper.hpp:62
std::unique_ptr< RandomGeneratorBase< real_t > > make_random_generator(std::size_t seed, RandomEngine e, RandomDistribution d)
Definition: RandomWrapper.hpp:204
Definition: StrumpackOptions.hpp:43