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