vSMC
vSMC: Scalable Monte Carlo
xor_combine_engine.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/xor_combine_engine.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, 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_COMBINE_HPP
33 #define VSMC_RNG_COMBINE_HPP
34 
36 
37 #define VSMC_STATIC_ASSERT_RNG_XOR_COMBINE_UNSIGNED(result_type) \
38  VSMC_STATIC_ASSERT((cxx11::is_unsigned<result_type>::value), \
39  USE_XorCombineEngine_WITH_ENGINES_HAVE_RESULT_TYPE_NOT_AN_UNSIGNED_INTEGER_TYPE)
40 
41 #define VSMC_STATIC_ASSERT_RNG_XOR_COMBINE_SAME_TYPE(Eng1, Eng2) \
42  VSMC_STATIC_ASSERT((cxx11::is_same<typename Eng1::resultType, \
43  typename Eng2::resultType>::value), \
44  USE_XorCombineEngine_WITH_TWO_RNG_ENGINES_WITH_DIFFERENT_RESULT_TYPE)
45 
46 #define VSMC_STATIC_ASSERT_RNG_XOR_COMBINE \
47  VSMC_STATIC_ASSERT_RNG_XOR_COMBINE_UNSIGNED(result_type); \
48  VSMC_STATIC_ASSERT_RNG_XOR_COMBINE_SAME_TYPE(Eng1, Eng2);
49 
50 namespace vsmc {
51 
54 template <typename Eng1, typename Eng2,
55  typename Eng1::result_type S1 = 0,
56  typename Eng2::result_type S2 = 0>
58 {
59  public :
60 
61  typedef typename Eng1::result_type result_type;
62  typedef Eng1 engine1_type;
63  typedef Eng2 engine2_type;
64 
65  explicit XorCombineEngine (result_type s = 1) : eng1_(s), eng2_(s)
67 
68  template <typename SeedSeq>
69  explicit XorCombineEngine (SeedSeq &seq,
70  typename cxx11::enable_if<internal::is_seed_seq<SeedSeq,
72  >::value>::type * = VSMC_NULLPTR) : eng1_(seq), eng2_(seq)
74 
75  void seed (result_type s)
76  {
77  eng1_.seed(s);
78  eng2_.seed(s);
79  }
80 
81  template <typename SeedSeq>
82  void seed (SeedSeq &seq,
83  typename cxx11::enable_if<internal::is_seed_seq<SeedSeq,
85  >::value>::type * = VSMC_NULLPTR)
86  {
87  eng1_.seed(seq);
88  eng2_.seed(seq);
89  }
90 
91  engine1_type &eng1 () {return eng1_;}
92 
93  engine2_type &eng2 () {return eng2_;}
94 
95  static VSMC_CONSTEXPR result_type min VSMC_MNE ()
96  {
97  return Eng1::min VSMC_MNE () < Eng2::min VSMC_MNE () ?
98  Eng1::min VSMC_MNE : Eng2::min VSMC_MNE ();
99  }
100 
101  static VSMC_CONSTEXPR result_type max VSMC_MNE ()
102  {
103  return Eng1::max VSMC_MNE () > Eng2::max VSMC_MNE () ?
104  Eng1::max VSMC_MNE : Eng2::max VSMC_MNE ();
105  }
106 
107  result_type operator() () {return (eng1_()<<S1)^(eng2_()<<S2);}
108 
109  void discard (std::size_t nskip)
110  {
111  for (std::size_t i = 0; i != nskip; ++i)
112  operator()();
113  }
114 
115  friend inline bool operator== (
118  {return (eng1.eng1_ == eng2.eng1_ && eng1.eng2_ == eng2.eng2_);}
119 
120  friend inline bool operator!= (
123  {return !(eng1 == eng2);}
124 
125  template <typename CharT, typename Traits>
126  friend inline std::basic_ostream<CharT, Traits> &operator<< (
127  std::basic_ostream<CharT, Traits> &os,
129  {
130  if (!os.good())
131  return os;
132 
133  os << eng.eng1_ << ' ' << eng.eng2_;
134 
135  return os;
136  }
137 
138  template <typename CharT, typename Traits>
139  friend inline std::basic_istream<CharT, Traits> &operator>> (
140  std::basic_istream<CharT, Traits> &is,
142  {
143  if (!is.good())
144  return is;
145 
146  engine1_type eng1_tmp;
147  engine2_type eng2_tmp;
148  is >> std::ws >> eng1_tmp;
149  is >> std::ws >> eng2_tmp;
150 
151  if (is.good()) {
152 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
153  eng.eng1_ = cxx11::move(eng1_tmp);
154  eng.eng2_ = cxx11::move(eng2_tmp);
155 #else
156  eng.eng1_ = eng1_tmp;
157  eng.eng2_ = eng2_tmp;
158 #endif
159  }
160 
161  return is;
162  }
163 
164  private :
165 
166  engine1_type eng1_;
167  engine2_type eng2_;
168 }; // class XorCombineEngine
169 
170 } // namespace vsmc
171 
172 #endif // VSMC_RNG_COMBINE_HPP
Definition: adapter.hpp:37
XorCombineEngine(result_type s=1)
#define VSMC_STATIC_ASSERT_RNG_XOR_COMBINE
void seed(result_type s)
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
static constexpr result_type max()
Eng1::result_type result_type
#define VSMC_MNE
Avoid MSVC stupid behavior: MNE = Macro No Expansion.
Definition: defines.hpp:38
void discard(std::size_t nskip)
remove_reference< T >::type && move(T &&t) noexcept
void seed(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorCombineEngine< Eng1, Eng2, S1, S2 > >::value >::type *=nullptr)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, XorCombineEngine< Eng1, Eng2, S1, S2 > &eng)
#define VSMC_NULLPTR
nullptr
Definition: defines.hpp:79
XorCombineEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, result_type, XorCombineEngine< Eng1, Eng2, S1, S2 > >::value >::type *=nullptr)
static constexpr result_type min()
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const XorCombineEngine< Eng1, Eng2, S1, S2 > &eng)
Combine two RNG engines using XOR.
friend bool operator!=(const XorCombineEngine< Eng1, Eng2, S1, S2 > &eng1, const XorCombineEngine< Eng1, Eng2, S1, S2 > &eng2)
friend bool operator==(const XorCombineEngine< Eng1, Eng2, S1, S2 > &eng1, const XorCombineEngine< Eng1, Eng2, S1, S2 > &eng2)