Boost logo

Boost-Commit :

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;
 }


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