$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r67761 - trunk/libs/random/test
From: steven_at_[hidden]
Date: 2011-01-07 13:49:09
Author: steven_watanabe
Date: 2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
New Revision: 67761
URL: http://svn.boost.org/trac/boost/changeset/67761
Log:
Start refactoring tests again.
Added:
   trunk/libs/random/test/concepts.hpp   (contents, props changed)
   trunk/libs/random/test/test_generator.ipp   (contents, props changed)
   trunk/libs/random/test/test_mt19937.cpp   (contents, props changed)
Text files modified: 
   trunk/libs/random/test/Jamfile.v2   |     5                                         
   trunk/libs/random/test/validate.cpp |   150 +++++++++++---------------------------- 
   2 files changed, 45 insertions(+), 110 deletions(-)
Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2	(original)
+++ trunk/libs/random/test/Jamfile.v2	2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
@@ -24,7 +24,6 @@
     kreutzer1986
     hellekalek1995
     mt11213b
-    mt19937
     mt19937_64
     lagged_fibonacci
     lagged_fibonacci607
@@ -44,6 +43,8 @@
     run instantiate.cpp : : : <define>BOOST_RANDOM_URNG_TEST=$(urng) : test_$(urng) ;
 }
 
+run test_mt19937.cpp /boost//unit_test_framework ;
+
 run test_seed_seq.cpp /boost//unit_test_framework ;
 
 run test_binomial.cpp ;
@@ -77,7 +78,7 @@
 # run statistic_tests.cpp ;
 
 exe statistic_tests.exe : statistic_tests.cpp ;
-explicit statistics_tests ;
+explicit statistics_tests.exe ;
 
 install statistic_tests : statistic_tests.exe : <install-type>EXE <location>. ;
 explicit statistic_tests ;
