1 /* boost random/inversive_congruential.hpp header file
3 * Copyright Jens Maurer 2000-2001
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)
8 * See http://www.boost.org for most recent version including documentation.
13 * 2001-02-18 moved to individual header files
16 #ifndef BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
17 #define BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
22 #include <boost/config.hpp>
23 #include <boost/static_assert.hpp>
24 #include <boost/random/detail/config.hpp>
25 #include <boost/random/detail/const_mod.hpp>
30 // Eichenauer and Lehn 1986
31 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
32 class inversive_congruential
35 typedef IntType result_type
;
36 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
37 static const bool has_fixed_range
= true;
38 static const result_type min_value
= (b
== 0 ? 1 : 0);
39 static const result_type max_value
= p
-1;
41 BOOST_STATIC_CONSTANT(bool, has_fixed_range
= false);
43 BOOST_STATIC_CONSTANT(result_type
, multiplier
= a
);
44 BOOST_STATIC_CONSTANT(result_type
, increment
= b
);
45 BOOST_STATIC_CONSTANT(result_type
, modulus
= p
);
47 result_type min
BOOST_PREVENT_MACRO_SUBSTITUTION () const { return b
== 0 ? 1 : 0; }
48 result_type max
BOOST_PREVENT_MACRO_SUBSTITUTION () const { return p
-1; }
50 explicit inversive_congruential(IntType y0
= 1) : value(y0
)
52 BOOST_STATIC_ASSERT(b
>= 0);
53 BOOST_STATIC_ASSERT(p
> 1);
54 BOOST_STATIC_ASSERT(a
>= 1);
58 template<class It
> inversive_congruential(It
& first
, It last
)
59 { seed(first
, last
); }
61 void seed(IntType y0
= 1) { value
= y0
; if(b
== 0) assert(y0
> 0); }
62 template<class It
> void seed(It
& first
, It last
)
65 throw std::invalid_argument("inversive_congruential::seed");
70 typedef const_mod
<IntType
, p
> do_mod
;
71 value
= do_mod::mult_add(a
, do_mod::invert(value
), b
);
75 static bool validation(result_type x
) { return val
== x
; }
77 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
79 #ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
80 template<class CharT
, class Traits
>
81 friend std::basic_ostream
<CharT
,Traits
>&
82 operator<<(std::basic_ostream
<CharT
,Traits
>& os
, inversive_congruential x
)
83 { os
<< x
.value
; return os
; }
85 template<class CharT
, class Traits
>
86 friend std::basic_istream
<CharT
,Traits
>&
87 operator>>(std::basic_istream
<CharT
,Traits
>& is
, inversive_congruential
& x
)
88 { is
>> x
.value
; return is
; }
91 friend bool operator==(inversive_congruential x
, inversive_congruential y
)
92 { return x
.value
== y
.value
; }
93 friend bool operator!=(inversive_congruential x
, inversive_congruential y
)
96 // Use a member function; Streamable concept not supported.
97 bool operator==(inversive_congruential rhs
) const
98 { return value
== rhs
.value
; }
99 bool operator!=(inversive_congruential rhs
) const
100 { return !(*this == rhs
); }
106 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
107 // A definition is required even for integral static constants
108 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
109 const bool inversive_congruential
<IntType
, a
, b
, p
, val
>::has_fixed_range
;
110 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
111 const typename inversive_congruential
<IntType
, a
, b
, p
, val
>::result_type inversive_congruential
<IntType
, a
, b
, p
, val
>::min_value
;
112 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
113 const typename inversive_congruential
<IntType
, a
, b
, p
, val
>::result_type inversive_congruential
<IntType
, a
, b
, p
, val
>::max_value
;
114 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
115 const typename inversive_congruential
<IntType
, a
, b
, p
, val
>::result_type inversive_congruential
<IntType
, a
, b
, p
, val
>::multiplier
;
116 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
117 const typename inversive_congruential
<IntType
, a
, b
, p
, val
>::result_type inversive_congruential
<IntType
, a
, b
, p
, val
>::increment
;
118 template<class IntType
, IntType a
, IntType b
, IntType p
, IntType val
>
119 const typename inversive_congruential
<IntType
, a
, b
, p
, val
>::result_type inversive_congruential
<IntType
, a
, b
, p
, val
>::modulus
;
122 } // namespace random
124 typedef random::inversive_congruential
<int32_t, 9102, 2147483647-36884165,
125 2147483647, 0> hellekalek1995
;
129 #endif // BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP