Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/random/xor_combine.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/random/xor_combine.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,207 @@ +/* boost random/xor_combine.hpp header file + * + * Copyright Jens Maurer 2002 + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org for most recent version including documentation. + * + * $Id: xor_combine.hpp 71018 2011-04-05 21:27:52Z steven_watanabe $ + * + */ + +#ifndef BOOST_RANDOM_XOR_COMBINE_HPP +#define BOOST_RANDOM_XOR_COMBINE_HPP + +#include <istream> +#include <iosfwd> +#include <cassert> +#include <algorithm> // for std::min and std::max +#include <boost/config.hpp> +#include <boost/limits.hpp> +#include <boost/cstdint.hpp> // uint32_t +#include <boost/random/detail/config.hpp> +#include <boost/random/detail/seed.hpp> +#include <boost/random/detail/seed_impl.hpp> + +namespace boost { +namespace random { + +/** + * Instantiations of @c xor_combine_engine model a + * \pseudo_random_number_generator. To produce its output it + * invokes each of the base generators, shifts their results + * and xors them together. + */ +template<class URNG1, int s1, class URNG2, int s2> +class xor_combine_engine +{ +public: + typedef URNG1 base1_type; + typedef URNG2 base2_type; + typedef typename base1_type::result_type result_type; + + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + BOOST_STATIC_CONSTANT(int, shift1 = s1); + BOOST_STATIC_CONSTANT(int, shift2 = s2); + + /** + * Constructors a @c xor_combine_engine by default constructing + * both base generators. + */ + xor_combine_engine() : _rng1(), _rng2() { } + + /** Constructs a @c xor_combine by copying two base generators. */ + xor_combine_engine(const base1_type & rng1, const base2_type & rng2) + : _rng1(rng1), _rng2(rng2) { } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with @c v. + * + * @xmlwarning + * The exact algorithm used by this function may change in the future. + * @endxmlwarning + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine, + result_type, v) + { seed(v); } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with values produced by @c seq. + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine, + SeedSeq, seq) + { seed(seq); } + + /** + * Constructs a @c xor_combine_engine, seeding both base generators + * with values from the iterator range [first, last) and changes + * first to point to the element after the last one used. If there + * are not enough elements in the range to seed both generators, + * throws @c std::invalid_argument. + */ + template<class It> xor_combine_engine(It& first, It last) + : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { } + + /** Calls @c seed() for both base generators. */ + void seed() { _rng1.seed(); _rng2.seed(); } + + /** @c seeds both base generators with @c v. */ + BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v) + { _rng1.seed(v); _rng2.seed(v); } + + /** @c seeds both base generators with values produced by @c seq. */ + BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq) + { _rng1.seed(seq); _rng2.seed(seq); } + + /** + * seeds both base generators with values from the iterator + * range [first, last) and changes first to point to the element + * after the last one used. If there are not enough elements in + * the range to seed both generators, throws @c std::invalid_argument. + */ + template<class It> void seed(It& first, It last) + { + _rng1.seed(first, last); + _rng2.seed(first, last); + } + + /** Returns the first base generator. */ + const base1_type& base1() const { return _rng1; } + + /** Returns the second base generator. */ + const base2_type& base2() const { return _rng2; } + + /** Returns the next value of the generator. */ + result_type operator()() + { + return (_rng1() << s1) ^ (_rng2() << s2); + } + + /** Fills a range with random values */ + template<class Iter> + 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) + { + _rng1.discard(z); + _rng2.discard(z); + } + + /** Returns the smallest value that the generator can produce. */ + static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::min)((URNG1::min)(), (URNG2::min)()); } + /** Returns the largest value that the generator can produce. */ + static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::max)((URNG1::min)(), (URNG2::max)()); } + + /** + * Writes the textual representation of the generator to a @c std::ostream. + */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s) + { + os << s._rng1 << ' ' << s._rng2; + return os; + } + + /** + * Reads the textual representation of the generator from a @c std::istream. + */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s) + { + is >> s._rng1 >> std::ws >> s._rng2; + return is; + } + + /** Returns true if the two generators will produce identical sequences. */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y) + { return x._rng1 == y._rng1 && x._rng2 == y._rng2; } + + /** Returns true if the two generators will produce different sequences. */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine) + +private: + base1_type _rng1; + base2_type _rng2; +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template<class URNG1, int s1, class URNG2, int s2> +const bool xor_combine_engine<URNG1, s1, URNG2, s2>::has_fixed_range; +template<class URNG1, int s1, class URNG2, int s2> +const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift1; +template<class URNG1, int s1, class URNG2, int s2> +const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift2; +#endif + +/// \cond show_private + +/** Provided for backwards compatibility. */ +template<class URNG1, int s1, class URNG2, int s2, + typename URNG1::result_type v = 0> +class xor_combine : public xor_combine_engine<URNG1, s1, URNG2, s2> +{ + typedef xor_combine_engine<URNG1, s1, URNG2, s2> base_type; +public: + typedef typename base_type::result_type result_type; + xor_combine() {} + xor_combine(result_type val) : base_type(val) {} + template<class It> + xor_combine(It& first, It last) : base_type(first, last) {} + xor_combine(const URNG1 & rng1, const URNG2 & rng2) + : base_type(rng1, rng2) { } + + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); } +}; + +/// \endcond + +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_XOR_COMBINE_HPP