Added: trunk/libs/random/test/concepts.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/concepts.hpp	2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
@@ -0,0 +1,134 @@
+/* concepts.hpp
+ *
+ * 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/concept_check.hpp>
+#include <boost/concept_archetype.hpp>
+# include <boost/concept/requires.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/static_assert.hpp>
+#include <istream>
+#include <ostream>
+
+#ifndef BOOST_RANDOM_TEST_CONCEPTS_HPP
+#define BOOST_RANDOM_TEST_CONCEPTS_HPP
+
+namespace boost {
+namespace random {
+namespace test {
+
+template<class Base = null_archetype<> >
+struct seed_seq_archetype : Base
+{
+    template<class Iter>
+    BOOST_CONCEPT_REQUIRES(
+        ((Mutable_RandomAccessIterator<Iter>))
+        ((UnsignedInteger<typename Mutable_RandomAccessIterator<Iter>::value_type>)),
+    (void))
+    generate(Iter, Iter);
+};
+
+template<class SSeq>
+struct SeedSeq
+{
+public:
+    BOOST_CONCEPT_USAGE(SeedSeq)
+    {
+        q.generate(rb, re);
+    }
+private:
+    SSeq q;
+    mutable_random_access_iterator_archetype<boost::uint32_t> rb, re;
+};
+
+template<class T>
+struct Streamable
+{
+public:
+    BOOST_CONCEPT_USAGE(Streamable)
+    {
+        os << x;
+        is >> v;
+        wos << x;
+        wis >> v;
+    }
+private:
+    const T x;
+    T v;
+
+    std::istream is;
+    std::ostream os;
+    std::wistream wis;
+    std::wostream wos;
+};
+
+template <class E>
+struct RandomNumberEngine :
+    DefaultConstructible<E>,
+    CopyConstructible<E>,
+    Assignable<E>,
+    EqualityComparable<E>,
+    Streamable<E>
+{
+ public:
+    typedef typename E::result_type result_type;
+
+    // relaxed from the standard
+    BOOST_MPL_ASSERT((boost::is_arithmetic<result_type>));
+
+    // backwards compatibility check
+    BOOST_STATIC_ASSERT(!E::has_fixed_range);
+
+    // a generator can be used to seed another generator (extension)
+    BOOST_CONCEPT_ASSERT((SeedSeq<E>));
+
+    BOOST_CONCEPT_USAGE(RandomNumberEngine)
+    {
+        same_type(e(), result_type());
+        same_type(E::min(), result_type());
+        same_type(E::max(), result_type());
+
+        E();
+        E(s);
+        E(q);
+
+        e.seed();
+        e.seed(s);
+        e.seed(q);
+
+        e.discard(z);
+
+        // extension
+        E(sb, se);
+        e.seed(sb, se);
+    }
+    
+ private:
+    E e;
+    E v;
+    const E x;
+    seed_seq_archetype<> q;
+    result_type s;
+    unsigned long long z;
+    
+    input_iterator_archetype<boost::uint32_t> sb, se;
+
+    // Type deduction will fail unless the arguments have the same type.
+    template <typename T>
+    void same_type(T const&, T const&);
+};
+
+}
+}
+}
+
+#endif
Added: trunk/libs/random/test/test_generator.ipp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_generator.ipp	2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
@@ -0,0 +1,194 @@
+/* test_generator.ipp
+ *
+ * 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 "concepts.hpp"
+#include <boost/random/seed_seq.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using boost::random::test::RandomNumberEngine;
+BOOST_CONCEPT_ASSERT((RandomNumberEngine< BOOST_RANDOM_URNG >));
+
+typedef BOOST_RANDOM_URNG::result_type result_type;
+
+template<class Converted, class URNG, class T>
+void test_seed_conversion(URNG & urng, const T & t)
+{
+    Converted c = static_cast<Converted>(t);
+    if(static_cast<T>(c) == t) {
+        URNG urng2(c);
+        std::ostringstream msg;
+        msg << "Testing seed: type " << typeid(Converted).name() << ", value " << c;
+        BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
+        urng2.seed(c);
+        BOOST_CHECK_MESSAGE(urng == urng2, msg.str());
+    }
+}
+
+void test_seed(result_type value)
+{
+    BOOST_RANDOM_URNG urng(value);
+
+    // integral types
+    test_seed_conversion<char>(urng, value);
+    test_seed_conversion<signed char>(urng, value);
+    test_seed_conversion<unsigned char>(urng, value);
+    test_seed_conversion<short>(urng, value);
+    test_seed_conversion<unsigned short>(urng, value);
+    test_seed_conversion<int>(urng, value);
+    test_seed_conversion<unsigned int>(urng, value);
+    test_seed_conversion<long>(urng, value);
+    test_seed_conversion<unsigned long>(urng, value);
+#if !defined(BOOST_NO_INT64_T)
+    test_seed_conversion<boost::int64_t>(urng, value);
+    test_seed_conversion<boost::uint64_t>(urng, value);
+#endif
+
+    // floating point types
+    test_seed_conversion<float>(urng, value);
+    test_seed_conversion<double>(urng, value);
+    test_seed_conversion<long double>(urng, value);
+}
+
+BOOST_AUTO_TEST_CASE(test_default_seed)
+{
+    BOOST_RANDOM_URNG urng;
+    BOOST_RANDOM_URNG urng2;
+    urng2();
+    BOOST_CHECK_NE(urng, urng2);
+    urng2.seed();
+    BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_arithmetic_seed)
+{
+    test_seed(static_cast<result_type>(0));
+    test_seed(static_cast<result_type>(127));
+    test_seed(static_cast<result_type>(539157235));
+    test_seed(static_cast<result_type>(~0u));
+}
+   
+BOOST_AUTO_TEST_CASE(test_iterator_seed)
+{
+    const std::vector<int> v(9999u, 0x41);
+    std::vector<int>::const_iterator it = v.begin();
+    std::vector<int>::const_iterator it_end = v.end();
+    BOOST_RANDOM_URNG urng(it, it_end);
+    BOOST_CHECK(it != v.begin());
+    std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
+    BOOST_CHECK_GT(n_words, 0);
+
+	it = v.begin();
+    BOOST_RANDOM_URNG urng2;
+    urng2.seed(it, it_end);
+    std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words2 = (it - v.begin());
+    BOOST_CHECK_EQUAL(n_words, n_words2);
+    BOOST_CHECK_EQUAL(urng, urng2);
+
+    it = v.end();
+    BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
+    BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
+
+    if(n_words > 1) {
+        it = v.end();
+        --it;
+		BOOST_CHECK_THROW(BOOST_RANDOM_URNG(it, it_end), std::invalid_argument);
+        it = v.end();
+        --it;
+        BOOST_CHECK_THROW(urng.seed(it, it_end), std::invalid_argument);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(test_seed_seq_seed)
+{
+	boost::random::seed_seq q;
+    BOOST_RANDOM_URNG urng(q);
+    BOOST_RANDOM_URNG urng2;
+    BOOST_CHECK_NE(urng, urng2);
+    urng2.seed(q);
+    BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+template<class CharT>
+void do_test_streaming(const BOOST_RANDOM_URNG& urng)
+{
+    BOOST_RANDOM_URNG urng2;
+    std::basic_ostringstream<CharT> output;
+    output << urng;
+    BOOST_CHECK_NE(urng, urng2);
+    // restore old state
+    std::basic_istringstream<CharT> input(output.str());
+    input >> urng2;
+    BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_streaming)
+{
+    BOOST_RANDOM_URNG urng;
+    urng.discard(9307);
+    do_test_streaming<char>(urng);
+#if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
+    do_test_streaming<wchar_t>(urng);
+#endif
+}
+
+BOOST_AUTO_TEST_CASE(test_discard)
+{
+    BOOST_RANDOM_URNG urng;
+    BOOST_RANDOM_URNG urng2;
+    BOOST_CHECK_EQUAL(urng, urng2);
+    for(int i = 0; i < 9307; ++i)
+        urng();
+    BOOST_CHECK_NE(urng, urng2);
+    urng2.discard(9307);
+    BOOST_CHECK_EQUAL(urng, urng2);
+}
+
+BOOST_AUTO_TEST_CASE(test_copy)
+{
+    BOOST_RANDOM_URNG urng;
+    urng.discard(9307);
+    {
+        BOOST_RANDOM_URNG urng2 = urng;
+        BOOST_CHECK_EQUAL(urng, urng2);
+    }
+    {
+        BOOST_RANDOM_URNG urng2(urng);
+        BOOST_CHECK_EQUAL(urng, urng2);
+    }
+    {
+        BOOST_RANDOM_URNG urng2;
+        urng2 = urng;
+        BOOST_CHECK_EQUAL(urng, urng2);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(test_min_max)
+{
+    BOOST_RANDOM_URNG urng;
+    for(int i = 0; i < 10000; ++i) {
+        result_type value = urng();
+        BOOST_CHECK_GE(value, (BOOST_RANDOM_URNG::min)());
+        BOOST_CHECK_LE(value, (BOOST_RANDOM_URNG::max)());
+    }
+}
+
+BOOST_AUTO_TEST_CASE(test_comparison)
+{
+    BOOST_RANDOM_URNG urng;
+    BOOST_RANDOM_URNG urng2;
+    BOOST_CHECK(urng == urng2);
+    BOOST_CHECK(!(urng != urng2));
+    urng();
+    BOOST_CHECK(urng != urng2);
+    BOOST_CHECK(!(urng == urng2));
+}
Added: trunk/libs/random/test/test_mt19937.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/random/test/test_mt19937.cpp	2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
@@ -0,0 +1,16 @@
+/* test_mt19937.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/mersenne_twister.hpp>
+
+#define BOOST_RANDOM_URNG boost::random::mt19937
+
+#include "test_generator.ipp"
Modified: trunk/libs/random/test/validate.cpp
==============================================================================
--- trunk/libs/random/test/validate.cpp	(original)
+++ trunk/libs/random/test/validate.cpp	2011-01-07 13:48:53 EST (Fri, 07 Jan 2011)
@@ -1,6 +1,7 @@
 /* boost validate.cpp
  *
  * Copyright Jens Maurer 2000
+ * Copyright Steven Watanabe 2010-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)
@@ -8,145 +9,78 @@
  * $Id$
  */
 
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-#pragma warning( disable : 4786 )
-#endif
-
-#include <iostream>
-#include <sstream>
-#include <string>
 #include <cmath>
