Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68767 - in trunk: boost boost/random libs/random/test
From: steven_at_[hidden]
Date: 2011-02-10 20:16:38


Author: steven_watanabe
Date: 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
New Revision: 68767
URL: http://svn.boost.org/trac/boost/changeset/68767

Log:
Update xor_combine to match C++0x. min/max are still broken.
Added:
   trunk/boost/random/taus88.hpp (contents, props changed)
   trunk/libs/random/test/test_taus88.cpp (contents, props changed)
Text files modified:
   trunk/boost/random.hpp | 16 -
   trunk/boost/random/xor_combine.hpp | 303 +++++++++++++++++++++------------------
   trunk/libs/random/test/Jamfile.v2 | 2
   3 files changed, 164 insertions(+), 157 deletions(-)

Modified: trunk/boost/random.hpp
==============================================================================
--- trunk/boost/random.hpp (original)
+++ trunk/boost/random.hpp 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
@@ -45,21 +45,7 @@
 #include <boost/random/discard_block.hpp>
 #include <boost/random/subtract_with_carry.hpp>
 #include <boost/random/variate_generator.hpp>
-
-namespace boost {
- /**
- * The specialization taus88 was suggested in
- *
- * @blockquote
- * "Maximally Equidistributed Combined Tausworthe Generators",
- * Pierre L'Ecuyer, Mathematics of Computation, Volume 65,
- * Number 213, January 1996, Pages 203-213
- * @endblockquote
- */
- typedef random::xor_combine<random::xor_combine<random::linear_feedback_shift<uint32_t, 32, 31, 13, 12, 0>, 0,
- random::linear_feedback_shift<uint32_t, 32, 29, 2, 4, 0>, 0, 0>, 0,
- random::linear_feedback_shift<uint32_t, 32, 28, 3, 17, 0>, 0, 0> taus88;
-} // namespace boost
+#include <boost/random/taus88.hpp>
 
 // misc
 #include <boost/random/random_number_generator.hpp>

Added: trunk/boost/random/taus88.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/random/taus88.hpp 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
@@ -0,0 +1,45 @@
+/* boost random/taus88.hpp header file
+ *
+ * Copyright Jens Maurer 2000-2001
+ * Copyright Steven Watanabe 2011
+ * 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/libs/random for documentation.
+ *
+ * $Id$
+ *
+ */
+
+#ifndef BOOST_RANDOM_TAUS88_HPP
+#define BOOST_RANDOM_TAUS88_HPP
+
+#include <boost/random/linear_feedback_shift.hpp>
+#include <boost/random/xor_combine.hpp>
+
+namespace boost {
+namespace random {
+
+/**
+ * The specialization taus88 was suggested in
+ *
+ * @blockquote
+ * "Maximally Equidistributed Combined Tausworthe Generators",
+ * Pierre L'Ecuyer, Mathematics of Computation, Volume 65,
+ * Number 213, January 1996, Pages 203-213
+ * @endblockquote
+ */
+typedef xor_combine_engine<
+ xor_combine_engine<
+ linear_feedback_shift_engine<uint32_t, 32, 31, 13, 12>, 0,
+ linear_feedback_shift_engine<uint32_t, 32, 29, 2, 4>, 0>, 0,
+ linear_feedback_shift_engine<uint32_t, 32, 28, 3, 17>, 0> taus88;
+
+} // namespace random
+
+using random::taus88;
+
+} // namespace boost
+
+#endif // BOOST_RANDOM_TAUS88_HPP

Modified: trunk/boost/random/xor_combine.hpp
==============================================================================
--- trunk/boost/random/xor_combine.hpp (original)
+++ trunk/boost/random/xor_combine.hpp 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
@@ -14,169 +14,190 @@
 #ifndef BOOST_RANDOM_XOR_COMBINE_HPP
 #define BOOST_RANDOM_XOR_COMBINE_HPP
 
-#include <iostream>
+#include <istream>
+#include <iosfwd>
 #include <cassert>
 #include <algorithm> // for std::min and std::max
 #include <boost/config.hpp>
 #include <boost/limits.hpp>
-#include <boost/static_assert.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 {
 
