vSMC  v3.0.0
Scalable Monte Carlo
seed.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/seed.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_RNG_SEED_HPP
33 #define VSMC_RNG_SEED_HPP
34 
36 #include <vsmc/rng/counter.hpp>
37 
38 #define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem) \
39  VSMC_RUNTIME_ASSERT((div > rem), \
40  "**SeedGenerator::modulo** " \
41  "REMAINDER IS NOT SMALLER THAN THE DIVISOR")
42 
43 #define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(max) \
44  VSMC_RUNTIME_ASSERT((max > 1), \
45  "**SeedGenerator::modulo** " \
46  "THE MAXIMUM OF THE INTERNAL SEED IS NO LARGER THAN 1")
47 
50 #ifndef VSMC_SEED_RESULT_TYPE
51 #define VSMC_SEED_RESULT_TYPE unsigned
52 #endif
53 
54 namespace vsmc
55 {
56 
67 template <typename ID, typename ResultType = VSMC_SEED_RESULT_TYPE>
69 {
70  static_assert(std::is_unsigned<ResultType>::value,
71  "**SeedGenerator** USED WITH ResultType OTHER THAN UNSIGEND INTEGER "
72  "TYPES");
73 
74  public:
75  using result_type = ResultType;
76 
78 
80  const SeedGenerator<ID, ResultType> &) = delete;
81 
83  {
85 
86  return seed;
87  }
88 
90  template <typename RNGType>
91  void operator()(RNGType &rng)
92  {
93  rng.seed(static_cast<typename RNGType::result_type>(get()));
94  }
95 
97  template <typename OutputIter>
98  OutputIter operator()(std::size_t n, OutputIter first)
99  {
100  using RNGType = typename std::iterator_traits<OutputIter>::value_type;
101 
102  for (std::size_t i = 0; i != n; ++i, ++first)
103  first->seed(static_cast<typename RNGType::result_type>(get()));
104 
105  return first;
106  }
107 
109  void set(result_type s) { seed_ = s % max_; }
110 
113  {
114  ++seed_;
115  if (seed_ >= max_)
116  seed_ = 1;
117 
118  return seed_ * divisor_ + remainder_;
119  }
120 
122  result_type max() const { return max_; }
123 
125  result_type divisor() const { return divisor_; }
126 
128  result_type remainder() const { return remainder_; }
129 
132  {
134 
135  divisor_ = divisor;
136  remainder_ = remainder;
137  max_ = std::numeric_limits<result_type>::max() / divisor;
138 
140 
141  set(seed_);
142  }
143 
144  template <typename CharT, typename Traits>
145  friend std::basic_ostream<CharT, Traits> &operator<<(
146  std::basic_ostream<CharT, Traits> &os,
148  {
149  if (!os)
150  return os;
151 
152  os << sg.seed_ << ' ';
153  os << sg.max_ << ' ';
154  os << sg.divisor_ << ' ';
155  os << sg.remainder_ << ' ';
156 
157  return os;
158  }
159 
160  template <typename CharT, typename Traits>
161  friend std::basic_istream<CharT, Traits> &operator>>(
162  std::basic_istream<CharT, Traits> &is,
164  {
165  if (!is)
166  return is;
167 
168  result_type seed;
172  is >> std::ws >> seed;
173  is >> std::ws >> max;
174  is >> std::ws >> divisor;
175  is >> std::ws >> remainder;
176 
177  if (is) {
178  sg.seed_ = seed;
179  sg.max_ = max;
180  sg.divisor_ = divisor;
181  sg.remainder_ = remainder;
182  }
183 
184  return is;
185  }
186 
187  private:
188  std::atomic<result_type> seed_;
189  result_type max_;
190  result_type divisor_;
191  result_type remainder_;
192 
193  SeedGenerator() : seed_(0), max_(0), divisor_(1), remainder_(0)
194  {
195  modulo(divisor_, remainder_);
196  }
197 }; // class SeedGenerator
198 
202 
203 } // namespace vsmc
204 
205 #endif // VSMC_RNG_SEED_HPP
static SeedGenerator< ID, ResultType > & instance()
Definition: seed.hpp:82
Definition: monitor.hpp:48
OutputIter operator()(std::size_t n, OutputIter first)
Seed a sequence of RNGs.
Definition: seed.hpp:98
ResultType result_type
Definition: seed.hpp:75
void modulo(result_type divisor, result_type remainder)
Set the divisor and the remainder.
Definition: seed.hpp:131
result_type max() const
The maximum of the seed.
Definition: seed.hpp:122
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, SeedGenerator< ID, ResultType > &sg)
Definition: seed.hpp:161
void operator()(RNGType &rng)
Seed a single RNG.
Definition: seed.hpp:91
#define VSMC_RUNTIME_ASSERT_RNG_SEED_MAX(max)
Definition: seed.hpp:43
SeedGenerator< ID, ResultType > & operator=(const SeedGenerator< ID, ResultType > &)=delete
result_type divisor() const
The divisor of the output seed.
Definition: seed.hpp:125
#define VSMC_RUNTIME_ASSERT_RNG_SEED_GENERATOR_MODULO(div, rem)
Definition: seed.hpp:38
Seed generator.
Definition: seed.hpp:68
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const SeedGenerator< ID, ResultType > &sg)
Definition: seed.hpp:145
result_type remainder() const
The remainder of the output seed.
Definition: seed.hpp:128