Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:13

0001 /* boost random/xor_combine.hpp header file
0002  *
0003  * Copyright Jens Maurer 2002
0004  * Distributed under the Boost Software License, Version 1.0. (See
0005  * accompanying file LICENSE_1_0.txt or copy at
0006  * http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  * See http://www.boost.org for most recent version including documentation.
0009  *
0010  * $Id$
0011  *
0012  */
0013 
0014 #ifndef BOOST_RANDOM_XOR_COMBINE_HPP
0015 #define BOOST_RANDOM_XOR_COMBINE_HPP
0016 
0017 #include <istream>
0018 #include <iosfwd>
0019 #include <cassert>
0020 #include <algorithm> // for std::min and std::max
0021 #include <boost/config.hpp>
0022 #include <boost/limits.hpp>
0023 #include <boost/cstdint.hpp>     // uint32_t
0024 #include <boost/random/detail/config.hpp>
0025 #include <boost/random/detail/seed.hpp>
0026 #include <boost/random/detail/seed_impl.hpp>
0027 #include <boost/random/detail/operators.hpp>
0028 
0029 namespace boost {
0030 namespace random {
0031 
0032 /**
0033  * Instantiations of @c xor_combine_engine model a
0034  * \pseudo_random_number_generator.  To produce its output it
0035  * invokes each of the base generators, shifts their results
0036  * and xors them together.
0037  */
0038 template<class URNG1, int s1, class URNG2, int s2>
0039 class xor_combine_engine
0040 {
0041 public:
0042     typedef URNG1 base1_type;
0043     typedef URNG2 base2_type;
0044     typedef typename base1_type::result_type result_type;
0045 
0046     BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
0047     BOOST_STATIC_CONSTANT(int, shift1 = s1);
0048     BOOST_STATIC_CONSTANT(int, shift2 = s2);
0049 
0050     /**
0051      * Constructors a @c xor_combine_engine by default constructing
0052      * both base generators.
0053      */
0054     xor_combine_engine() : _rng1(), _rng2() { }
0055 
0056     /** Constructs a @c xor_combine by copying two base generators. */
0057     xor_combine_engine(const base1_type & rng1, const base2_type & rng2)
0058       : _rng1(rng1), _rng2(rng2) { }
0059 
0060     /**
0061      * Constructs a @c xor_combine_engine, seeding both base generators
0062      * with @c v.
0063      *
0064      * @xmlwarning
0065      * The exact algorithm used by this function may change in the future.
0066      * @endxmlwarning
0067      */
0068     BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine,
0069         result_type, v)
0070     { seed(v); }
0071 
0072     /**
0073      * Constructs a @c xor_combine_engine, seeding both base generators
0074      * with values produced by @c seq.
0075      */
0076     BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine,
0077         SeedSeq, seq)
0078     { seed(seq); }
0079 
0080     /**
0081      * Constructs a @c xor_combine_engine, seeding both base generators
0082      * with values from the iterator range [first, last) and changes
0083      * first to point to the element after the last one used.  If there
0084      * are not enough elements in the range to seed both generators,
0085      * throws @c std::invalid_argument.
0086      */
0087     template<class It> xor_combine_engine(It& first, It last)
0088       : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
0089 
0090     /** Calls @c seed() for both base generators. */
0091     void seed() { _rng1.seed(); _rng2.seed(); }
0092 
0093     /** @c seeds both base generators with @c v. */
0094     BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v)
0095     { _rng1.seed(v); _rng2.seed(v); }
0096 
0097     /** @c seeds both base generators with values produced by @c seq. */
0098     BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq)
0099     { _rng1.seed(seq); _rng2.seed(seq); }
0100 
0101     /**
0102      * seeds both base generators with values from the iterator
0103      * range [first, last) and changes first to point to the element
0104      * after the last one used.  If there are not enough elements in
0105      * the range to seed both generators, throws @c std::invalid_argument.
0106      */
0107     template<class It> void seed(It& first, It last)
0108     {
0109         _rng1.seed(first, last);
0110         _rng2.seed(first, last);
0111     }
0112 
0113     /** Returns the first base generator. */
0114     const base1_type& base1() const { return _rng1; }
0115 
0116     /** Returns the second base generator. */
0117     const base2_type& base2() const { return _rng2; }
0118 
0119     /** Returns the next value of the generator. */
0120     result_type operator()()
0121     {
0122         return (_rng1() << s1) ^ (_rng2() << s2);
0123     }
0124   
0125     /** Fills a range with random values */
0126     template<class Iter>
0127     void generate(Iter first, Iter last)
0128     { detail::generate_from_int(*this, first, last); }
0129 
0130     /** Advances the state of the generator by @c z. */
0131     void discard(boost::uintmax_t z)
0132     {
0133         _rng1.discard(z);
0134         _rng2.discard(z);
0135     }
0136 
0137     /** Returns the smallest value that the generator can produce. */
0138     static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
0139     { return (URNG1::min)()<(URNG2::min)()?(URNG1::min)():(URNG2::min)(); }
0140     /** Returns the largest value that the generator can produce. */
0141     static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
0142     { return (URNG1::max)()>(URNG2::max)()?(URNG1::max)():(URNG2::max)(); }
0143 
0144     /**
0145      * Writes the textual representation of the generator to a @c std::ostream.
0146      */
0147     BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s)
0148     {
0149         os << s._rng1 << ' ' << s._rng2;
0150         return os;
0151     }
0152     
0153     /**
0154      * Reads the textual representation of the generator from a @c std::istream.
0155      */
0156     BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s)
0157     {
0158         is >> s._rng1 >> std::ws >> s._rng2;
0159         return is;
0160     }
0161     
0162     /** Returns true if the two generators will produce identical sequences. */
0163     BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y)
0164     { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
0165     
0166     /** Returns true if the two generators will produce different sequences. */
0167     BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine)
0168 
0169 private:
0170     base1_type _rng1;
0171     base2_type _rng2;
0172 };
0173 
0174 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
0175 //  A definition is required even for integral static constants
0176 template<class URNG1, int s1, class URNG2, int s2>
0177 const bool xor_combine_engine<URNG1, s1, URNG2, s2>::has_fixed_range;
0178 template<class URNG1, int s1, class URNG2, int s2>
0179 const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift1;
0180 template<class URNG1, int s1, class URNG2, int s2>
0181 const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift2;
0182 #endif
0183 
0184 /// \cond show_private
0185 
0186 /** Provided for backwards compatibility. */
0187 template<class URNG1, int s1, class URNG2, int s2,
0188     typename URNG1::result_type v = 0>
0189 class xor_combine : public xor_combine_engine<URNG1, s1, URNG2, s2>
0190 {
0191     typedef xor_combine_engine<URNG1, s1, URNG2, s2> base_type;
0192 public:
0193     typedef typename base_type::result_type result_type;
0194     xor_combine() {}
0195     xor_combine(result_type val) : base_type(val) {}
0196     template<class It>
0197     xor_combine(It& first, It last) : base_type(first, last) {}
0198     xor_combine(const URNG1 & rng1, const URNG2 & rng2)
0199       : base_type(rng1, rng2) { }
0200 
0201     result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); }
0202     result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); }
0203 };
0204 
0205 /// \endcond
0206 
0207 } // namespace random
0208 } // namespace boost
0209 
0210 #endif // BOOST_RANDOM_XOR_COMBINE_HPP