• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* haertel.hpp file
2  *
3  * Copyright Jens Maurer 2000, 2002
4  * Distributed under the Boost Software License, Version 1.0. (See
5  * accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  * $Id$
9  *
10  * Revision history
11  */
12 
13 /*
14  * NOTE: This is not part of the official boost submission.  It exists
15  * only as a collection of ideas.
16  */
17 
18 #ifndef BOOST_RANDOM_HAERTEL_HPP
19 #define BOOST_RANDOM_HAERTEL_HPP
20 
21 #include <boost/cstdint.hpp>
22 #include <boost/random/linear_congruential.hpp>
23 #include <boost/random/inversive_congruential.hpp>
24 
25 namespace boost {
26 namespace random {
27 
28 // Wikramaratna 1989  ACORN
29 template<class IntType, int k, IntType m, IntType val>
30 class additive_congruential
31 {
32 public:
33   typedef IntType result_type;
34 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
35   static const bool has_fixed_range = true;
36   static const result_type min_value = 0;
37   static const result_type max_value = m-1;
38 #else
39   enum {
40     has_fixed_range = true,
41     min_value = 0,
42     max_value = m-1
43   };
44 #endif
45   template<class InputIterator>
additive_congruential(InputIterator start)46   explicit additive_congruential(InputIterator start) { seed(start); }
47   template<class InputIterator>
seed(InputIterator start)48   void seed(InputIterator start)
49   {
50     for(int i = 0; i <= k; ++i, ++start)
51       values[i] = *start;
52   }
53 
operator ()()54   result_type operator()()
55   {
56     for(int i = 1; i <= k; ++i) {
57       IntType tmp = values[i-1] + values[i];
58       if(tmp >= m)
59         tmp -= m;
60       values[i] = tmp;
61     }
62     return values[k];
63   }
validation() const64   result_type validation() const { return val; }
65 private:
66   IntType values[k+1];
67 };
68 
69 
70 template<class IntType, int r, int s, IntType m, IntType val>
71 class lagged_fibonacci_int
72 {
73 public:
74   typedef IntType result_type;
75 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
76   static const bool has_fixed_range = true;
77   static const result_type min_value = 0;
78   static const result_type max_value = m-1;
79 #else
80   enum {
81     has_fixed_range = true,
82     min_value = 0,
83     max_value = m-1
84   };
85 #endif
lagged_fibonacci_int(IntType start)86   explicit lagged_fibonacci_int(IntType start) { seed(start); }
87   template<class Generator>
lagged_fibonacci_int(Generator & gen)88   explicit lagged_fibonacci_int(Generator & gen) { seed(gen); }
seed(IntType start)89   void seed(IntType start)
90   {
91     linear_congruential<uint32_t, 299375077, 0, 0, 0> init;
92     seed(init);
93   }
94   template<class Generator>
seed(Generator & gen)95   void seed(Generator & gen)
96   {
97     assert(r > s);
98     for(int i = 0; i < 607; ++i)
99       values[i] = gen();
100     current = 0;
101     lag = r-s;
102   }
103 
operator ()()104   result_type operator()()
105   {
106     result_type tmp = values[current] + values[lag];
107     if(tmp >= m)
108       tmp -= m;
109     values[current] = tmp;
110     ++current;
111     if(current >= r)
112       current = 0;
113     ++lag;
114     if(lag >= r)
115       lag = 0;
116     return tmp;
117   }
validation() const118   result_type validation() const { return val; }
119 private:
120   result_type values[r];
121   int current, lag;
122 };
123 
124 } // namespace random
125 } // namespace boost
126 
127 // distributions from Haertel's dissertation
128 // (additional parameterizations of the basic templates)
129 namespace Haertel {
130   typedef boost::random::linear_congruential<boost::uint64_t, 45965, 453816691,
131     (boost::uint64_t(1)<<31), 0> LCG_Af2;
132   typedef boost::random::linear_congruential<boost::uint64_t, 211936855, 0,
133     (boost::uint64_t(1)<<29)-3, 0> LCG_Die1;
134   typedef boost::random::linear_congruential<boost::uint32_t, 2824527309u, 0,
135     0, 0> LCG_Fis;
136   typedef boost::random::linear_congruential<boost::uint64_t, 950706376u, 0,
137     (boost::uint64_t(1)<<31)-1, 0> LCG_FM;
138   typedef boost::random::linear_congruential<boost::int32_t, 51081, 0,
139     2147483647, 0> LCG_Hae;
140   typedef boost::random::linear_congruential<boost::uint32_t, 69069, 1,
141     0, 0> LCG_VAX;
142   typedef boost::random::inversive_congruential<boost::int64_t, 240318, 197,
143     1000081, 0> NLG_Inv1;
144   typedef boost::random::inversive_congruential<boost::int64_t, 15707262,
145     13262967, (1<<24)-17, 0> NLG_Inv2;
146   typedef boost::random::inversive_congruential<boost::int32_t, 1, 1,
147     2147483647, 0> NLG_Inv4;
148   typedef boost::random::inversive_congruential<boost::int32_t, 1, 2,
149     1<<30, 0> NLG_Inv5;
150   typedef boost::random::additive_congruential<boost::int32_t, 6,
151     (1<<30)-35, 0> MRG_Acorn7;
152   typedef boost::random::lagged_fibonacci_int<boost::uint32_t, 607, 273,
153     0, 0> MRG_Fib2;
154 } // namespace Haertel
155 
156 #endif
157