-/// \cond hide_private_members
-#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
- #define BOOST_RANDOM_VAL_TYPE typename URNG1::result_type
-#else
- #define BOOST_RANDOM_VAL_TYPE uint32_t
-#endif
-/// \endcond
-
 /**
- * Instantiations of @c xor_combine model a \pseudo_random_number_generator.
- * To produce its output it invokes each of the base generators, shifts
- * their results and xors them together.
+ * 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
-#ifndef BOOST_RANDOM_DOXYGEN
-, BOOST_RANDOM_VAL_TYPE val = 0
-#endif
->
-class xor_combine
+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 by default constructing
- * both base generators.
- */
- xor_combine() : _rng1(), _rng2()
- { }
- /**
- * Constructs a @c xor_combine by copying two base generators.
- */
- xor_combine(const base1_type & rng1, const base2_type & rng2)
- : _rng1(rng1), _rng2(rng2) { }
- /**
- * Constructs a @c xor_combine, seeding both base generators
- * with @c v.
- */
- xor_combine(const result_type & v)
- : _rng1(v), _rng2(v) { }
- /**
- * Constructs a @c xor_combine, 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(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.
- */
- void seed(const result_type & v) { _rng1.seed(v); _rng2.seed(v); }
- /**
- * 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() { return _rng1; }
- /** Returns the second base generator. */
- const base2_type& base2() { return _rng2; }
-
- /** Returns the next value of the generator. */
- result_type operator()()
- {
- // MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
-#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base2_type::result_type>::is_integer);
- BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::digits >= std::numeric_limits<typename base2_type::result_type>::digits);
-#endif
- return (_rng1() << s1) ^ (_rng2() << s2);
- }
-
- /**
- * Returns the smallest value that the generator can produce.
- */
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::min BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.min)()); }
- /**
- * Returns the largest value that the generator can produce.
- */
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::max BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.max)()); }
- static bool validation(result_type x) { return val == x; }
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- template<class CharT, class Traits>
- friend std::basic_ostream<CharT,Traits>&
- operator<<(std::basic_ostream<CharT,Traits>& os, const xor_combine& s)
- {
- os << s._rng1 << " " << s._rng2 << " ";
- return os;
- }
-
- template<class CharT, class Traits>
- friend std::basic_istream<CharT,Traits>&
- operator>>(std::basic_istream<CharT,Traits>& is, xor_combine& s)
- {
- is >> s._rng1 >> std::ws >> s._rng2 >> std::ws;
- return is;
- }
-#endif
-
- friend bool operator==(const xor_combine& x, const xor_combine& y)
- { return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
- friend bool operator!=(const xor_combine& x, const xor_combine& y)
- { return !(x == y); }
-#else
- // Use a member function; Streamable concept not supported.
- bool operator==(const xor_combine& rhs) const
- { return _rng1 == rhs._rng1 && _rng2 == rhs._rng2; }
- bool operator!=(const xor_combine& rhs) const
- { return !(*this == rhs); }
-#endif
+ 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.
+ */
+ 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); }
+
+#ifndef BOOST_NO_LONG_LONG
+ /** Advances the state of the generator by @c z. */
+ void discard(boost::ulong_long_type z)
+ {
+ _rng1.discard(z);
+ _rng2.discard(z);
+ }
+#endif
+
+ /** 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;
+ 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, BOOST_RANDOM_VAL_TYPE val>
-const bool xor_combine<URNG1, s1, URNG2, s2, val>::has_fixed_range;
-template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
-const int xor_combine<URNG1, s1, URNG2, s2, val>::shift1;
-template<class URNG1, int s1, class URNG2, int s2, BOOST_RANDOM_VAL_TYPE val>
-const int xor_combine<URNG1, s1, URNG2, s2, val>::shift2;
+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
 
-#undef BOOST_RANDOM_VAL_TYPE
+/// \cond
+
+/** 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)
+ : _rng1(rng1), _rng2(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

Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2 (original)
+++ trunk/libs/random/test/Jamfile.v2 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
@@ -32,7 +32,6 @@
     ranlux64_4_01
     ranlux24
     ranlux48
- taus88
 ;
 
 for urng in $(all-urngs)
@@ -46,6 +45,7 @@
 run test_lagged_fibonacci.cpp /boost//unit_test_framework ;
 run test_lagged_fibonacci607.cpp /boost//unit_test_framework ;
 run test_linear_feedback_shift.cpp /boost//unit_test_framework ;
+run test_taus88.cpp /boost//unit_test_framework ;
 
 run test_seed_seq.cpp /boost//unit_test_framework ;
 

Added: trunk/libs/random/test/test_taus88.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_taus88.cpp 2011-02-10 20:16:34 EST (Thu, 10 Feb 2011)
@@ -0,0 +1,17 @@
+/* test_taus88.cpp
+ *
+ * Copyright Steven Watanabe 2011
+ * 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)
+ *
+ * $Id$
+ *
+ */
+
+#include <boost/random/taus88.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::taus88
+#define BOOST_RANDOM_VALIDATION_VALUE 3535848941U
+
+#include "test_generator.ipp"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk