X-Git-Url: https://git.donarmstrong.com/?p=rsem.git;a=blobdiff_plain;f=boost%2Frandom%2Fadditive_combine.hpp;h=b4cb63cd57c9577546edcb009627242c9c839f17;hp=90eff93fe553023510542e2ba197c7bb5ec4155a;hb=2d71eb92104693ca9baa5a2e1c23eeca776d8fd3;hpb=da57529b92adbb7ae74a89861cb39fb35ac7c62d diff --git a/boost/random/additive_combine.hpp b/boost/random/additive_combine.hpp index 90eff93..b4cb63c 100644 --- a/boost/random/additive_combine.hpp +++ b/boost/random/additive_combine.hpp @@ -7,7 +7,7 @@ * * See http://www.boost.org for most recent version including documentation. * - * $Id: additive_combine.hpp 60755 2010-03-22 00:45:06Z steven_watanabe $ + * $Id: additive_combine.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ * * Revision history * 2001-02-18 moved to individual header files @@ -16,20 +16,23 @@ #ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP #define BOOST_RANDOM_ADDITIVE_COMBINE_HPP -#include +#include +#include #include // for std::min and std::max #include #include #include +#include +#include #include namespace boost { namespace random { /** - * An instantiation of class template \additive_combine model a + * An instantiation of class template @c additive_combine_engine models a * \pseudo_random_number_generator. It combines two multiplicative - * \linear_congruential number generators, i.e. those with @c c = 0. + * \linear_congruential_engine number generators, i.e. those with @c c = 0. * It is described in * * @blockquote @@ -38,183 +41,225 @@ namespace random { * @endblockquote * * The template parameters MLCG1 and MLCG2 shall denote two different - * \linear_congruential number generators, each with c = 0. Each invocation - * returns a random number X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1), where - * m1 denotes the modulus of MLCG1. - * - * The template parameter @c val is the validation value checked by validation. + * \linear_congruential_engine number generators, each with c = 0. Each + * invocation returns a random number + * X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1), + * where m1 denotes the modulus of MLCG1. */ -template -class additive_combine +template +class additive_combine_engine { public: - typedef MLCG1 first_base; - typedef MLCG2 second_base; - typedef typename MLCG1::result_type result_type; + typedef MLCG1 first_base; + typedef MLCG2 second_base; + typedef typename MLCG1::result_type result_type; + + // Required by old Boost.Random concept + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + /** + * Returns the smallest value that the generator can produce + */ + static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () + { return 1; } + /** + * Returns the largest value that the generator can produce + */ + static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () + { return MLCG1::modulus-1; } + + /** + * Constructs an @c additive_combine_engine using the + * default constructors of the two base generators. + */ + additive_combine_engine() : _mlcg1(), _mlcg2() { } + /** + * Constructs an @c additive_combine_engine, using seed as + * the constructor argument for both base generators. + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(additive_combine_engine, + result_type, seed_arg) + { + _mlcg1.seed(seed_arg); + _mlcg2.seed(seed_arg); + } + /** + * Constructs an @c additive_combine_engine, using seq as + * the constructor argument for both base generators. + * + * @xmlwarning + * The semantics of this function are liable to change. + * A @c seed_seq is designed to generate all the seeds + * in one shot, but this seeds the two base engines + * independantly and probably ends up giving the same + * sequence to both. + * @endxmlwarning + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(additive_combine_engine, + SeedSeq, seq) + { + _mlcg1.seed(seq); + _mlcg2.seed(seq); + } + /** + * Constructs an @c additive_combine_engine, using + * @c seed1 and @c seed2 as the constructor argument to + * the first and second base generators, respectively. + */ + additive_combine_engine(typename MLCG1::result_type seed1, + typename MLCG2::result_type seed2) + : _mlcg1(seed1), _mlcg2(seed2) { } + /** + * Contructs an @c additive_combine_engine with + * values from the range defined by the input iterators first + * and last. first will be modified to point to the element + * after the last one used. + * + * Throws: @c std::invalid_argument if the input range is too small. + * + * Exception Safety: Basic + */ + template additive_combine_engine(It& first, It last) + : _mlcg1(first, last), _mlcg2(first, last) { } + + /** + * Seeds an @c additive_combine_engine using the default + * seeds of the two base generators. + */ + void seed() + { + _mlcg1.seed(); + _mlcg2.seed(); + } + + /** + * Seeds an @c additive_combine_engine, using @c seed as the + * seed for both base generators. + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(additive_combine_engine, + result_type, seed_arg) + { + _mlcg1.seed(seed_arg); + _mlcg2.seed(seed_arg); + } + + /** + * Seeds an @c additive_combine_engine, using @c seq to + * seed both base generators. + * + * See the warning on the corresponding constructor. + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(additive_combine_engine, + SeedSeq, seq) + { + _mlcg1.seed(seq); + _mlcg2.seed(seq); + } + + /** + * Seeds an @c additive_combine generator, using @c seed1 and @c seed2 as + * the seeds to the first and second base generators, respectively. + */ + void seed(typename MLCG1::result_type seed1, + typename MLCG2::result_type seed2) + { + _mlcg1.seed(seed1); + _mlcg2.seed(seed2); + } + + /** + * Seeds an @c additive_combine_engine with + * values from the range defined by the input iterators first + * and last. first will be modified to point to the element + * after the last one used. + * + * Throws: @c std::invalid_argument if the input range is too small. + * + * Exception Safety: Basic + */ + template void seed(It& first, It last) + { + _mlcg1.seed(first, last); + _mlcg2.seed(first, last); + } + + /** Returns the next value of the generator. */ + result_type operator()() { + result_type val1 = _mlcg1(); + result_type val2 = _mlcg2(); + if(val2 < val1) return val1 - val2; + else return val1 - val2 + MLCG1::modulus - 1; + } + + /** Fills a range with random values */ + template + void generate(Iter first, Iter last) + { detail::generate_from_int(*this, first, last); } + + /** Advances the state of the generator by @c z. */ + void discard(boost::uintmax_t z) + { + _mlcg1.discard(z); + _mlcg2.discard(z); + } + + /** + * Writes the state of an @c additive_combine_engine to a @c + * std::ostream. The textual representation of an @c + * additive_combine_engine is the textual representation of + * the first base generator followed by the textual representation + * of the second base generator. + */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, additive_combine_engine, r) + { os << r._mlcg1 << ' ' << r._mlcg2; return os; } + + /** + * Reads the state of an @c additive_combine_engine from a + * @c std::istream. + */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, additive_combine_engine, r) + { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; } + + /** + * Returns: true iff the two @c additive_combine_engines will + * produce the same sequence of values. + */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(additive_combine_engine, x, y) + { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; } + /** + * Returns: true iff the two @c additive_combine_engines will + * produce different sequences of values. + */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(additive_combine_engine) + +private: + MLCG1 _mlcg1; + MLCG2 _mlcg2; +}; + #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION - static const bool has_fixed_range = true; - static const result_type min_value = 1; - static const result_type max_value = MLCG1::max_value-1; -#else - enum { has_fixed_range = false }; -#endif - /** - * Returns: The smallest value that the generator can produce - */ - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; } - /** - * Returns: The largest value that the generator can produce - */ - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_mlcg1.max)()-1; } - - /** - * Constructs an \additive_combine generator using the - * default constructors of the two base generators. - */ - additive_combine() : _mlcg1(), _mlcg2() { } - /** - * Constructs an \additive_combine generator, using aseed as - * the constructor argument for both base generators. - */ - explicit additive_combine(result_type aseed) - : _mlcg1(aseed), _mlcg2(aseed) { } - /** - * Constructs an \additive_combine generator, using - * @c seed1 and @c seed2 as the constructor argument to - * the first and second base generators, respectively. - */ - additive_combine(typename MLCG1::result_type seed1, - typename MLCG2::result_type seed2) - : _mlcg1(seed1), _mlcg2(seed2) { } - /** - * Contructs an \additive_combine generator with - * values from the range defined by the input iterators first - * and last. first will be modified to point to the element - * after the last one used. - * - * Throws: @c std::invalid_argument if the input range is too small. - * - * Exception Safety: Basic - */ - template additive_combine(It& first, It last) - : _mlcg1(first, last), _mlcg2(first, last) { } - - /** - * Seeds an \additive_combine generator using the default - * seeds of the two base generators. - */ - void seed() - { - _mlcg1.seed(); - _mlcg2.seed(); - } - - /** - * Seeds an \additive_combine generator, using @c aseed as the - * seed for both base generators. - */ - void seed(result_type aseed) - { - _mlcg1.seed(aseed); - _mlcg2.seed(aseed); - } - - /** - * Seeds an \additive_combine generator, using @c seed1 and @c seed2 as - * the seeds to the first and second base generators, respectively. - */ - void seed(typename MLCG1::result_type seed1, - typename MLCG2::result_type seed2) - { - _mlcg1.seed(seed1); - _mlcg2.seed(seed2); - } - - /** - * Seeds an \additive_combine generator with - * values from the range defined by the input iterators first - * and last. first will be modified to point to the element - * after the last one used. - * - * Throws: @c std::invalid_argument if the input range is too small. - * - * Exception Safety: Basic - */ - template void seed(It& first, It last) - { - _mlcg1.seed(first, last); - _mlcg2.seed(first, last); - } - - /** - * Returns: the next value of the generator - */ - result_type operator()() { - result_type z = _mlcg1() - _mlcg2(); - if(z < 1) - z += MLCG1::modulus-1; - return z; - } - - static bool validation(result_type x) { return val == x; } - -#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE - -#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS - /** - * Writes the state of an \additive_combine generator to a @c - * std::ostream. The textual representation of an \additive_combine - * generator is the textual representation of the first base - * generator followed by the textual representation of the - * second base generator. - */ - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const additive_combine& r) - { os << r._mlcg1 << " " << r._mlcg2; return os; } - - /** - * Reads the state of an \additive_combine generator from a - * @c std::istream. - */ - template - friend std::basic_istream& - operator>>(std::basic_istream& is, additive_combine& r) - { is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; } +template +const bool additive_combine_engine::has_fixed_range; #endif - /** - * Returns: true iff the two \additive_combine generators will - * produce the same sequence of values. - */ - friend bool operator==(const additive_combine& x, const additive_combine& y) - { return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; } - /** - * Returns: true iff the two \additive_combine generators will - * produce different sequences of values. - */ - friend bool operator!=(const additive_combine& x, const additive_combine& y) - { return !(x == y); } -#else - // Use a member function; Streamable concept not supported. - bool operator==(const additive_combine& rhs) const - { return _mlcg1 == rhs._mlcg1 && _mlcg2 == rhs._mlcg2; } - bool operator!=(const additive_combine& rhs) const - { return !(*this == rhs); } -#endif +/// \cond show_deprecated -private: - MLCG1 _mlcg1; - MLCG2 _mlcg2; +/** Provided for backwards compatibility. */ +template +class additive_combine : public additive_combine_engine +{ + typedef additive_combine_engine base_t; +public: + typedef typename base_t::result_type result_type; + additive_combine() {} + template + additive_combine(T& arg) : base_t(arg) {} + template + additive_combine(const T& arg) : base_t(arg) {} + template + additive_combine(It& first, It last) : base_t(first, last) {} }; -} // namespace random +/// \endcond /** * The specialization \ecuyer1988 was suggested in @@ -224,10 +269,14 @@ private: * Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774 * @endblockquote */ -typedef random::additive_combine< - random::linear_congruential, - random::linear_congruential, - 2060321752> ecuyer1988; +typedef additive_combine_engine< + linear_congruential_engine, + linear_congruential_engine +> ecuyer1988; + +} // namespace random + +using random::ecuyer1988; } // namespace boost