• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* boost random/lagged_fibonacci.hpp header file
2  *
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)
7  *
8  * See http://www.boost.org for most recent version including documentation.
9  *
10  * $Id$
11  *
12  * Revision history
13  *  2013-10-14  fixed some warnings with Wshadow (mgaunard)
14  *  2001-02-18  moved to individual header files
15  */
16 
17 #ifndef BOOST_RANDOM_LAGGED_FIBONACCI_HPP
18 #define BOOST_RANDOM_LAGGED_FIBONACCI_HPP
19 
20 #include <istream>
21 #include <iosfwd>
22 #include <algorithm>     // std::max
23 #include <iterator>
24 #include <boost/config/no_tr1/cmath.hpp>         // std::pow
25 #include <boost/config.hpp>
26 #include <boost/limits.hpp>
27 #include <boost/cstdint.hpp>
28 #include <boost/integer/integer_mask.hpp>
29 #include <boost/random/linear_congruential.hpp>
30 #include <boost/random/uniform_01.hpp>
31 #include <boost/random/detail/config.hpp>
32 #include <boost/random/detail/seed.hpp>
33 #include <boost/random/detail/operators.hpp>
34 #include <boost/random/detail/generator_seed_seq.hpp>
35 
36 namespace boost {
37 namespace random {
38 
39 /**
40  * Instantiations of class template \lagged_fibonacci_engine model a
41  * \pseudo_random_number_generator. It uses a lagged Fibonacci
42  * algorithm with two lags @c p and @c q:
43  * x(i) = x(i-p) + x(i-q) (mod 2<sup>w</sup>) with p > q.
44  */
45 template<class UIntType, int w, unsigned int p, unsigned int q>
46 class lagged_fibonacci_engine
47 {
48 public:
49     typedef UIntType result_type;
50     BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
51     BOOST_STATIC_CONSTANT(int, word_size = w);
52     BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
53     BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
54 
55     BOOST_STATIC_CONSTANT(UIntType, default_seed = 331u);
56 
57     /** Returns the smallest value that the generator can produce. */
BOOST_PREVENT_MACRO_SUBSTITUTION()58     static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
59     /** Returns the largest value that the generator can produce. */
BOOST_PREVENT_MACRO_SUBSTITUTION()60     static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
61     { return low_bits_mask_t<w>::sig_bits; }
62 
63     /** Creates a new @c lagged_fibonacci_engine and calls @c seed(). */
lagged_fibonacci_engine()64     lagged_fibonacci_engine() { seed(); }
65 
66     /** Creates a new @c lagged_fibonacci_engine and calls @c seed(value). */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_engine,UIntType,value)67     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_engine,
68         UIntType, value)
69     { seed(value); }
70 
71     /** Creates a new @c lagged_fibonacci_engine and calls @c seed(seq). */
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_engine,SeedSeq,seq)72     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_engine,
73         SeedSeq, seq)
74     { seed(seq); }
75 
76     /**
77      * Creates a new @c lagged_fibonacci_engine and calls @c seed(first, last).
78      */
lagged_fibonacci_engine(It & first,It last)79     template<class It> lagged_fibonacci_engine(It& first, It last)
80     { seed(first, last); }
81 
82     // compiler-generated copy ctor and assignment operator are fine
83 
84     /** Calls @c seed(default_seed). */
seed()85     void seed() { seed(default_seed); }
86 
87     /**
88      * Sets the state of the generator to values produced by
89      * a \minstd_rand0 generator.
90      */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_engine,UIntType,value)91     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_engine,
92         UIntType, value)
93     {
94         minstd_rand0 intgen(static_cast<boost::uint32_t>(value));
95         detail::generator_seed_seq<minstd_rand0> gen(intgen);
96         seed(gen);
97     }
98 
99     /**
100      * Sets the state of the generator using values produced by seq.
101      */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_engine,SeedSeq,seq)102     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_engine, SeedSeq, seq)
103     {
104         detail::seed_array_int<w>(seq, x);
105         i = long_lag;
106     }
107 
108     /**
109      * Sets the state of the generator to values from the iterator
110      * range [first, last).  If there are not enough elements in the
111      * range [first, last) throws @c std::invalid_argument.
112      */
113     template<class It>
seed(It & first,It last)114     void seed(It& first, It last)
115     {
116         detail::fill_array_int<w>(first, last, x);
117         i = long_lag;
118     }
119 
120     /** Returns the next value of the generator. */
operator ()()121     result_type operator()()
122     {
123         if(i >= long_lag)
124             fill();
125         return x[i++];
126     }
127 
128     /** Fills a range with random values */
129     template<class Iter>
generate(Iter first,Iter last)130     void generate(Iter first, Iter last)
131     { detail::generate_from_int(*this, first, last); }
132 
133     /** Advances the state of the generator by @c z. */
discard(boost::uintmax_t z)134     void discard(boost::uintmax_t z)
135     {
136         for(boost::uintmax_t j = 0; j < z; ++j) {
137             (*this)();
138         }
139     }
140 
141     /**
142      * Writes the textual representation of the generator to a @c std::ostream.
143      */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,lagged_fibonacci_engine,f)144     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_engine, f)
145     {
146         os << f.i;
147         for(unsigned int j = 0; j < f.long_lag; ++j)
148             os << ' ' << f.x[j];
149         return os;
150     }
151 
152     /**
153      * Reads the textual representation of the generator from a @c std::istream.
154      */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,lagged_fibonacci_engine,f)155     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_engine, f)
156     {
157         is >> f.i >> std::ws;
158         for(unsigned int j = 0; j < f.long_lag; ++j)
159             is >> f.x[j] >> std::ws;
160         return is;
161     }
162 
163     /**
164      * Returns true if the two generators will produce identical
165      * sequences of outputs.
166      */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_engine,x_,y_)167     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_engine, x_, y_)
168     { return x_.i == y_.i && std::equal(x_.x, x_.x+long_lag, y_.x); }
169 
170     /**
171      * Returns true if the two generators will produce different
172      * sequences of outputs.
173      */
174     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_engine)
175 
176 private:
177     /// \cond show_private
178     void fill();
179     /// \endcond
180 
181     unsigned int i;
182     UIntType x[long_lag];
183 };
184 
185 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
186 //  A definition is required even for integral static constants
187 template<class UIntType, int w, unsigned int p, unsigned int q>
188 const bool lagged_fibonacci_engine<UIntType, w, p, q>::has_fixed_range;
189 template<class UIntType, int w, unsigned int p, unsigned int q>
190 const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::long_lag;
191 template<class UIntType, int w, unsigned int p, unsigned int q>
192 const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::short_lag;
193 template<class UIntType, int w, unsigned int p, unsigned int q>
194 const UIntType lagged_fibonacci_engine<UIntType, w, p, q>::default_seed;
195 #endif
196 
197 /// \cond show_private
198 
199 template<class UIntType, int w, unsigned int p, unsigned int q>
fill()200 void lagged_fibonacci_engine<UIntType, w, p, q>::fill()
201 {
202     // two loops to avoid costly modulo operations
203     {  // extra scope for MSVC brokenness w.r.t. for scope
204     for(unsigned int j = 0; j < short_lag; ++j)
205         x[j] = (x[j] + x[j+(long_lag-short_lag)]) & low_bits_mask_t<w>::sig_bits;
206     }
207     for(unsigned int j = short_lag; j < long_lag; ++j)
208         x[j] = (x[j] + x[j-short_lag]) & low_bits_mask_t<w>::sig_bits;
209     i = 0;
210 }
211 
212 /// \endcond
213 
214 /// \cond show_deprecated
215 
216 // provided for backwards compatibility
217 template<class UIntType, int w, unsigned int p, unsigned int q, UIntType v = 0>
218 class lagged_fibonacci : public lagged_fibonacci_engine<UIntType, w, p, q>
219 {
220     typedef lagged_fibonacci_engine<UIntType, w, p, q> base_type;
221 public:
lagged_fibonacci()222     lagged_fibonacci() {}
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci,UIntType,val)223     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci, UIntType, val)
224     { this->seed(val); }
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci,SeedSeq,seq)225     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci, SeedSeq, seq)
226     { this->seed(seq); }
227     template<class It>
lagged_fibonacci(It & first,It last)228     lagged_fibonacci(It& first, It last) : base_type(first, last) {}
229 };
230 
231 /// \endcond
232 
233 // lagged Fibonacci generator for the range [0..1)
234 // contributed by Matthias Troyer
235 // for p=55, q=24 originally by G. J. Mitchell and D. P. Moore 1958
236 
237 /**
238  * Instantiations of class template @c lagged_fibonacci_01 model a
239  * \pseudo_random_number_generator. It uses a lagged Fibonacci
240  * algorithm with two lags @c p and @c q, evaluated in floating-point
241  * arithmetic: x(i) = x(i-p) + x(i-q) (mod 1) with p > q. See
242  *
243  *  @blockquote
244  *  "Uniform random number generators for supercomputers", Richard Brent,
245  *  Proc. of Fifth Australian Supercomputer Conference, Melbourne,
246  *  Dec. 1992, pp. 704-706.
247  *  @endblockquote
248  *
249  * @xmlnote
250  * The quality of the generator crucially depends on the choice
251  * of the parameters. User code should employ one of the sensibly
252  * parameterized generators such as \lagged_fibonacci607 instead.
253  * @endxmlnote
254  *
255  * The generator requires considerable amounts of memory for the storage
256  * of its state array. For example, \lagged_fibonacci607 requires about
257  * 4856 bytes and \lagged_fibonacci44497 requires about 350 KBytes.
258  */
259 template<class RealType, int w, unsigned int p, unsigned int q>
260 class lagged_fibonacci_01_engine
261 {
262 public:
263     typedef RealType result_type;
264     BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
265     BOOST_STATIC_CONSTANT(int, word_size = w);
266     BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
267     BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
268 
269     BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 331u);
270 
271     /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(). */
lagged_fibonacci_01_engine()272     lagged_fibonacci_01_engine() { seed(); }
273     /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(value). */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01_engine,uint32_t,value)274     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01_engine, uint32_t, value)
275     { seed(value); }
276     /** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(gen). */
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01_engine,SeedSeq,seq)277     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01_engine, SeedSeq, seq)
278     { seed(seq); }
lagged_fibonacci_01_engine(It & first,It last)279     template<class It> lagged_fibonacci_01_engine(It& first, It last)
280     { seed(first, last); }
281 
282     // compiler-generated copy ctor and assignment operator are fine
283 
284     /** Calls seed(default_seed). */
seed()285     void seed() { seed(default_seed); }
286 
287     /**
288      * Constructs a \minstd_rand0 generator with the constructor parameter
289      * value and calls seed with it. Distinct seeds in the range
290      * [1, 2147483647) will produce generators with different states. Other
291      * seeds will be equivalent to some seed within this range. See
292      * \linear_congruential_engine for details.
293      */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine,boost::uint32_t,value)294     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine, boost::uint32_t, value)
295     {
296         minstd_rand0 intgen(value);
297         detail::generator_seed_seq<minstd_rand0> gen(intgen);
298         seed(gen);
299     }
300 
301     /**
302      * Seeds this @c lagged_fibonacci_01_engine using values produced by
303      * @c seq.generate.
304      */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_01_engine,SeedSeq,seq)305     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_01_engine, SeedSeq, seq)
306     {
307         detail::seed_array_real<w>(seq, x);
308         i = long_lag;
309     }
310 
311     /**
312      * Seeds this @c lagged_fibonacci_01_engine using values from the
313      * iterator range [first, last).  If there are not enough elements
314      * in the range, throws @c std::invalid_argument.
315      */
316     template<class It>
seed(It & first,It last)317     void seed(It& first, It last)
318     {
319         detail::fill_array_real<w>(first, last, x);
320         i = long_lag;
321     }
322 
323     /** Returns the smallest value that the generator can produce. */
BOOST_PREVENT_MACRO_SUBSTITUTION()324     static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(0); }
325     /** Returns the upper bound of the generators outputs. */
BOOST_PREVENT_MACRO_SUBSTITUTION()326     static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); }
327 
328     /** Returns the next value of the generator. */
operator ()()329     result_type operator()()
330     {
331         if(i >= long_lag)
332             fill();
333         return x[i++];
334     }
335 
336     /** Fills a range with random values */
337     template<class Iter>
generate(Iter first,Iter last)338     void generate(Iter first, Iter last)
339     { return detail::generate_from_real(*this, first, last); }
340 
341     /** Advances the state of the generator by @c z. */
discard(boost::uintmax_t z)342     void discard(boost::uintmax_t z)
343     {
344         for(boost::uintmax_t j = 0; j < z; ++j) {
345             (*this)();
346         }
347     }
348 
349     /**
350      * Writes the textual representation of the generator to a @c std::ostream.
351      */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os,lagged_fibonacci_01_engine,f)352     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_01_engine, f)
353     {
354         // allow for Koenig lookup
355         using std::pow;
356         os << f.i;
357         std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
358         for(unsigned int j = 0; j < f.long_lag; ++j)
359             os << ' ' << f.x[j] * f.modulus();
360         os.flags(oldflags);
361         return os;
362     }
363 
364     /**
365      * Reads the textual representation of the generator from a @c std::istream.
366      */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is,lagged_fibonacci_01_engine,f)367     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_01_engine, f)
368     {
369         is >> f.i;
370         for(unsigned int j = 0; j < f.long_lag; ++j) {
371             typename lagged_fibonacci_01_engine::result_type value;
372             is >> std::ws >> value;
373             f.x[j] = value / f.modulus();
374         }
375         return is;
376     }
377 
378     /**
379      * Returns true if the two generators will produce identical
380      * sequences of outputs.
381      */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_01_engine,x_,y_)382     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_01_engine, x_, y_)
383     { return x_.i == y_.i && std::equal(x_.x, x_.x+long_lag, y_.x); }
384 
385     /**
386      * Returns true if the two generators will produce different
387      * sequences of outputs.
388      */
389     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_01_engine)
390 
391 private:
392     /// \cond show_private
393     void fill();
modulus()394     static RealType modulus()
395     {
396         using std::pow;
397         return pow(RealType(2), word_size);
398     }
399     /// \endcond
400     unsigned int i;
401     RealType x[long_lag];
402 };
403 
404 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
405 //  A definition is required even for integral static constants
406 template<class RealType, int w, unsigned int p, unsigned int q>
407 const bool lagged_fibonacci_01_engine<RealType, w, p, q>::has_fixed_range;
408 template<class RealType, int w, unsigned int p, unsigned int q>
409 const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::long_lag;
410 template<class RealType, int w, unsigned int p, unsigned int q>
411 const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::short_lag;
412 template<class RealType, int w, unsigned int p, unsigned int q>
413 const int lagged_fibonacci_01_engine<RealType,w,p,q>::word_size;
414 template<class RealType, int w, unsigned int p, unsigned int q>
415 const boost::uint32_t lagged_fibonacci_01_engine<RealType,w,p,q>::default_seed;
416 #endif
417 
418 /// \cond show_private
419 template<class RealType, int w, unsigned int p, unsigned int q>
fill()420 void lagged_fibonacci_01_engine<RealType, w, p, q>::fill()
421 {
422     // two loops to avoid costly modulo operations
423     {  // extra scope for MSVC brokenness w.r.t. for scope
424     for(unsigned int j = 0; j < short_lag; ++j) {
425         RealType t = x[j] + x[j+(long_lag-short_lag)];
426         if(t >= RealType(1))
427             t -= RealType(1);
428         x[j] = t;
429     }
430     }
431     for(unsigned int j = short_lag; j < long_lag; ++j) {
432         RealType t = x[j] + x[j-short_lag];
433         if(t >= RealType(1))
434             t -= RealType(1);
435         x[j] = t;
436     }
437     i = 0;
438 }
439 /// \endcond
440 
441 /// \cond show_deprecated
442 
443 // provided for backwards compatibility
444 template<class RealType, int w, unsigned int p, unsigned int q>
445 class lagged_fibonacci_01 : public lagged_fibonacci_01_engine<RealType, w, p, q>
446 {
447     typedef lagged_fibonacci_01_engine<RealType, w, p, q> base_type;
448 public:
lagged_fibonacci_01()449     lagged_fibonacci_01() {}
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01,boost::uint32_t,val)450     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, boost::uint32_t, val)
451     { this->seed(val); }
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01,SeedSeq,seq)452     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01, SeedSeq, seq)
453     { this->seed(seq); }
454     template<class It>
lagged_fibonacci_01(It & first,It last)455     lagged_fibonacci_01(It& first, It last) : base_type(first, last) {}
456 };
457 
458 /// \endcond
459 
460 namespace detail {
461 
462 template<class Engine>
463 struct generator_bits;
464 
465 template<class RealType, int w, unsigned int p, unsigned int q>
466 struct generator_bits<lagged_fibonacci_01_engine<RealType, w, p, q> >
467 {
valueboost::random::detail::generator_bits468     static std::size_t value() { return w; }
469 };
470 
471 template<class RealType, int w, unsigned int p, unsigned int q>
472 struct generator_bits<lagged_fibonacci_01<RealType, w, p, q> >
473 {
valueboost::random::detail::generator_bits474     static std::size_t value() { return w; }
475 };
476 
477 }
478 
479 #ifdef BOOST_RANDOM_DOXYGEN
480 namespace detail {
481 /**
482  * The specializations lagged_fibonacci607 ... lagged_fibonacci44497
483  * use well tested lags.
484  *
485  * See
486  *
487  *  @blockquote
488  *  "On the Periods of Generalized Fibonacci Recurrences", Richard P. Brent
489  *  Computer Sciences Laboratory Australian National University, December 1992
490  *  @endblockquote
491  *
492  * The lags used here can be found in
493  *
494  *  @blockquote
495  *  "Uniform random number generators for supercomputers", Richard Brent,
496  *  Proc. of Fifth Australian Supercomputer Conference, Melbourne,
497  *  Dec. 1992, pp. 704-706.
498  *  @endblockquote
499  */
500 struct lagged_fibonacci_doc {};
501 }
502 #endif
503 
504 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
505 typedef lagged_fibonacci_01_engine<double, 48, 607, 273> lagged_fibonacci607;
506 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
507 typedef lagged_fibonacci_01_engine<double, 48, 1279, 418> lagged_fibonacci1279;
508 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
509 typedef lagged_fibonacci_01_engine<double, 48, 2281, 1252> lagged_fibonacci2281;
510 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
511 typedef lagged_fibonacci_01_engine<double, 48, 3217, 576> lagged_fibonacci3217;
512 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
513 typedef lagged_fibonacci_01_engine<double, 48, 4423, 2098> lagged_fibonacci4423;
514 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
515 typedef lagged_fibonacci_01_engine<double, 48, 9689, 5502> lagged_fibonacci9689;
516 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
517 typedef lagged_fibonacci_01_engine<double, 48, 19937, 9842> lagged_fibonacci19937;
518 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
519 typedef lagged_fibonacci_01_engine<double, 48, 23209, 13470> lagged_fibonacci23209;
520 /** @copydoc boost::random::detail::lagged_fibonacci_doc */
521 typedef lagged_fibonacci_01_engine<double, 48, 44497, 21034> lagged_fibonacci44497;
522 
523 } // namespace random
524 
525 using random::lagged_fibonacci607;
526 using random::lagged_fibonacci1279;
527 using random::lagged_fibonacci2281;
528 using random::lagged_fibonacci3217;
529 using random::lagged_fibonacci4423;
530 using random::lagged_fibonacci9689;
531 using random::lagged_fibonacci19937;
532 using random::lagged_fibonacci23209;
533 using random::lagged_fibonacci44497;
534 
535 } // namespace boost
536 
537 #endif // BOOST_RANDOM_LAGGED_FIBONACCI_HPP
538