-#include <iterator>
-#include <vector>
 #include <boost/random.hpp>
 #include <boost/config.hpp>
 
 #include <boost/test/test_tools.hpp>
 #include <boost/test/included/test_exec_monitor.hpp>
 
-#ifdef BOOST_NO_STDC_NAMESPACE
-  namespace std { using ::abs; using ::fabs; using ::pow; }
-#endif
-
-
-/*
- * General portability note:
- * MSVC mis-compiles explicit function template instantiations.
- * For example, f<A>() and f<B>() are both compiled to call f<A>().
- * BCC is unable to implicitly convert a "const char *" to a std::string
- * when using explicit function template instantiations.
- *
- * Therefore, avoid explicit function template instantiations.
- */
-
 /*
  * Validate correct implementation
  */
 
-// own run
-bool check_(unsigned long x, const boost::mt11213b&) { return x == 3809585648U; }
+template<class PRNG>
+typename PRNG::result_type validation_value(PRNG rng)
+{
+    for(int i = 0; i < 9999; i++)
+        rng();
+    return rng();
+}
+
+int test_main(int, char*[])
+{
+    // own run
+    BOOST_CHECK_EQUAL(validation_value(boost::mt11213b()), 3809585648U);
 
-// validation by experiment from mt19937.c
-bool check_(unsigned long x, const boost::mt19937&) { return x == 4123659995U; }
+    // validation by experiment from mt19937.c
+    BOOST_CHECK_EQUAL(validation_value(boost::mt19937()), 4123659995U);
 
 #if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-// validation from the C++0x draft (n3090)
-bool check_(boost::uint64_t x, const boost::mt19937_64&) { return x == UINT64_C(9981545732273789042); }
+    // validation from the C++0x draft (n3090)
+    BOOST_CHECK_EQUAL(validation_value(boost::mt19937_64()), UINT64_C(9981545732273789042));
 #endif
 
-// validation values from the publications
-bool check_(int x, const boost::minstd_rand0&) { return x == 1043618065; }
+    // validation values from the publications
+    BOOST_CHECK_EQUAL(validation_value(boost::minstd_rand0()), 1043618065);
 
-// validation values from the publications
-bool check_(int x, const boost::minstd_rand&) { return x == 399268537; }
+    // validation values from the publications
+    BOOST_CHECK_EQUAL(validation_value(boost::minstd_rand()), 399268537);
 
 #if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-// by experiment from lrand48()
-bool check_(unsigned long x, const boost::rand48&) { return x == 1993516219; }
+    // by experiment from lrand48()
+    BOOST_CHECK_EQUAL(validation_value(boost::rand48()), 1993516219);
 #endif
 
-// ????
-bool check_(unsigned long x, const boost::taus88&) { return x == 3535848941U; }
+    // ????
+    BOOST_CHECK_EQUAL(validation_value(boost::taus88()), 3535848941U);
 
-// ????
-bool check_(int x, const boost::ecuyer1988&) { return x == 2060321752; }
+    // ????
+    BOOST_CHECK_EQUAL(validation_value(boost::ecuyer1988()), 2060321752);
 
-// validation by experiment from Harry Erwin's generator.h (private e-mail)
-bool check_(unsigned int x, const boost::kreutzer1986&) { return x == 139726; }
+    // validation by experiment from Harry Erwin's generator.h (private e-mail)
+    BOOST_CHECK_EQUAL(validation_value(boost::kreutzer1986()), 139726);
 
-// validation from the C++0x draft (n3090)
-bool check_(unsigned int x, const boost::random::knuth_b&) { return x == 1112339016; }
+    // validation from the C++0x draft (n3090)
+    BOOST_CHECK_EQUAL(validation_value(boost::random::knuth_b()), 1112339016);
 
-bool check_(double x, const boost::lagged_fibonacci607&) { return std::abs(x-0.401269) < 1e-5; }
+    BOOST_CHECK_CLOSE_FRACTION(validation_value(boost::lagged_fibonacci607()), 0.401269, 1e-5);
 
-// principal operation validated with CLHEP, values by experiment
-bool check_(unsigned long x, const boost::ranlux3&) { return x == 5957620; }
-bool check_(unsigned long x, const boost::ranlux4&) { return x == 8587295; }
+    // principal operation validated with CLHEP, values by experiment
+    BOOST_CHECK_EQUAL(validation_value(boost::ranlux3()), 5957620);
+    BOOST_CHECK_EQUAL(validation_value(boost::ranlux4()), 8587295);
 
-bool check_(float x, const boost::ranlux3_01&)
-{ return std::abs(x-5957620/std::pow(2.0f,24)) < 1e-6; }
-bool check_(float x, const boost::ranlux4_01&)
-{ return std::abs(x-8587295/std::pow(2.0f,24)) < 1e-6; }
+    BOOST_CHECK_CLOSE_FRACTION(validation_value(boost::ranlux3_01()), 5957620/std::pow(2.0f,24), 1e-6);
+    BOOST_CHECK_CLOSE_FRACTION(validation_value(boost::ranlux4_01()), 8587295/std::pow(2.0f,24), 1e-6);
 
-bool check_(double x, const boost::ranlux64_3_01&)
-{ return std::abs(x-0.838413) < 1e-6; }
-bool check_(double x, const boost::ranlux64_4_01&)
-{ return std::abs(x-0.59839) < 1e-6; }
+    BOOST_CHECK_CLOSE_FRACTION(validation_value(boost::ranlux64_3_01()), 0.838413, 1e-6);
+    BOOST_CHECK_CLOSE_FRACTION(validation_value(boost::ranlux64_4_01()), 0.59839, 1e-6);
 
-bool check_(boost::uint32_t x, const boost::random::ranlux24&) { return x == 9901578; }
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-bool check_(boost::uint64_t x, const boost::random::ranlux48&) { return x == UINT64_C(249142670248501); }
-#endif
+    BOOST_CHECK_EQUAL(validation_value(boost::random::ranlux24()), 9901578);
 
-template<class PRNG>
-void validate(const std::string & name, const PRNG &)
-{
-  std::cout << "validating " << name << ": ";
-  PRNG rng;  // default ctor
-  for(int i = 0; i < 9999; i++)
-    rng();
-  typename PRNG::result_type val = rng();
-  // make sure the validation function is a static member
-  bool result = check_(val, rng);
-  
-  // allow for a simple eyeball check for MSVC instantiation brokenness
-  // (if the numbers for all generators are the same, it's obviously broken)
-  std::cout << val << std::endl;
-  BOOST_CHECK(result);
-}
-
-void validate_all()
-{
-  using namespace boost;
 #if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-  validate("rand48", rand48());
+    BOOST_CHECK_EQUAL(validation_value(boost::random::ranlux48()), UINT64_C(249142670248501));
 #endif
-  validate("minstd_rand", minstd_rand());
-  validate("minstd_rand0", minstd_rand0());
-  validate("ecuyer combined", ecuyer1988());
-  validate("mt11213b", mt11213b());
-  validate("mt19937", mt19937());
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-  validate("mt19937_64", mt19937_64());
-#endif
-  validate("kreutzer1986", kreutzer1986());
-  validate("knuth_b", boost::random::knuth_b());
-  validate("ranlux3", ranlux3());
-  validate("ranlux4", ranlux4());
-  validate("ranlux3_01", ranlux3_01());
-  validate("ranlux4_01", ranlux4_01());
-  validate("ranlux64_3_01", ranlux64_3_01());
-  validate("ranlux64_4_01", ranlux64_4_01());
-  validate("ranlux24", boost::random::ranlux24());
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-  validate("ranlux48", boost::random::ranlux48());
-#endif
-  validate("taus88", taus88());
-  validate("lagged_fibonacci607", lagged_fibonacci607());
-}
 
-int test_main(int, char*[])
-{
-  validate_all();
-  return 0;
+    return 0;
 }