haertel.hpp 4.1 KB

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