|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r60199 - in trunk: boost boost/random/detail libs/random libs/random/build libs/random/example libs/random/performance libs/random/src libs/random/test
From: steven_at_[hidden]
Date: 2010-03-05 14:12:48
Author: steven_watanabe
Date: 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
New Revision: 60199
URL: http://svn.boost.org/trac/boost/changeset/60199
Log:
Rearrange the componenents in libs/random and create a library for random_device. Fixes #3672
Added:
trunk/boost/random/detail/auto_link.hpp (contents, props changed)
trunk/libs/random/build/
trunk/libs/random/build/Jamfile.v2 (contents, props changed)
trunk/libs/random/example/random_demo.cpp
- copied unchanged from r60077, /trunk/libs/random/random_demo.cpp
trunk/libs/random/performance/
trunk/libs/random/performance/generate_table.cpp
- copied unchanged from r60077, /trunk/libs/random/generate_table.cpp
trunk/libs/random/performance/nondet_random_speed.cpp
- copied unchanged from r60077, /trunk/libs/random/nondet_random_speed.cpp
trunk/libs/random/performance/random_speed.cpp
- copied unchanged from r60077, /trunk/libs/random/random_speed.cpp
trunk/libs/random/src/
trunk/libs/random/src/random_device.cpp
- copied, changed from r60077, /trunk/libs/random/random_device.cpp
trunk/libs/random/test/histogram.cpp
- copied unchanged from r60077, /trunk/libs/random/histogram.cpp
trunk/libs/random/test/instantiate.cpp
- copied unchanged from r60077, /trunk/libs/random/instantiate.cpp
trunk/libs/random/test/integrate.hpp
- copied unchanged from r60077, /trunk/libs/random/integrate.hpp
trunk/libs/random/test/random_test.cpp
- copied unchanged from r60077, /trunk/libs/random/random_test.cpp
trunk/libs/random/test/statistic_tests.cpp
- copied unchanged from r60077, /trunk/libs/random/statistic_tests.cpp
trunk/libs/random/test/statistic_tests.hpp
- copied unchanged from r60077, /trunk/libs/random/statistic_tests.hpp
trunk/libs/random/test/validate.cpp
- copied unchanged from r60077, /trunk/libs/random/validate.cpp
Removed:
trunk/libs/random/generate_table.cpp
trunk/libs/random/histogram.cpp
trunk/libs/random/instantiate.cpp
trunk/libs/random/integrate.hpp
trunk/libs/random/nondet_random_speed.cpp
trunk/libs/random/random_demo.cpp
trunk/libs/random/random_device.cpp
trunk/libs/random/random_speed.cpp
trunk/libs/random/random_test.cpp
trunk/libs/random/statistic_tests.cpp
trunk/libs/random/statistic_tests.hpp
trunk/libs/random/validate.cpp
Text files modified:
trunk/boost/nondet_random.hpp | 7 +++
trunk/libs/random/src/random_device.cpp | 80 ++++++++++++++++++++++++++++++++++++++-
trunk/libs/random/test/Jamfile.v2 | 6 +--
3 files changed, 86 insertions(+), 7 deletions(-)
Modified: trunk/boost/nondet_random.hpp
==============================================================================
--- trunk/boost/nondet_random.hpp (original)
+++ trunk/boost/nondet_random.hpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
@@ -23,6 +23,7 @@
#include <boost/config.hpp>
#include <boost/utility.hpp> // noncopyable
#include <boost/integer_traits.hpp> // compile-time integral limits
+#include <boost/random/detail/auto_link.hpp>
namespace boost {
@@ -61,6 +62,12 @@
* pseudo-device, which blocks on reads if the entropy pool has no more
* random bits available.
*
+ * <b>Inplementation Note for Windows</b>
+ *
+ * On the Windows operating system, token is interpreted as the name
+ * of a cryptographic service provider. By default \random_device uses
+ * MS_DEF_PROV.
+ *
* <b>Performance</b>
*
* The test program <a href="\boost/libs/random/nondet_random_speed.cpp">
Added: trunk/boost/random/detail/auto_link.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/random/detail/auto_link.hpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
@@ -0,0 +1,42 @@
+/* boost random auto_link.hpp header file
+ *
+ * Copyright Steven Watanabe 2010
+ * 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$
+ */
+
+#ifndef BOOST_RANDOM_DETAIL_AUTO_LINK_HPP
+#define BOOST_RANDOM_DETAIL_AUTO_LINK_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_DECLSPEC
+ #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
+ #if defined(BOOST_RANDOM_SOURCE)
+ #define BOOST_RANDOM_DECL __declspec(dllexport)
+ #else
+ #define BOOST_RANDOM_DECL __declspec(dllimport)
+ #endif
+ #endif
+#endif
+
+#ifndef BOOST_RANDOM_DECL
+ #define BOOST_RANDOM_DECL
+#endif
+
+#if !defined(BOOST_RANDOM_NO_LIB) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_RANDOM_SOURCE)
+
+#define BOOST_LIB_NAME boost_random
+
+#if defined(BOOST_RANDOM_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+ #define BOOST_DYN_LINK
+#endif
+
+#include <boost/config/auto_link.hpp>
+
+#endif
+
+#endif
Added: trunk/libs/random/build/Jamfile.v2
==============================================================================
--- (empty file)
+++ trunk/libs/random/build/Jamfile.v2 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
@@ -0,0 +1,18 @@
+# Jamfile.v2
+#
+# Copyright (c) 2010
+# Steven Watanabe
+#
+# 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)
+
+project /boost/random
+ : source-location ../src
+ : requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
+ : usage-requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
+;
+
+lib boost_random : [ glob *.cpp ] ;
+
+boost-install boost_random ;
Deleted: trunk/libs/random/generate_table.cpp
==============================================================================
--- trunk/libs/random/generate_table.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,121 +0,0 @@
-// generate_table.cpp
-//
-// Copyright (c) 2009
-// Steven Watanabe
-//
-// 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)
-
-#include <vector>
-#include <utility>
-#include <iostream>
-#include <cstring>
-#include <fstream>
-#include <boost/regex.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-#include <boost/format.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-
-boost::regex generator_regex("(?:fixed-range )?([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
-boost::regex distribution_regex("([^\\s]+)( virtual function)? ([^:]+): (\\d+(?:\\.\\d+)?) nsec/loop = \\d+(?:\\.\\d+)? CPU cycles");
-
-std::string template_name(std::string arg) {
- return boost::regex_replace(arg, boost::regex("[^\\w]"), "_");
-}
-
-struct compare_second {
- template<class Pair>
- bool operator()(const Pair& p1, const Pair& p2) const {
- return (p1.second < p2.second);
- }
-};
-
-typedef boost::multi_index_container<
- std::string,
- boost::mpl::vector<
- boost::multi_index::sequenced<>,
- boost::multi_index::hashed_unique<boost::multi_index::identity<std::string> >
- >
-> unique_list;
-
-int main() {
- std::vector<std::pair<std::string, double> > generator_info;
- std::string line;
- while(std::getline(std::cin, line)) {
- boost::smatch match;
- if(std::strncmp(line.c_str(), "counting ", 9) == 0) break;
- if(boost::regex_match(line, match, generator_regex)) {
- std::string generator(match[1]);
- double time = boost::lexical_cast<double>(match[2]);
- if(generator != "counting") {
- generator_info.push_back(std::make_pair(generator, time));
- }
- } else {
- std::cerr << "oops: " << line << std::endl;
- }
- }
-
- double min = std::min_element(generator_info.begin(), generator_info.end(), compare_second())->second;
-
- std::ofstream generator_defs("performance_data.qbk");
- std::ofstream generator_performance("generator_performance.qbk");
- generator_performance << "[table Basic Generators\n";
- generator_performance << " [[generator] [M rn/sec] [time per random number \\[nsec\\]] "
- "[relative speed compared to fastest \\[percent\\]]]\n";
-
- typedef std::pair<std::string, double> pair_type;
- BOOST_FOREACH(const pair_type& pair, generator_info) {
- generator_defs << boost::format("[template %s_speed[] %d%%]\n")
- % template_name(pair.first) % static_cast<int>(100*min/pair.second);
- generator_performance << boost::format(" [[%s][%g][%g][%d%%]]\n")
- % pair.first % (1000/pair.second) % pair.second % static_cast<int>(100*min/pair.second);
- }
- generator_performance << "]\n";
-
- std::map<std::pair<std::string, std::string>, double> distribution_info;
- unique_list generator_names;
- unique_list distribution_names;
- do {
- boost::smatch match;
- if(boost::regex_match(line, match, distribution_regex)) {
- if(!match[2].matched && match[1] != "counting") {
- std::string generator(match[1]);
- std::string distribution(match[3]);
- double time = boost::lexical_cast<double>(match[4]);
- generator_names.push_back(generator);
- distribution_names.push_back(distribution);
- distribution_info.insert(std::make_pair(std::make_pair(distribution, generator), time));
- }
- } else {
- std::cerr << "oops: " << line << std::endl;
- }
- } while(std::getline(std::cin, line));
-
- std::ofstream distribution_performance("distribution_performance.qbk");
-
- distribution_performance << "[table Distributions\n";
- distribution_performance << " [[\\[M rn/sec\\]]";
- BOOST_FOREACH(const std::string& generator, generator_names) {
- distribution_performance << boost::format("[%s]") % generator;
- }
- distribution_performance << "]\n";
- BOOST_FOREACH(const std::string& distribution, distribution_names) {
- distribution_performance << boost::format(" [[%s]") % distribution;
- BOOST_FOREACH(const std::string& generator, generator_names) {
- std::map<std::pair<std::string, std::string>, double>::iterator pos =
- distribution_info.find(std::make_pair(distribution, generator));
- if(pos != distribution_info.end()) {
- distribution_performance << boost::format("[%g]") % (1000/pos->second);
- } else {
- distribution_performance << "[-]";
- }
- }
- distribution_performance << "]\n";
- }
- distribution_performance << "]\n";
-}
Deleted: trunk/libs/random/histogram.cpp
==============================================================================
--- trunk/libs/random/histogram.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,165 +0,0 @@
-/* boost histogram.cpp graphical verification of distribution functions
- *
- * Copyright Jens Maurer 2000
- * 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$
- *
- * This test program allows to visibly examine the results of the
- * distribution functions.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <vector>
-#include <algorithm>
-#include <cmath>
-#include <string>
-#include <boost/random.hpp>
-
-
-void plot_histogram(const std::vector<int>& slots, int samples,
- double from, double to)
-{
- int m = *std::max_element(slots.begin(), slots.end());
- const int nRows = 20;
- std::cout.setf(std::ios::fixed|std::ios::left);
- std::cout.precision(5);
- for(int r = 0; r < nRows; r++) {
- double y = ((nRows - r) * double(m))/(nRows * samples);
- std::cout << std::setw(10) << y << " ";
- for(unsigned int col = 0; col < slots.size(); col++) {
- char out = ' ';
- if(slots[col]/double(samples) >= y)
- out = 'x';
- std::cout << out;
- }
- std::cout << std::endl;
- }
- std::cout << std::setw(12) << " "
- << std::setw(10) << from;
- std::cout.setf(std::ios::right, std::ios::adjustfield);
- std::cout << std::setw(slots.size()-10) << to << std::endl;
-}
-
-// I am not sure whether these two should be in the library as well
-
-// maintain sum of NumberGenerator results
-template<class NumberGenerator,
- class Sum = typename NumberGenerator::result_type>
-class sum_result
-{
-public:
- typedef NumberGenerator base_type;
- typedef typename base_type::result_type result_type;
- explicit sum_result(const base_type & g) : gen(g), _sum(0) { }
- result_type operator()() { result_type r = gen(); _sum += r; return r; }
- base_type & base() { return gen; }
- Sum sum() const { return _sum; }
- void reset() { _sum = 0; }
-private:
- base_type gen;
- Sum _sum;
-};
-
-
-// maintain square sum of NumberGenerator results
-template<class NumberGenerator,
- class Sum = typename NumberGenerator::result_type>
-class squaresum_result
-{
-public:
- typedef NumberGenerator base_type;
- typedef typename base_type::result_type result_type;
- explicit squaresum_result(const base_type & g) : gen(g), _sum(0) { }
- result_type operator()() { result_type r = gen(); _sum += r*r; return r; }
- base_type & base() { return gen; }
- Sum squaresum() const { return _sum; }
- void reset() { _sum = 0; }
-private:
- base_type gen;
- Sum _sum;
-};
-
-
-template<class RNG>
-void histogram(RNG base, int samples, double from, double to,
- const std::string & name)
-{
- typedef squaresum_result<sum_result<RNG, double>, double > SRNG;
- SRNG gen((sum_result<RNG, double>(base)));
- const int nSlots = 60;
- std::vector<int> slots(nSlots,0);
- for(int i = 0; i < samples; i++) {
- double val = gen();
- if(val < from || val >= to) // early check avoids overflow
- continue;
- int slot = int((val-from)/(to-from) * nSlots);
- if(slot < 0 || slot > (int)slots.size())
- continue;
- slots[slot]++;
- }
- std::cout << name << std::endl;
- plot_histogram(slots, samples, from, to);
- double mean = gen.base().sum() / samples;
- std::cout << "mean: " << mean
- << " sigma: " << std::sqrt(gen.squaresum()/samples-mean*mean)
- << "\n" << std::endl;
-}
-
-template<class PRNG, class Dist>
-inline boost::variate_generator<PRNG&, Dist> make_gen(PRNG & rng, Dist d)
-{
- return boost::variate_generator<PRNG&, Dist>(rng, d);
-}
-
-template<class PRNG>
-void histograms()
-{
- PRNG rng;
- using namespace boost;
- histogram(make_gen(rng, uniform_smallint<>(0, 5)), 100000, -1, 6,
- "uniform_smallint(0,5)");
- histogram(make_gen(rng, uniform_int<>(0, 5)), 100000, -1, 6,
- "uniform_int(0,5)");
- histogram(make_gen(rng, uniform_real<>(0,1)), 100000, -0.5, 1.5,
- "uniform_real(0,1)");
- histogram(make_gen(rng, bernoulli_distribution<>(0.2)), 100000, -0.5, 1.5,
- "bernoulli(0.2)");
- histogram(make_gen(rng, binomial_distribution<>(4, 0.2)), 100000, -1, 5,
- "binomial(4, 0.2)");
- histogram(make_gen(rng, triangle_distribution<>(1, 2, 8)), 100000, 0, 10,
- "triangle(1,2,8)");
- histogram(make_gen(rng, geometric_distribution<>(5.0/6.0)), 100000, 0, 10,
- "geometric(5/6)");
- histogram(make_gen(rng, exponential_distribution<>(0.3)), 100000, 0, 10,
- "exponential(0.3)");
- histogram(make_gen(rng, cauchy_distribution<>()), 100000, -5, 5,
- "cauchy");
- histogram(make_gen(rng, lognormal_distribution<>(3, 2)), 100000, 0, 10,
- "lognormal");
- histogram(make_gen(rng, normal_distribution<>()), 100000, -3, 3,
- "normal");
- histogram(make_gen(rng, normal_distribution<>(0.5, 0.5)), 100000, -3, 3,
- "normal(0.5, 0.5)");
- histogram(make_gen(rng, poisson_distribution<>(1.5)), 100000, 0, 5,
- "poisson(1.5)");
- histogram(make_gen(rng, poisson_distribution<>(10)), 100000, 0, 20,
- "poisson(10)");
- histogram(make_gen(rng, gamma_distribution<>(0.5)), 100000, 0, 0.5,
- "gamma(0.5)");
- histogram(make_gen(rng, gamma_distribution<>(1)), 100000, 0, 3,
- "gamma(1)");
- histogram(make_gen(rng, gamma_distribution<>(2)), 100000, 0, 6,
- "gamma(2)");
-}
-
-
-int main()
-{
- histograms<boost::mt19937>();
- // histograms<boost::lagged_fibonacci607>();
-}
-
Deleted: trunk/libs/random/instantiate.cpp
==============================================================================
--- trunk/libs/random/instantiate.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,437 +0,0 @@
-/* boost validate.cpp
- *
- * Copyright Jens Maurer 2000
- * 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$
- */
-
-#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/preprocessor/stringize.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.
- */
-
-/*
- * Check function signatures
- */
-
-#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x570) )
-#pragma warn -par
-#endif
-template<class URNG, class Dist>
-void instantiate_dist(URNG& urng, const char * name, const Dist& dist)
-{
- // this makes a copy of urng
- boost::variate_generator<URNG, Dist> gen(urng, dist);
-
- // this keeps a reference to urng
- boost::variate_generator<URNG&, Dist> genref(urng, dist);
-
- BOOST_CHECK(gen.engine() == genref.engine());
-
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- // and here is a pointer to (a copy of) the urng
- URNG copy = urng;
- boost::variate_generator<URNG*, Dist> genptr(©, dist);
-#endif
-
- for(int i = 0; i < 1000; ++i) {
- (void) gen();
- (void) genref();
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- (void) genptr();
-#endif
- }
- // If the values are not exactly equal, we cannot
- // rely on them being close...
- typename Dist::result_type g = gen();
- BOOST_CHECK_EQUAL(g, genref());
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
- BOOST_CHECK_EQUAL(g, genptr());
-#endif
-
- (void) gen.engine();
- gen.distribution().reset();
-
- Dist d = dist; // copy ctor
- d = dist; // copy assignment
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- {
- std::ostringstream file;
- file << urng << std::endl;
- file << d;
- std::istringstream input(file.str());
- // std::cout << file.str() << std::endl;
- URNG restored_engine;
- input >> restored_engine;
- input >> std::ws;
- Dist restored_dist;
- input >> restored_dist;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- boost::variate_generator<URNG, Dist> old(urng, d);
- boost::variate_generator<URNG, Dist> restored(restored_engine, restored_dist);
- // advance some more so that state is exercised
- for(int i = 0; i < 1000; ++i) {
- (void) old();
- (void) restored();
- }
- BOOST_CHECK_MESSAGE((std::abs(old()-restored()) < 0.0001),
- (std::string(name) + " old == restored_dist"));
-#endif // BOOST_MSVC
- }
-#endif // BOOST_RANDOM_NO_STREAM_OPERATORS
-}
-
-template<class URNG, class RealType>
-void instantiate_real_dist(URNG& urng, RealType /* ignored */)
-{
- instantiate_dist(urng, "uniform_01",
- boost::uniform_01<RealType>());
- instantiate_dist(urng, "uniform_real",
- boost::uniform_real<RealType>(0, 2.1));
- instantiate_dist(urng, "triangle_distribution",
- boost::triangle_distribution<RealType>(1, 1.5, 7));
- instantiate_dist(urng, "exponential_distribution",
- boost::exponential_distribution<RealType>(5));
- instantiate_dist(urng, "normal_distribution",
- boost::normal_distribution<RealType>());
- instantiate_dist(urng, "lognormal_distribution",
- boost::lognormal_distribution<RealType>(1, 1));
- instantiate_dist(urng, "cauchy_distribution",
- boost::cauchy_distribution<RealType>(1));
- instantiate_dist(urng, "gamma_distribution",
- boost::gamma_distribution<RealType>(1));
-}
-
-template<class URNG, class T, class Converted>
-void test_seed_conversion(URNG & urng, const T & t, const Converted &) {
- 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());
- }
-}
-
-// rand48 uses non-standard seeding
-template<class T, class Converted>
-void test_seed_conversion(boost::rand48 & urng, const T & t, const Converted &) {
- boost::rand48 urng2(t);
- urng2.seed(t);
-}
-
-template<class URNG, class ResultType>
-void test_seed(const URNG &, const ResultType & value) {
- URNG urng(value);
-
- // integral types
- test_seed_conversion(urng, value, static_cast<char>(0));
- test_seed_conversion(urng, value, static_cast<signed char>(0));
- test_seed_conversion(urng, value, static_cast<unsigned char>(0));
- test_seed_conversion(urng, value, static_cast<short>(0));
- test_seed_conversion(urng, value, static_cast<unsigned short>(0));
- test_seed_conversion(urng, value, static_cast<int>(0));
- test_seed_conversion(urng, value, static_cast<unsigned int>(0));
- test_seed_conversion(urng, value, static_cast<long>(0));
- test_seed_conversion(urng, value, static_cast<unsigned long>(0));
-#if !defined(BOOST_NO_INT64_T)
- test_seed_conversion(urng, value, static_cast<boost::int64_t>(0));
- test_seed_conversion(urng, value, static_cast<boost::uint64_t>(0));
-#endif
-
- // floating point types
- test_seed_conversion(urng, value, static_cast<float>(0));
- test_seed_conversion(urng, value, static_cast<double>(0));
- test_seed_conversion(urng, value, static_cast<long double>(0));
-}
-
-template<class URNG, class ResultType>
-void instantiate_seed(const URNG & urng, const ResultType &) {
- {
- URNG urng;
- URNG urng2;
- urng2.seed();
- BOOST_CHECK(urng == urng2);
- }
- test_seed(urng, static_cast<ResultType>(0));
- test_seed(urng, static_cast<ResultType>(127));
- test_seed(urng, static_cast<ResultType>(539157235));
- test_seed(urng, static_cast<ResultType>(~0u));
-}
-
-// ranlux uses int32_t for seeding instead of result_type
-template<class ResultType>
-void instantiate_seed(const boost::ranlux3 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux3, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux4 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux4, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux3_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux3_01, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux4_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux4_01, boost::uint32_t>(urng, ResultType());
-}
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_3 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_4 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3, boost::uint32_t>(urng, ResultType());
-}
-#endif
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_3_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_3_01, boost::uint32_t>(urng, ResultType());
-}
-template<class ResultType>
-void instantiate_seed(const boost::ranlux64_4_01 & urng, const ResultType &) {
- instantiate_seed<boost::ranlux64_4_01, boost::uint32_t>(urng, ResultType());
-}
-
-
-template<class URNG, class ResultType>
-void instantiate_urng(const std::string & s, const URNG & u, const ResultType & r)
-{
- std::cout << "Basic tests for " << s << std::endl;
- URNG urng;
- instantiate_seed(u, r); // seed() member function
- int a[URNG::has_fixed_range ? 5 : 10]; // compile-time constant
- (void) a; // avoid "unused" warning
- typename URNG::result_type x1 = urng();
- ResultType x2 = x1;
- (void) &x2; // avoid "unused" warning
-
- URNG urng2 = urng; // copy constructor
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- BOOST_CHECK(urng == urng2); // operator==
- BOOST_CHECK(!(urng != urng2)); // operator!=
- urng();
- urng2 = urng; // copy assignment
- BOOST_CHECK(urng == urng2);
- urng2 = URNG(urng2); // copy constructor, not templated constructor
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
-
- const std::vector<int> v(9999u, 0x41);
- std::vector<int>::const_iterator it = v.begin();
- std::vector<int>::const_iterator it_end = v.end();
- URNG urng3(it, it_end);
- BOOST_CHECK(it != v.begin());
- std::iterator_traits<std::vector<int>::const_iterator>::difference_type n_words = (it - v.begin());
- std::cout << "; seeding uses " << n_words << " words" << std::endl;
-
- it = v.end();
- BOOST_CHECK_THROW(urng3.seed(it, it_end), std::invalid_argument);
-
- if(n_words > 1) {
- it = v.end();
- --it;
- BOOST_CHECK_THROW(urng3.seed(it, it_end), std::invalid_argument);
- }
-
- // check for min/max members
- ResultType min = (urng3.min)();
- (void) &min;
- ResultType max = (urng3.max)();
- (void) &max;
-
-#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
- // Streamable concept not supported for broken compilers
-
- // advance a little so that state is relatively arbitrary
- for(int i = 0; i < 9307; ++i)
- urng();
- urng2 = urng;
-
- {
- // narrow stream first
- std::ostringstream file;
- file << urng;
- // move forward
- urng();
- // restore old state
- std::istringstream input(file.str());
- input >> urng;
- // std::cout << file.str() << std::endl;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- // advance some more so that state is exercised
- for(int i = 0; i < 10000; ++i) {
- urng();
- urng2();
- }
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
- }
-
- urng2 = urng;
-#if !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_STD_WSTRING)
- {
- // then wide stream
- std::wostringstream file;
- file << urng;
- // move forward
- urng();
- std::wistringstream input(file.str());
- input >> urng;
-#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // MSVC brokenness
- // advance some more so that state is exercised
- for(int i = 0; i < 10000; ++i) {
- urng();
- urng2();
- }
- BOOST_CHECK(urng == urng2);
-#endif // BOOST_MSVC
- }
-#endif // BOOST_NO_STD_WSTREAMBUF, BOOST_NO_STD_WSTRING
-#endif // BOOST_RANDOM_NO_STREAM_OPERATORS
-
- // instantiate various distributions with this URNG
- instantiate_dist(urng, "uniform_smallint", boost::uniform_smallint<>(0, 11));
- instantiate_dist(urng, "uniform_int", boost::uniform_int<>(-200, 20000));
- instantiate_dist(urng, "bernoulli_distribution",
- boost::bernoulli_distribution<>(0.2));
- instantiate_dist(urng, "binomial_distribution",
- boost::binomial_distribution<>(4, 0.2));
- instantiate_dist(urng, "geometric_distribution",
- boost::geometric_distribution<>(0.8));
- instantiate_dist(urng, "poisson_distribution",
- boost::poisson_distribution<>(1));
-
- instantiate_real_dist(urng, 1.0f);
- instantiate_real_dist(urng, 1.0);
- instantiate_real_dist(urng, 1.0l);
-
-#if 0
- // We cannot compare the outcomes before/after save with std::abs(x-y)
- instantiate_dist("uniform_on_sphere",
- boost::uniform_on_sphere<URNG>(urng, 2));
-#endif
-}
-
-template<class T>
-void extra_tests(T*)
-{
-}
-
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-void extra_tests(boost::rand48*)
-{
- using namespace boost;
- rand48 rnd(boost::int32_t(5));
- rand48 rnd2(boost::uint64_t(0x80000000) * 42);
- rnd.seed(boost::int32_t(17));
- rnd2.seed(boost::uint64_t(0x80000000) * 49);
-}
-#endif
-
-void extra_tests(boost::minstd_rand*)
-{
- using namespace boost;
- minstd_rand mstd(42);
- mstd.seed(17);
-}
-
-void extra_tests(boost::mt19937*)
-{
- using namespace boost;
- minstd_rand mstd(42);
- mstd.seed(17);
-
- mt19937 mt(boost::uint32_t(17)); // needs to be an exact type match for MSVC
- int i = 42;
- mt.seed(boost::uint32_t(i));
- mt19937 mt2(mstd);
- mt2.seed(mstd);
-
- random_number_generator<mt19937> std_rng(mt2);
- (void) std_rng(10);
-}
-
-void instantiate_all()
-{
- using namespace boost;
-
- typedef boost::random::lagged_fibonacci<boost::uint32_t, 24, 607, 273> lagged_fibonacci;
-
- typedef BOOST_RANDOM_URNG_TEST::result_type result_type;
- instantiate_urng(BOOST_PP_STRINGIZE(BOOST_RANDOM_URNG_TEST), BOOST_RANDOM_URNG_TEST(), static_cast<result_type>(0));
- BOOST_RANDOM_URNG_TEST* type_ptr = 0;
- extra_tests(type_ptr);
-
-}
-
-
-#if defined(BOOST_MSVC) && _MSC_VER < 1300
-
-// These explicit instantiations are necessary, otherwise MSVC does
-// not find the <boost/operators.hpp> inline friends.
-// We ease the typing with a suitable preprocessor macro.
-#define INSTANT(x) \
-template class boost::uniform_smallint<x>; \
-template class boost::uniform_int<x>; \
-template class boost::uniform_real<x>; \
-template class boost::bernoulli_distribution<x>; \
-template class boost::geometric_distribution<x>; \
-template class boost::triangle_distribution<x>; \
-template class boost::exponential_distribution<x>; \
-template class boost::normal_distribution<x>; \
-template class boost::uniform_on_sphere<x>; \
-template class boost::lognormal_distribution<x>;
-
-INSTANT(boost::minstd_rand0)
-INSTANT(boost::minstd_rand)
-INSTANT(boost::ecuyer1988)
-INSTANT(boost::kreutzer1986)
-INSTANT(boost::hellekalek1995)
-INSTANT(boost::mt19937)
-INSTANT(boost::mt11213b)
-
-#undef INSTANT
-#endif
-
-
-int test_main(int, char*[])
-{
- instantiate_all();
- return 0;
-}
Deleted: trunk/libs/random/integrate.hpp
==============================================================================
--- trunk/libs/random/integrate.hpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,79 +0,0 @@
-/* integrate.hpp header file
- *
- * Copyright Jens Maurer 2000
- * 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$
- *
- * Revision history
- * 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
- */
-
-#ifndef INTEGRATE_HPP
-#define INTEGRATE_HPP
-
-#include <boost/limits.hpp>
-
-template<class UnaryFunction>
-inline typename UnaryFunction::result_type
-trapezoid(UnaryFunction f, typename UnaryFunction::argument_type a,
- typename UnaryFunction::argument_type b, int n)
-{
- typename UnaryFunction::result_type tmp = 0;
- for(int i = 1; i <= n-1; ++i)
- tmp += f(a+(b-a)/n*i);
- return (b-a)/2/n * (f(a) + f(b) + 2*tmp);
-}
-
-template<class UnaryFunction>
-inline typename UnaryFunction::result_type
-simpson(UnaryFunction f, typename UnaryFunction::argument_type a,
- typename UnaryFunction::argument_type b, int n)
-{
- typename UnaryFunction::result_type tmp1 = 0;
- for(int i = 1; i <= n-1; ++i)
- tmp1 += f(a+(b-a)/n*i);
- typename UnaryFunction::result_type tmp2 = 0;
- for(int i = 1; i <= n ; ++i)
- tmp2 += f(a+(b-a)/2/n*(2*i-1));
-
- return (b-a)/6/n * (f(a) + f(b) + 2*tmp1 + 4*tmp2);
-}
-
-// compute b so that f(b) = y; assume f is monotone increasing
-template<class UnaryFunction>
-inline typename UnaryFunction::argument_type
-invert_monotone_inc(UnaryFunction f, typename UnaryFunction::result_type y,
- typename UnaryFunction::argument_type lower = -1,
- typename UnaryFunction::argument_type upper = 1)
-{
- while(upper-lower > 1e-6) {
- double middle = (upper+lower)/2;
- if(f(middle) > y)
- upper = middle;
- else
- lower = middle;
- }
- return (upper+lower)/2;
-}
-
-// compute b so that I(f(x), a, b) == y
-template<class UnaryFunction>
-inline typename UnaryFunction::argument_type
-quantil(UnaryFunction f, typename UnaryFunction::argument_type a,
- typename UnaryFunction::result_type y,
- typename UnaryFunction::argument_type step)
-{
- typedef typename UnaryFunction::result_type result_type;
- if(y >= 1.0)
- return std::numeric_limits<result_type>::infinity();
- typename UnaryFunction::argument_type b = a;
- for(result_type result = 0; result < y; b += step)
- result += step*f(b);
- return b;
-}
-
-
-#endif /* INTEGRATE_HPP */
Deleted: trunk/libs/random/nondet_random_speed.cpp
==============================================================================
--- trunk/libs/random/nondet_random_speed.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,64 +0,0 @@
-/* boost nondet_random_speed.cpp performance test
- *
- * Copyright Jens Maurer 2000
- * 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 <iostream>
-#include <string>
-#include <boost/timer.hpp>
-#include <boost/nondet_random.hpp>
-
-// set to your CPU frequency in MHz
-static const double cpu_frequency = 200 * 1e6;
-
-static void show_elapsed(double end, int iter, const std::string & name)
-{
- double usec = end/iter*1e6;
- double cycles = usec * cpu_frequency/1e6;
- std::cout << name << ": "
- << usec*1e3 << " nsec/loop = "
- << cycles << " CPU cycles"
- << std::endl;
-}
-
-template<class Result, class RNG>
-static void timing(RNG & rng, int iter, const std::string& name)
-{
- volatile Result tmp; // make sure we're not optimizing too much
- boost::timer t;
- for(int i = 0; i < iter; i++)
- tmp = rng();
- show_elapsed(t.elapsed(), iter, name);
-}
-
-template<class RNG>
-void run(int iter, const std::string & name)
-{
- RNG rng;
- timing<long>(rng, iter, name);
-}
-
-int main(int argc, char*argv[])
-{
- if(argc != 2) {
- std::cerr << "usage: " << argv[0] << " iterations" << std::endl;
- return 1;
- }
-
- int iter = std::atoi(argv[1]);
-
-#ifdef __linux__
- boost::random_device dev;
- timing<unsigned int>(dev, iter, "random_device");
-#else
-#error The non-deterministic random device is currently available on Linux only.
-#endif
-
- return 0;
-}
Deleted: trunk/libs/random/random_demo.cpp
==============================================================================
--- trunk/libs/random/random_demo.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,128 +0,0 @@
-/* boost random_demo.cpp profane demo
- *
- * Copyright Jens Maurer 2000
- * 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$
- *
- * A short demo program how to use the random number library.
- */
-
-#include <iostream>
-#include <fstream>
-#include <ctime> // std::time
-
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/uniform_int.hpp>
-#include <boost/random/uniform_real.hpp>
-#include <boost/random/variate_generator.hpp>
-
-// Sun CC doesn't handle boost::iterator_adaptor yet
-#if !defined(__SUNPRO_CC) || (__SUNPRO_CC > 0x530)
-#include <boost/generator_iterator.hpp>
-#endif
-
-#ifdef BOOST_NO_STDC_NAMESPACE
-namespace std {
- using ::time;
-}
-#endif
-
-// This is a typedef for a random number generator.
-// Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand
-typedef boost::minstd_rand base_generator_type;
-
-// This is a reproducible simulation experiment. See main().
-void experiment(base_generator_type & generator)
-{
- // Define a uniform random number distribution of integer values between
- // 1 and 6 inclusive.
- typedef boost::uniform_int<> distribution_type;
- typedef boost::variate_generator<base_generator_type&, distribution_type> gen_type;
- gen_type die_gen(generator, distribution_type(1, 6));
-
-#if !defined(__SUNPRO_CC) || (__SUNPRO_CC > 0x530)
- // If you want to use an STL iterator interface, use iterator_adaptors.hpp.
- // Unfortunately, this doesn't work on SunCC yet.
- boost::generator_iterator<gen_type> die(&die_gen);
- for(int i = 0; i < 10; i++)
- std::cout << *die++ << " ";
- std::cout << '\n';
-#endif
-}
-
-int main()
-{
- // Define a random number generator and initialize it with a reproducible
- // seed.
- // (The seed is unsigned, otherwise the wrong overload may be selected
- // when using mt19937 as the base_generator_type.)
- base_generator_type generator(42u);
-
- std::cout << "10 samples of a uniform distribution in [0..1):\n";
-
- // Define a uniform random number distribution which produces "double"
- // values between 0 and 1 (0 inclusive, 1 exclusive).
- boost::uniform_real<> uni_dist(0,1);
- boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni(generator, uni_dist);
-
- std::cout.setf(std::ios::fixed);
- // You can now retrieve random numbers from that distribution by means
- // of a STL Generator interface, i.e. calling the generator as a zero-
- // argument function.
- for(int i = 0; i < 10; i++)
- std::cout << uni() << '\n';
-
- /*
- * Change seed to something else.
- *
- * Caveat: std::time(0) is not a very good truly-random seed. When
- * called in rapid succession, it could return the same values, and
- * thus the same random number sequences could ensue. If not the same
- * values are returned, the values differ only slightly in the
- * lowest bits. A linear congruential generator with a small factor
- * wrapped in a uniform_smallint (see experiment) will produce the same
- * values for the first few iterations. This is because uniform_smallint
- * takes only the highest bits of the generator, and the generator itself
- * needs a few iterations to spread the initial entropy from the lowest bits
- * to the whole state.
- */
- generator.seed(static_cast<unsigned int>(std::time(0)));
-
- std::cout << "\nexperiment: roll a die 10 times:\n";
-
- // You can save a generator's state by copy construction.
- base_generator_type saved_generator = generator;
-
- // When calling other functions which take a generator or distribution
- // as a parameter, make sure to always call by reference (or pointer).
- // Calling by value invokes the copy constructor, which means that the
- // sequence of random numbers at the caller is disconnected from the
- // sequence at the callee.
- experiment(generator);
-
- std::cout << "redo the experiment to verify it:\n";
- experiment(saved_generator);
-
- // After that, both generators are equivalent
- assert(generator == saved_generator);
-
- // as a degenerate case, you can set min = max for uniform_int
- boost::uniform_int<> degen_dist(4,4);
- boost::variate_generator<base_generator_type&, boost::uniform_int<> > deg(generator, degen_dist);
- std::cout << deg() << " " << deg() << " " << deg() << std::endl;
-
-#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
- {
- // You can save the generator state for future use. You can read the
- // state back in at any later time using operator>>.
- std::ofstream file("rng.saved", std::ofstream::trunc);
- file << generator;
- }
-#endif
- // Some compilers don't pay attention to std:3.6.1/5 and issue a
- // warning here if "return 0;" is omitted.
- return 0;
-}
Deleted: trunk/libs/random/random_device.cpp
==============================================================================
--- trunk/libs/random/random_device.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,117 +0,0 @@
-/* boost random_device.cpp implementation
- *
- * Copyright Jens Maurer 2000
- * 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/nondet_random.hpp>
-#include <string>
-#include <cassert>
-
-
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-// A definition is required even for integral static constants
-const bool boost::random_device::has_fixed_range;
-const boost::random_device::result_type boost::random_device::min_value;
-const boost::random_device::result_type boost::random_device::max_value;
-#endif
-
-
-#if defined(__linux__) || defined (__FreeBSD__)
-
-// the default is the unlimited capacity device, using some secure hash
-// try "/dev/random" for blocking when the entropy pool has drained
-const char * const boost::random_device::default_token = "/dev/urandom";
-
-/*
- * This uses the POSIX interface for unbuffered reading.
- * Using buffered std::istream would consume entropy which may
- * not actually be used. Entropy is a precious good we avoid
- * wasting.
- */
-
-#if defined(__GNUC__) && defined(_CXXRT_STD_NAME)
-// I have severe difficulty to get the POSIX includes to work with
-// -fhonor-std and Dietmar Kühl's standard C++ library. Hack around that
-// problem for now.
-extern "C" {
-static const int O_RDONLY = 0;
-extern int open(const char *__file, int __oflag, ...);
-extern int read(int __fd, __ptr_t __buf, size_t __nbytes);
-extern int close(int __fd);
-}
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h> // open
-#include <unistd.h> // read, close
-#endif
-
-#include <errno.h> // errno
-#include <string.h> // strerror
-#include <stdexcept> // std::invalid_argument
-
-
-class boost::random_device::impl
-{
-public:
- impl(const std::string & token) : path(token) {
- fd = open(token.c_str(), O_RDONLY);
- if(fd < 0)
- error("cannot open");
- }
-
- ~impl() { if(close(fd) < 0) error("could not close"); }
-
- unsigned int next() {
- unsigned int result;
- long sz = read(fd, reinterpret_cast<char *>(&result), sizeof(result));
- if(sz == -1)
- error("error while reading");
- else if(sz != sizeof(result)) {
- errno = 0;
- error("EOF while reading");
- }
- return result;
- }
-
-private:
- void error(const std::string & msg) {
- throw std::invalid_argument("boost::random_device: " + msg +
- " random-number pseudo-device " + path +
- ": " + strerror(errno));
- }
- const std::string path;
- int fd;
-};
-
-#endif // __linux__ || __FreeBSD__
-
-
-boost::random_device::random_device(const std::string& token)
- : pimpl(new impl(token))
-{
- assert((std::numeric_limits<result_type>::max)() == max_value);
-}
-
-boost::random_device::~random_device()
-{
- // the complete class impl is now visible, so we're safe
- // (see comment in random.hpp)
- delete pimpl;
-}
-
-double boost::random_device::entropy() const
-{
- return 10;
-}
-
-unsigned int boost::random_device::operator()()
-{
- return pimpl->next();
-}
Deleted: trunk/libs/random/random_speed.cpp
==============================================================================
--- trunk/libs/random/random_speed.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,423 +0,0 @@
-/* boost random_speed.cpp performance measurements
- *
- * Copyright Jens Maurer 2000
- * 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 <iostream>
-#include <cstdlib>
-#include <string>
-#include <boost/config.hpp>
-#include <boost/random.hpp>
-#include <boost/progress.hpp>
-#include <boost/shared_ptr.hpp>
-
-/*
- * Configuration Section
- */
-
-// define if your C library supports the non-standard drand48 family
-#define HAVE_DRAND48
-
-// define if you have the original mt19937int.c (with commented out main())
-#undef HAVE_MT19937INT_C
-
-// define if you have the original mt19937ar.c (with commented out main())
-#define HAVE_MT19937AR_C
-
-// set to your CPU frequency in MHz
-static const double cpu_frequency = 3.66 * 1e9;
-
-/*
- * End of Configuration Section
- */
-
-/*
- * 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.
- */
-
-// provides a run-time configurable linear congruential generator, just
-// for comparison
-template<class IntType>
-class linear_congruential
-{
-public:
- typedef IntType result_type;
-
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-
- linear_congruential(IntType x0, IntType a, IntType c, IntType m)
- : _x(x0), _a(a), _c(c), _m(m) { }
- // compiler-generated copy ctor and assignment operator are fine
- void seed(IntType x0, IntType a, IntType c, IntType m)
- { _x = x0; _a = a; _c = c; _m = m; }
- void seed(IntType x0) { _x = x0; }
- result_type operator()() { _x = (_a*_x+_c) % _m; return _x; }
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c == 0 ? 1 : 0; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _m -1; }
-
-private:
- IntType _x, _a, _c, _m;
-};
-
-
-// simplest "random" number generator possible, to check on overhead
-class counting
-{
-public:
- typedef int result_type;
-
- BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
-
- counting() : _x(0) { }
- result_type operator()() { return ++_x; }
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::numeric_limits<result_type>::max)(); }
-
-private:
- int _x;
-};
-
-
-// decoration of variate_generator to make it runtime-exchangeable
-// for speed comparison
-template<class Ret>
-class RandomGenBase
-{
-public:
- virtual Ret operator()() = 0;
- virtual ~RandomGenBase() { }
-};
-
-template<class URNG, class Dist, class Ret = typename Dist::result_type>
-class DynamicRandomGenerator
- : public RandomGenBase<Ret>
-{
-public:
- DynamicRandomGenerator(URNG& urng, const Dist& d) : _rng(urng, d) { }
- Ret operator()() { return _rng(); }
-private:
- boost::variate_generator<URNG&, Dist> _rng;
-};
-
-template<class Ret>
-class GenericRandomGenerator
-{
-public:
- typedef Ret result_type;
-
- GenericRandomGenerator() { };
- void set(boost::shared_ptr<RandomGenBase<Ret> > p) { _p = p; }
- // takes over ownership
- void set(RandomGenBase<Ret> * p) { _p.reset(p); }
- Ret operator()() { return (*_p)(); }
-private:
- boost::shared_ptr<RandomGenBase<Ret> > _p;
-};
-
-
-// start implementation of measuring timing
-
-void show_elapsed(double end, int iter, const std::string & name)
-{
- double usec = end/iter*1e6;
- double cycles = usec * cpu_frequency/1e6;
- std::cout << name << ": "
- << usec*1e3 << " nsec/loop = "
- << cycles << " CPU cycles"
- << std::endl;
-}
-
-#if 0
-template<class RNG>
-void timing(RNG & rng, int iter, const std::string& name)
-{
- // make sure we're not optimizing too much
- volatile typename RNG::result_type tmp;
- boost::timer t;
- for(int i = 0; i < iter; i++)
- tmp = rng();
- show_elapsed(t.elapsed(), iter, name);
-}
-#endif
-
-// overload for using a copy, allows more concise invocation
-template<class RNG>
-void timing(RNG rng, int iter, const std::string& name)
-{
- // make sure we're not optimizing too much
- volatile typename RNG::result_type tmp;
- boost::timer t;
- for(int i = 0; i < iter; i++)
- tmp = rng();
- show_elapsed(t.elapsed(), iter, name);
-}
-
-template<class RNG>
-void timing_sphere(RNG rng, int iter, const std::string & name)
-{
- boost::timer t;
- for(int i = 0; i < iter; i++) {
- // the special return value convention of uniform_on_sphere saves 20% CPU
- const std::vector<double> & tmp = rng();
- (void) tmp[0];
- }
- show_elapsed(t.elapsed(), iter, name);
-}
-
-template<class RNG>
-void run(int iter, const std::string & name, RNG rng)
-{
- std::cout << (RNG::has_fixed_range ? "fixed-range " : "");
- // BCC has trouble with string autoconversion for explicit specializations
-
- // make sure we're not optimizing too much
- volatile typename RNG::result_type tmp;
- boost::timer t;
- for(int i = 0; i < iter; i++)
- tmp = rng();
- show_elapsed(t.elapsed(), iter, name);
-}
-
-#ifdef HAVE_DRAND48
-// requires non-standard C library support for srand48/lrand48
-struct lrand48_ {
- static const bool has_fixed_range = false;
- typedef long result_type;
- lrand48_() {
- using namespace std;
- srand48(1);
- }
- result_type operator()() {
- using namespace std;
- return lrand48();
- }
-};
-#endif
-
-#ifdef HAVE_MT19937INT_C // requires the original mt19937int.c
-extern "C" void sgenrand(unsigned long);
-extern "C" unsigned long genrand();
-
-void run(int iter, const std::string & name, float)
-{
- sgenrand(4357);
- timing(genrand, iter, name, 0u);
-}
-#endif
-
-#ifdef HAVE_MT19937AR_C
-extern "C" {
-void init_genrand(unsigned long s);
-unsigned long genrand_int32(void);
-}
-struct mt19937_c {
- static const bool has_fixed_range = false;
- mt19937_c() {
- init_genrand(5489);
- }
- typedef unsigned long result_type;
- result_type operator()() {
- return genrand_int32();
- }
-};
-#endif
-
-template<class PRNG, class Dist>
-inline boost::variate_generator<PRNG&, Dist> make_gen(PRNG & rng, Dist d)
-{
- return boost::variate_generator<PRNG&, Dist>(rng, d);
-}
-
-template<class Gen>
-void distrib(int iter, const std::string & name, const Gen &)
-{
- Gen gen;
-
- timing(make_gen(gen, boost::uniform_int<>(-2, 4)),
- iter, name + " uniform_int");
-
- timing(make_gen(gen, boost::geometric_distribution<>(0.5)),
- iter, name + " geometric");
-
- timing(make_gen(gen, boost::binomial_distribution<int>(4, 0.8)),
- iter, name + " binomial");
-
- timing(make_gen(gen, boost::poisson_distribution<>(1)),
- iter, name + " poisson");
-
-
- timing(make_gen(gen, boost::uniform_real<>(-5.3, 4.8)),
- iter, name + " uniform_real");
-
- timing(make_gen(gen, boost::triangle_distribution<>(1, 2, 7)),
- iter, name + " triangle");
-
- timing(make_gen(gen, boost::exponential_distribution<>(3)),
- iter, name + " exponential");
-
- timing(make_gen(gen, boost::normal_distribution<>()),
- iter, name + " normal polar");
-
- timing(make_gen(gen, boost::lognormal_distribution<>()),
- iter, name + " lognormal");
-
- timing(make_gen(gen, boost::cauchy_distribution<>()),
- iter, name + " cauchy");
-
- timing(make_gen(gen, boost::cauchy_distribution<>()),
- iter, name + " gamma");
-
- timing_sphere(make_gen(gen, boost::uniform_on_sphere<>(3)),
- iter/10, name + " uniform_on_sphere");
-}
-
-
-template<class URNG, class Dist>
-inline boost::shared_ptr<DynamicRandomGenerator<URNG, Dist> >
-make_dynamic(URNG & rng, const Dist& d)
-{
- typedef DynamicRandomGenerator<URNG, Dist> type;
- return boost::shared_ptr<type>(new type(rng, d));
-}
-
-template<class Gen>
-void distrib_runtime(int iter, const std::string & n, const Gen &)
-{
- std::string name = n + " virtual function ";
- Gen gen;
-
- GenericRandomGenerator<int> g_int;
-
- g_int.set(make_dynamic(gen, boost::uniform_int<>(-2,4)));
- timing(g_int, iter, name + "uniform_int");
-
- g_int.set(make_dynamic(gen, boost::geometric_distribution<>(0.5)));
- timing(g_int, iter, name + "geometric");
-
- g_int.set(make_dynamic(gen, boost::binomial_distribution<>(4, 0.8)));
- timing(g_int, iter, name + "binomial");
-
- g_int.set(make_dynamic(gen, boost::poisson_distribution<>(1)));
- timing(g_int, iter, name + "poisson");
-
- GenericRandomGenerator<double> g;
-
- g.set(make_dynamic(gen, boost::uniform_real<>(-5.3, 4.8)));
- timing(g, iter, name + "uniform_real");
-
- g.set(make_dynamic(gen, boost::triangle_distribution<>(1, 2, 7)));
- timing(g, iter, name + "triangle");
-
- g.set(make_dynamic(gen, boost::exponential_distribution<>(3)));
- timing(g, iter, name + "exponential");
-
- g.set(make_dynamic(gen, boost::normal_distribution<>()));
- timing(g, iter, name + "normal polar");
-
- g.set(make_dynamic(gen, boost::lognormal_distribution<>()));
- timing(g, iter, name + "lognormal");
-
- g.set(make_dynamic(gen, boost::cauchy_distribution<>()));
- timing(g, iter, name + "cauchy");
-
- g.set(make_dynamic(gen, boost::gamma_distribution<>(0.4)));
- timing(g, iter, name + "gamma");
-}
-
-
-int main(int argc, char*argv[])
-{
- if(argc != 2) {
- std::cerr << "usage: " << argv[0] << " iterations" << std::endl;
- return 1;
- }
-
- // okay, it's ugly, but it's only used here
- int iter =
-#ifndef BOOST_NO_STDC_NAMESPACE
- std::
-#endif
- atoi(argv[1]);
-
-#if !defined(BOOST_NO_INT64_T) && \
- !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
- run(iter, "rand48", boost::rand48());
- linear_congruential<boost::uint64_t>
- lcg48(boost::uint64_t(1)<<16 | 0x330e,
- boost::uint64_t(0xDEECE66DUL) | (boost::uint64_t(0x5) << 32), 0xB,
- boost::uint64_t(1)<<48);
- timing(lcg48, iter, "lrand48 run-time");
-#endif
-
-#ifdef HAVE_DRAND48
- // requires non-standard C library support for srand48/lrand48
- run(iter, "lrand48", lrand48_()); // coded for lrand48()
-#endif
-
- run(iter, "minstd_rand0", boost::minstd_rand0());
- run(iter, "minstd_rand", boost::minstd_rand());
- run(iter, "ecuyer combined", boost::ecuyer1988());
- run(iter, "kreutzer1986", boost::kreutzer1986());
- run(iter, "taus88", boost::taus88());
-
- run(iter, "hellekalek1995 (inversive)", boost::hellekalek1995());
-
- run(iter, "mt11213b", boost::mt11213b());
- run(iter, "mt19937", boost::mt19937());
-
- run(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
- run(iter, "lagged_fibonacci1279", boost::lagged_fibonacci1279());
- run(iter, "lagged_fibonacci2281", boost::lagged_fibonacci2281());
- run(iter, "lagged_fibonacci3217", boost::lagged_fibonacci3217());
- run(iter, "lagged_fibonacci4423", boost::lagged_fibonacci4423());
- run(iter, "lagged_fibonacci9689", boost::lagged_fibonacci9689());
- run(iter, "lagged_fibonacci19937", boost::lagged_fibonacci19937());
- run(iter, "lagged_fibonacci23209", boost::lagged_fibonacci23209());
- run(iter, "lagged_fibonacci44497", boost::lagged_fibonacci44497());
-
- run(iter, "subtract_with_carry", boost::random::ranlux_base());
- run(iter, "subtract_with_carry_01", boost::random::ranlux_base_01());
- run(iter, "ranlux3", boost::ranlux3());
- run(iter, "ranlux4", boost::ranlux4());
- run(iter, "ranlux3_01", boost::ranlux3_01());
- run(iter, "ranlux4_01", boost::ranlux4_01());
- run(iter, "ranlux64_3", boost::ranlux3());
- run(iter, "ranlux64_4", boost::ranlux4());
- run(iter, "ranlux64_3_01", boost::ranlux3_01());
- run(iter, "ranlux64_4_01", boost::ranlux4_01());
-
- run(iter, "counting", counting());
-
-#ifdef HAVE_MT19937INT_C
- // requires the original mt19937int.c
- run<float>(iter, "mt19937 original"); // coded for sgenrand()/genrand()
-#endif
-
-#ifdef HAVE_MT19937AR_C
- run(iter, "mt19937ar.c", mt19937_c());
-#endif
-
- distrib(iter, "counting", counting());
- distrib_runtime(iter, "counting", counting());
-
- distrib(iter, "minstd_rand", boost::minstd_rand());
-
- distrib(iter, "kreutzer1986", boost::kreutzer1986());
-
- distrib(iter, "mt19937", boost::mt19937());
-
- distrib(iter, "lagged_fibonacci607", boost::lagged_fibonacci607());
-
- distrib_runtime(iter, "mt19937", boost::mt19937());
-}
Deleted: trunk/libs/random/random_test.cpp
==============================================================================
--- trunk/libs/random/random_test.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,291 +0,0 @@
-/* boost random_test.cpp various tests
- *
- * Copyright Jens Maurer 2000
- * 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$
- */
-
-#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.
- */
-
-/*
- * A few equidistribution tests
- */
-
-// yet to come...
-
-template<class Generator>
-void check_uniform_int(Generator & gen, int iter)
-{
- std::cout << "testing uniform_int(" << (gen.min)() << "," << (gen.max)()
- << ")" << std::endl;
- int range = (gen.max)()-(gen.min)()+1;
- std::vector<int> bucket(range);
- for(int j = 0; j < iter; j++) {
- int result = gen();
- if(result < (gen.min)() || result > (gen.max)())
- std::cerr << " ... delivers " << result << std::endl;
- else
- bucket[result-(gen.min)()]++;
- }
- int sum = 0;
- // use a different variable name "k", because MSVC has broken "for" scoping
- for(int k = 0; k < range; k++)
- sum += bucket[k];
- double avg = static_cast<double>(sum)/range;
- double p = 1 / static_cast<double>(range);
- double threshold = 2*std::sqrt(static_cast<double>(iter)*p*(1-p));
- for(int i = 0; i < range; i++) {
- if(std::fabs(bucket[i] - avg) > threshold) {
- // 95% confidence interval
- std::cout << " ... has bucket[" << i << "] = " << bucket[i]
- << " (distance " << (bucket[i] - avg) << ")"
- << std::endl;
- }
- }
-}
-
-template<class Generator>
-void test_uniform_int(Generator & gen)
-{
- typedef boost::uniform_int<int> int_gen;
-
- // large range => small range (modulo case)
- typedef boost::variate_generator<Generator&, int_gen> level_one;
-
- level_one uint12(gen, int_gen(1,2));
- BOOST_CHECK((uint12.distribution().min)() == 1);
- BOOST_CHECK((uint12.distribution().max)() == 2);
- check_uniform_int(uint12, 100000);
- level_one uint16(gen, int_gen(1,6));
- check_uniform_int(uint16, 100000);
-
- // test chaining to get all cases in operator()
-
- // identity map
- typedef boost::variate_generator<level_one&, int_gen> level_two;
- level_two uint01(uint12, int_gen(0, 1));
- check_uniform_int(uint01, 100000);
-
- // small range => larger range
- level_two uint05(uint12, int_gen(-3, 2));
- check_uniform_int(uint05, 100000);
-
- // small range => larger range
- level_two uint099(uint12, int_gen(0, 99));
- check_uniform_int(uint099, 100000);
-
- // larger => small range, rejection case
- typedef boost::variate_generator<level_two&, int_gen> level_three;
- level_three uint1_4(uint05, int_gen(1, 4));
- check_uniform_int(uint1_4, 100000);
-
- typedef boost::uniform_int<boost::uint8_t> int8_gen;
- typedef boost::variate_generator<Generator&, int8_gen> gen8_t;
-
- gen8_t gen8_03(gen, int8_gen(0, 3));
-
- // use the full range of the type, where the destination
- // range is a power of the source range
- typedef boost::variate_generator<gen8_t, int8_gen> uniform_uint8;
- uniform_uint8 uint8_0255(gen8_03, int8_gen(0, 255));
- check_uniform_int(uint8_0255, 100000);
-
- // use the full range, but a generator whose range is not
- // a root of the destination range.
- gen8_t gen8_02(gen, int8_gen(0, 2));
- uniform_uint8 uint8_0255_2(gen8_02, int8_gen(0, 255));
- check_uniform_int(uint8_0255_2, 100000);
-
- // expand the range to a larger type.
- typedef boost::variate_generator<gen8_t, int_gen> uniform_uint_from8;
- uniform_uint_from8 uint0300(gen8_03, int_gen(0, 300));
- check_uniform_int(uint0300, 100000);
-}
-
-#if defined(BOOST_MSVC) && _MSC_VER < 1300
-
-// These explicit instantiations are necessary, otherwise MSVC does
-// not find the <boost/operators.hpp> inline friends.
-// We ease the typing with a suitable preprocessor macro.
-#define INSTANT(x) \
-template class boost::uniform_smallint<x>; \
-template class boost::uniform_int<x>; \
-template class boost::uniform_real<x>; \
-template class boost::bernoulli_distribution<x>; \
-template class boost::geometric_distribution<x>; \
-template class boost::triangle_distribution<x>; \
-template class boost::exponential_distribution<x>; \
-template class boost::normal_distribution<x>; \
-template class boost::uniform_on_sphere<x>; \
-template class boost::lognormal_distribution<x>;
-
-INSTANT(boost::minstd_rand0)
-INSTANT(boost::minstd_rand)
-INSTANT(boost::ecuyer1988)
-INSTANT(boost::kreutzer1986)
-INSTANT(boost::hellekalek1995)
-INSTANT(boost::mt19937)
-INSTANT(boost::mt11213b)
-
-#undef INSTANT
-#endif
-
-#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
-// testcase by Mario R�tti
-class ruetti_gen
-{
-public:
- ruetti_gen() : state((max)() - 1) {}
- typedef boost::uint64_t result_type;
- result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
- result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<result_type>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }
- result_type operator()() { return state--; }
-private:
- result_type state;
-};
-
-void test_overflow_range()
-{
- ruetti_gen gen;
- boost::variate_generator<ruetti_gen, boost::uniform_int<> >
- rng(gen, boost::uniform_int<>(0, 10));
- for (int i=0;i<10;i++)
- (void) rng();
-}
-#else
-void test_overflow_range()
-{ }
-#endif
-
-template <typename EngineT>
-struct rand_for_random_shuffle
-{
- explicit rand_for_random_shuffle(EngineT &engine)
- : m_engine(engine)
- { }
-
- template <typename IntT>
- IntT operator()(IntT upperBound)
- {
- assert(upperBound > 0);
-
- if (upperBound == 1)
- {
- return 0;
- }
-
- typedef boost::uniform_int<IntT> distribution_type;
- typedef boost::variate_generator<EngineT &, distribution_type> generator_type;
-
- return generator_type(m_engine, distribution_type(0, upperBound - 1))();
- }
-
- EngineT &m_engine;
-
-};
-
-// Test that uniform_int<> can be used with std::random_shuffle
-// Author: Jos Hickson
-void test_random_shuffle()
-{
- typedef boost::uniform_int<> distribution_type;
- typedef boost::variate_generator<boost::mt19937 &, distribution_type> generator_type;
-
- boost::mt19937 engine1(1234);
- boost::mt19937 engine2(1234);
-
- rand_for_random_shuffle<boost::mt19937> referenceRand(engine1);
-
- distribution_type dist(0,10);
- generator_type testRand(engine2, dist);
-
- std::vector<int> referenceVec;
-
- for (int i = 0; i < 200; ++i)
- {
- referenceVec.push_back(i);
- }
-
- std::vector<int> testVec(referenceVec);
-
- std::random_shuffle(referenceVec.begin(), referenceVec.end(), referenceRand);
- std::random_shuffle(testVec.begin(), testVec.end(), testRand);
-
- typedef std::vector<int>::iterator iter_type;
- iter_type theEnd(referenceVec.end());
-
- for (iter_type referenceIter(referenceVec.begin()), testIter(testVec.begin());
- referenceIter != theEnd;
- ++referenceIter, ++testIter)
- {
- BOOST_CHECK_EQUAL(*referenceIter, *testIter);
- }
-}
-
-
-int test_main(int, char*[])
-{
-
-#if !defined(__INTEL_COMPILER) || !defined(_MSC_VER) || __INTEL_COMPILER > 700
- boost::mt19937 mt;
- test_uniform_int(mt);
-
- // bug report from Ken Mahler: This used to lead to an endless loop.
- typedef boost::uniform_int<unsigned int> uint_dist;
- boost::minstd_rand mr;
- boost::variate_generator<boost::minstd_rand, uint_dist> r2(mr,
- uint_dist(0, 0xffffffff));
- r2();
- r2();
-
- // bug report from Fernando Cacciola: This used to lead to an endless loop.
- // also from Douglas Gregor
- boost::variate_generator<boost::minstd_rand, boost::uniform_int<> > x(mr, boost::uniform_int<>(0, 8361));
- (void) x();
-
- // bug report from Alan Stokes and others: this throws an assertion
- boost::variate_generator<boost::minstd_rand, boost::uniform_int<> > y(mr, boost::uniform_int<>(1,1));
- std::cout << "uniform_int(1,1) " << y() << ", " << y() << ", " << y()
- << std::endl;
-
- test_overflow_range();
- test_random_shuffle();
-
- return 0;
-#else
- std::cout << "Intel 7.00 on Win32 loops, so the test is disabled\n";
- return 1;
-#endif
-}
Copied: trunk/libs/random/src/random_device.cpp (from r60077, /trunk/libs/random/random_device.cpp)
==============================================================================
--- /trunk/libs/random/random_device.cpp (original)
+++ trunk/libs/random/src/random_device.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
@@ -1,6 +1,7 @@
/* boost random_device.cpp implementation
*
* Copyright Jens Maurer 2000
+ * Copyright Steven Watanabe 2010
* 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)
@@ -9,6 +10,8 @@
*
*/
+#define BOOST_RANDOM_SOURCE
+
#include <boost/nondet_random.hpp>
#include <string>
#include <cassert>
@@ -22,7 +25,79 @@
#endif
-#if defined(__linux__) || defined (__FreeBSD__)
+#if defined(BOOST_WINDOWS)
+
+#include <windows.h>
+#include <wincrypt.h>
+#include <stdexcept> // std::invalid_argument
+
+const char * const boost::random_device::default_token = "";
+
+class boost::random_device::impl
+{
+public:
+ impl(const std::string & token) : path(token) {
+ std::basic_string<TCHAR> prov_name(token.begin(), token.end());
+ if(prov_name.empty()) prov_name = MS_DEF_PROV;
+
+ TCHAR buffer[80];
+ DWORD type;
+ DWORD len;
+
+ // Find the type of the provider
+ for(DWORD i = 0; ; ++i) {
+ len = sizeof(buffer);
+ if(!CryptEnumProviders(i, NULL, 0, &type, buffer, &len)) {
+ error("Could not find provider");
+ }
+ if(buffer == prov_name) {
+ break;
+ }
+ }
+
+ if(!CryptAcquireContext(&hProv, NULL, prov_name.c_str(), type,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ error("Failed to aqcuire CSP context");
+ }
+ }
+
+ ~impl() {
+ if(!CryptReleaseContext(hProv, 0)) error("could not release CSP");
+ }
+
+ unsigned int next() {
+ unsigned int result;
+
+ if(!CryptGenRandom(hProv, sizeof(result),
+ static_cast<BYTE*>(static_cast<void*>(&result)))) {
+ error("error while reading");
+ }
+
+ return result;
+ }
+
+private:
+ void error(const std::string & msg) {
+ DWORD error_code = GetLastError();
+ TCHAR buf[80];
+ DWORD num = FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ 0,
+ buf,
+ sizeof(buf),
+ NULL);
+
+ throw std::invalid_argument("boost::random_device: " + msg +
+ " random-number pseudo-device " + path +
+ ": " + std::string(&buf[0], &buf[0] + num));
+ }
+ const std::string path;
+ HCRYPTPROV hProv;
+};
+
+#else
// the default is the unlimited capacity device, using some secure hash
// try "/dev/random" for blocking when the entropy pool has drained
@@ -90,8 +165,7 @@
int fd;
};
-#endif // __linux__ || __FreeBSD__
-
+#endif // BOOST_WINDOWS
boost::random_device::random_device(const std::string& token)
: pimpl(new impl(token))
Deleted: trunk/libs/random/statistic_tests.cpp
==============================================================================
--- trunk/libs/random/statistic_tests.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,664 +0,0 @@
-/* statistic_tests.cpp file
- *
- * Copyright Jens Maurer 2000, 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)
- *
- * $Id$
- *
- * Revision history
- */
-
-/*
- * NOTE: This is not part of the official boost submission. It exists
- * only as a collection of ideas.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <string>
-#include <functional>
-#include <math.h> // lgamma is not in namespace std
-#include <vector>
-#include <algorithm>
-
-#include <boost/cstdint.hpp>
-#include <boost/random.hpp>
-
-#include "statistic_tests.hpp"
-#include "integrate.hpp"
-
-
-namespace boost {
-namespace random {
-
-// Wikramaratna 1989 ACORN
-template<class IntType, int k, IntType m, IntType val>
-class additive_congruential
-{
-public:
- typedef IntType result_type;
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const result_type min_value = 0;
- static const result_type max_value = m-1;
-#else
- enum {
- has_fixed_range = true,
- min_value = 0,
- max_value = m-1
- };
-#endif
- template<class InputIterator>
- explicit additive_congruential(InputIterator start) { seed(start); }
- template<class InputIterator>
- void seed(InputIterator start)
- {
- for(int i = 0; i <= k; ++i, ++start)
- values[i] = *start;
- }
-
- result_type operator()()
- {
- for(int i = 1; i <= k; ++i) {
- IntType tmp = values[i-1] + values[i];
- if(tmp >= m)
- tmp -= m;
- values[i] = tmp;
- }
- return values[k];
- }
- result_type validation() const { return val; }
-private:
- IntType values[k+1];
-};
-
-
-template<class IntType, int r, int s, IntType m, IntType val>
-class lagged_fibonacci_int
-{
-public:
- typedef IntType result_type;
-#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
- static const bool has_fixed_range = true;
- static const result_type min_value = 0;
- static const result_type max_value = m-1;
-#else
- enum {
- has_fixed_range = true,
- min_value = 0,
- max_value = m-1
- };
-#endif
- explicit lagged_fibonacci_int(IntType start) { seed(start); }
- template<class Generator>
- explicit lagged_fibonacci_int(Generator & gen) { seed(gen); }
- void seed(IntType start)
- {
- linear_congruential<uint32_t, 299375077, 0, 0, 0> init;
- seed(init);
- }
- template<class Generator>
- void seed(Generator & gen)
- {
- assert(r > s);
- for(int i = 0; i < 607; ++i)
- values[i] = gen();
- current = 0;
- lag = r-s;
- }
-
- result_type operator()()
- {
- result_type tmp = values[current] + values[lag];
- if(tmp >= m)
- tmp -= m;
- values[current] = tmp;
- ++current;
- if(current >= r)
- current = 0;
- ++lag;
- if(lag >= r)
- lag = 0;
- return tmp;
- }
- result_type validation() const { return val; }
-private:
- result_type values[r];
- int current, lag;
-};
-
-} // namespace random
-} // namespace boost
-
-// distributions from Haertel's dissertation
-// (additional parameterizations of the basic templates)
-namespace Haertel {
- typedef boost::random::linear_congruential<boost::uint64_t, 45965, 453816691,
- (boost::uint64_t(1)<<31), 0> LCG_Af2;
- typedef boost::random::linear_congruential<boost::uint64_t, 211936855, 0,
- (boost::uint64_t(1)<<29)-3, 0> LCG_Die1;
- typedef boost::random::linear_congruential<boost::uint32_t, 2824527309u, 0,
- 0, 0> LCG_Fis;
- typedef boost::random::linear_congruential<boost::uint64_t, 950706376u, 0,
- (boost::uint64_t(1)<<31)-1, 0> LCG_FM;
- typedef boost::random::linear_congruential<boost::int32_t, 51081, 0,
- 2147483647, 0> LCG_Hae;
- typedef boost::random::linear_congruential<boost::uint32_t, 69069, 1,
- 0, 0> LCG_VAX;
- typedef boost::random::inversive_congruential<boost::int64_t, 240318, 197,
- 1000081, 0> NLG_Inv1;
- typedef boost::random::inversive_congruential<boost::int64_t, 15707262,
- 13262967, (1<<24)-17, 0> NLG_Inv2;
- typedef boost::random::inversive_congruential<boost::int32_t, 1, 1,
- 2147483647, 0> NLG_Inv4;
- typedef boost::random::inversive_congruential<boost::int32_t, 1, 2,
- 1<<30, 0> NLG_Inv5;
- typedef boost::random::additive_congruential<boost::int32_t, 6,
- (1<<30)-35, 0> MRG_Acorn7;
- typedef boost::random::lagged_fibonacci_int<boost::uint32_t, 607, 273,
- 0, 0> MRG_Fib2;
-
- template<class Gen, class T>
- inline void check_validation(Gen & gen, T value, const std::string & name)
- {
- for(int i = 0; i < 100000-1; ++i)
- gen();
- if(value != gen())
- std::cout << name << ": validation failed" << std::endl;
- }
-
- // we have validation after 100000 steps with Haertel's generators
- template<class Gen, class T>
- void validate(T value, const std::string & name)
- {
- Gen gen(1234567);
- check_validation(gen, value, name);
- }
-
- void validate_all()
- {
- validate<LCG_Af2>(183269031u, "LCG_Af2");
- validate<LCG_Die1>(522319944u, "LCG_Die1");
- validate<LCG_Fis>(-2065162233u, "LCG_Fis");
- validate<LCG_FM>(581815473u, "LCG_FM");
- validate<LCG_Hae>(28931709, "LCG_Hae");
- validate<LCG_VAX>(1508154087u, "LCG_VAX");
- validate<NLG_Inv2>(6666884, "NLG_Inv2");
- validate<NLG_Inv4>(1521640076, "NLG_Inv4");
- validate<NLG_Inv5>(641840839, "NLG_Inv5");
- static const int acorn7_init[]
- = { 1234567, 7654321, 246810, 108642, 13579, 97531, 555555 };
- MRG_Acorn7 acorn7(acorn7_init);
- check_validation(acorn7, 874294697, "MRG_Acorn7");
- validate<MRG_Fib2>(1234567u, "MRG_Fib2");
- }
-} // namespace Haertel
-
-
-
-
-double normal_density(double x)
-{
- const double pi = 3.14159265358979323846;
- return 1/std::sqrt(2*pi) * std::exp(-x*x/2);
-}
-
-namespace std {
-#ifdef _CXXRTCF_H__
- using _CS_swamp::lgamma;
-#elif defined __SGI_STL_PORT
- using ::lgamma;
-#endif
-}
-
-
-class chi_square_density : public std::unary_function<double, double>
-{
-public:
- chi_square_density(int freedom)
- : _exponent( static_cast<double>(freedom)/2-1 ),
- _factor(1/(std::pow(2, _exponent+1) * std::exp(lgamma(_exponent+1))))
- { }
-
- double operator()(double x)
- {
- return _factor*std::pow(x, _exponent)*std::exp(-x/2);
- }
-private:
- double _exponent, _factor;
-};
-
-// computes F(x) or F(y) - F(x)
-class chi_square_probability : public distribution_function<double>
-{
-public:
- chi_square_probability(int freedom) : dens(freedom) {}
- double operator()(double x) { return operator()(0, x); }
- double operator()(double x, double y)
- { return trapezoid(dens, x, y, 1000); }
-private:
- chi_square_density dens;
-};
-
-class uniform_distribution : public distribution_function<double>
-{
-public:
- uniform_distribution(double from, double to) : from(from), to(to)
- { assert(from < to); }
- double operator()(double x)
- {
- if(x < from)
- return 0;
- else if(x > to)
- return 1;
- else
- return (x-from)/(to-from);
- }
- double operator()(double x, double delta)
- { return operator()(x+delta) - operator()(x); }
-private:
- double from, to;
-};
-
-class test_environment;
-
-class test_base
-{
-protected:
- explicit test_base(test_environment & env) : environment(env) { }
- void check(double val) const;
-private:
- test_environment & environment;
-};
-
-class equidistribution_test : test_base
-{
-public:
- equidistribution_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(classes-1), high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "equidistribution: " << std::flush;
- equidistribution_experiment equi(classes);
- uniform_smallint<RNG> uint_linear(rng, 0, classes-1);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(equi, uint_linear, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(equi, uint_linear, n1), 2*n2));
-
- std::cout << " 2D: " << std::flush;
- equidistribution_2d_experiment equi_2d(classes);
- unsigned int root = static_cast<unsigned int>(std::sqrt(double(classes)));
- assert(root * root == classes);
- uniform_smallint<RNG> uint_square(rng, 0, root-1);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(equi_2d, uint_square, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(equi_2d, uint_square, n1), 2*n2));
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class ks_equidistribution_test : test_base
-{
-public:
- ks_equidistribution_test(test_environment & env, unsigned int classes)
- : test_base(env),
- test_distrib_chi_square(kolmogorov_smirnov_probability(5000),
- classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "KS: " << std::flush;
- // generator_reference_t<RNG> gen_ref(rng);
- RNG& gen_ref(rng);
- kolmogorov_experiment ks(n1);
- uniform_distribution ud((rng.min)(), (rng.max)());
- check(run_experiment(test_distrib_chi_square,
- ks_experiment_generator(ks, gen_ref, ud), n2));
- check(run_experiment(test_distrib_chi_square,
- ks_experiment_generator(ks, gen_ref, ud), 2*n2));
- }
-private:
- distribution_experiment test_distrib_chi_square;
-};
-
-class runs_test : test_base
-{
-public:
- runs_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(classes-1), high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "runs: up: " << std::flush;
- runs_experiment<true> r_up(classes);
- // generator_reference_t<RNG> gen_ref(rng);
- RNG& gen_ref(rng);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(r_up, gen_ref, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(r_up, gen_ref, n1), 2*n2));
-
- std::cout << " down: " << std::flush;
- runs_experiment<false> r_down(classes);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(r_down, gen_ref, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(r_down, gen_ref, n1), 2*n2));
-
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class gap_test : test_base
-{
-public:
- gap_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(classes-1), high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "gaps: " << std::flush;
- gap_experiment gap(classes, 0.2, 0.8);
- // generator_reference_t<RNG> gen_ref(rng);
- RNG& gen_ref(rng);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(gap, gen_ref, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(gap, gen_ref, n1), 2*n2));
-
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class poker_test : test_base
-{
-public:
- poker_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(classes-1), high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "poker: " << std::flush;
- poker_experiment poker(8, classes);
- uniform_smallint<RNG> usmall(rng, 0, 7);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(poker, usmall, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(poker, usmall, n1), 2*n2));
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class coupon_collector_test : test_base
-{
-public:
- coupon_collector_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(classes-1), high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "coupon collector: " << std::flush;
- coupon_collector_experiment coupon(5, classes);
-
- uniform_smallint<RNG> usmall(rng, 0, 4);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(coupon, usmall, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(coupon, usmall, n1), 2*n2));
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class permutation_test : test_base
-{
-public:
- permutation_test(test_environment & env, unsigned int classes,
- unsigned int high_classes)
- : test_base(env), classes(classes),
- test_distrib_chi_square(chi_square_probability(fac<int>(classes)-1),
- high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "permutation: " << std::flush;
- permutation_experiment perm(classes);
-
- // generator_reference_t<RNG> gen_ref(rng);
- RNG& gen_ref(rng);
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(perm, gen_ref, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(perm, gen_ref, n1), 2*n2));
- std::cout << std::endl;
- }
-private:
- unsigned int classes;
- distribution_experiment test_distrib_chi_square;
-};
-
-class maximum_test : test_base
-{
-public:
- maximum_test(test_environment & env, unsigned int high_classes)
- : test_base(env),
- test_distrib_chi_square(kolmogorov_smirnov_probability(1000),
- high_classes)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "maximum-of-t: " << std::flush;
- maximum_experiment<RNG> mx(rng, n1, 5);
- check(run_experiment(test_distrib_chi_square, mx, n2));
- check(run_experiment(test_distrib_chi_square, mx, 2*n2));
- std::cout << std::endl;
- }
-private:
- distribution_experiment test_distrib_chi_square;
-};
-
-class birthday_test : test_base
-{
-public:
- birthday_test(test_environment & env)
- : test_base(env)
- { }
-
- template<class RNG>
- void run(RNG & rng, int n1, int n2)
- {
- using namespace boost;
- std::cout << "birthday spacing: " << std::flush;
- uniform_int<RNG> uni(rng, 0, (1<<25)-1);
- birthday_spacing_experiment bsp(4, 512, (1<<25));
- std::cout << run_experiment(bsp, uni, n1);
-#if 0
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(perm, gen_ref, n1), n2));
- check(run_experiment(test_distrib_chi_square,
- experiment_generator(perm, gen_ref, n1), 2*n2));
-#endif
- std::cout << std::endl;
- }
-
-
-};
-
-class test_environment
-{
-public:
- static const int classes = 20;
- explicit test_environment(double confid)
- : confidence(confid),
- confidence_chi_square_quantil(quantil(chi_square_density(classes-1), 0, confidence, 1e-4)),
- test_distrib_chi_square6(chi_square_probability(7-1), classes),
- ksequi_test(*this, classes),
- equi_test(*this, 100, classes),
- rns_test(*this, 7, classes),
- gp_test(*this, 7, classes),
- pk_test(*this, 5, classes),
- cpn_test(*this, 15, classes),
- perm_test(*this, 5, classes),
- max_test(*this, classes),
- bday_test(*this)
- {
- std::cout << "Confidence level: " << confid
- << "; 1-alpha = " << (1-confid)
- << "; chi_square(" << (classes-1)
- << ", " << confidence_chi_square_quantil
- << ") = "
- << chi_square_probability(classes-1)(0, confidence_chi_square_quantil)
- << std::endl;
- }
-
- bool check_confidence(double val, double chi_square_conf) const
- {
- std::cout << val;
- bool result = (val <= chi_square_conf);
- if(!result) {
- std::cout << "* [";
- double prob = (val > 10*chi_square_conf ? 1 :
- chi_square_probability(classes-1)(0, val));
- std::cout << (1-prob) << "]";
- }
- std::cout << " " << std::flush;
- return result;
- }
-
- bool check(double chi_square_value) const
- {
- return check_confidence(chi_square_value, confidence_chi_square_quantil);
- }
-
- template<class RNG>
- void run_test(const std::string & name)
- {
- using namespace boost;
-
- std::cout << "Running tests on " << name << std::endl;
-
- RNG rng(1234567);
- typedef boost::uniform_01<RNG> UGen;
-
-#if 1
- ksequi_test.run(rng, 5000, 250);
- equi_test.run(rng, 5000, 250);
- rns_test.run(rng, 100000, 250);
- gp_test.run(rng, 10000, 250);
- pk_test.run(rng, 5000, 250);
- cpn_test.run(rng, 500, 250);
- perm_test.run(rng, 1200, 250);
- max_test.run(rng, 1000, 250);
-#endif
- bday_test.run(rng, 1000, 150);
-
- std::cout << std::endl;
- }
-
-private:
- double confidence;
- double confidence_chi_square_quantil;
- distribution_experiment test_distrib_chi_square6;
- ks_equidistribution_test ksequi_test;
- equidistribution_test equi_test;
- runs_test rns_test;
- gap_test gp_test;
- poker_test pk_test;
- coupon_collector_test cpn_test;
- permutation_test perm_test;
- maximum_test max_test;
- birthday_test bday_test;
-};
-
-void test_base::check(double val) const
-{
- environment.check(val);
-}
-
-void print_ks_table()
-{
- std::cout.setf(std::ios::fixed);
- std::cout.precision(5);
- static const double all_p[] = { 0.01, 0.05, 0.25, 0.5, 0.75, 0.95, 0.99 };
- for(int n = 0; n <= 10000; (n < 55 ? ++n : n *= 10)) {
- std::cout << std::setw(4) << n << " ";
- for(unsigned int i = 0; i < sizeof(all_p)/sizeof(all_p[0]); ++i) {
- std::cout << std::setw(8)
- << (n == 0 ? all_p[i] :
- invert_monotone_inc(kolmogorov_smirnov_probability(n), all_p[i], 0, 10))
- << " ";
- }
- std::cout << std::endl;
- }
-}
-
-int main()
-{
- // Haertel::validate_all();
- test_environment env(0.99);
- env.run_test<boost::minstd_rand>("minstd_rand");
- env.run_test<boost::mt19937>("mt19937");
- env.run_test<Haertel::LCG_Af2>("LCG_Af2");
- env.run_test<Haertel::LCG_Die1>("LCG_Die1");
- env.run_test<Haertel::LCG_Fis>("LCG_Fis");
- env.run_test<Haertel::LCG_FM>("LCG_FM");
- env.run_test<Haertel::LCG_Hae>("LCG_Hae");
- env.run_test<Haertel::LCG_VAX>("LCG_VAX");
- env.run_test<Haertel::NLG_Inv1>("NLG_Inv1");
- env.run_test<Haertel::NLG_Inv2>("NLG_Inv2");
- env.run_test<Haertel::NLG_Inv4>("NLG_Inv4");
- env.run_test<Haertel::NLG_Inv5>("NLG_Inv5");
-}
Deleted: trunk/libs/random/statistic_tests.hpp
==============================================================================
--- trunk/libs/random/statistic_tests.hpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,638 +0,0 @@
-/* statistic_tests.hpp header file
- *
- * Copyright Jens Maurer 2000
- * 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$
- *
- */
-
-#ifndef STATISTIC_TESTS_HPP
-#define STATISTIC_TESTS_HPP
-
-#include <stdexcept>
-#include <iterator>
-#include <vector>
-#include <boost/limits.hpp>
-#include <algorithm>
-#include <cmath>
-
-#include <boost/random.hpp>
-#include <boost/config.hpp>
-
-
-#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
-namespace std
-{
- inline double pow(double a, double b) { return ::pow(a,b); }
- inline double ceil(double x) { return ::ceil(x); }
-} // namespace std
-#endif
-
-
-template<class T>
-inline T fac(int k)
-{
- T result = 1;
- for(T i = 2; i <= k; ++i)
- result *= i;
- return result;
-}
-
-template<class T>
-T binomial(int n, int k)
-{
- if(k < n/2)
- k = n-k;
- T result = 1;
- for(int i = k+1; i<= n; ++i)
- result *= i;
- return result / fac<T>(n-k);
-}
-
-template<class T>
-T stirling2(int n, int m)
-{
- T sum = 0;
- for(int k = 0; k <= m; ++k)
- sum += binomial<T>(m, k) * std::pow(double(k), n) *
- ( (m-k)%2 == 0 ? 1 : -1);
- return sum / fac<T>(m);
-}
-
-/*
- * Experiments which create an empirical distribution in classes,
- * suitable for the chi-square test.
- */
-// std::floor(gen() * classes)
-
-class experiment_base
-{
-public:
- experiment_base(int cls) : _classes(cls) { }
- unsigned int classes() const { return _classes; }
-protected:
- unsigned int _classes;
-};
-
-class equidistribution_experiment : public experiment_base
-{
-public:
- explicit equidistribution_experiment(unsigned int classes)
- : experiment_base(classes) { }
-
- template<class NumberGenerator, class Counter>
- void run(NumberGenerator f, Counter & count, int n) const
- {
- assert((f.min)() == 0 &&
- static_cast<unsigned int>((f.max)()) == classes()-1);
- for(int i = 0; i < n; ++i)
- count(f());
- }
- double probability(int i) const { return 1.0/classes(); }
-};
-
-// two-dimensional equidistribution experiment
-class equidistribution_2d_experiment : public equidistribution_experiment
-{
-public:
- explicit equidistribution_2d_experiment(unsigned int classes)
- : equidistribution_experiment(classes) { }
-
- template<class NumberGenerator, class Counter>
- void run(NumberGenerator f, Counter & count, int n) const
- {
- unsigned int range = (f.max)()+1;
- assert((f.min)() == 0 && range*range == classes());
- for(int i = 0; i < n; ++i) {
- int y1 = f();
- int y2 = f();
- count(y1 + range * y2);
- }
- }
-};
-
-// distribution experiment: assume a probability density and
-// count events so that an equidistribution results.
-class distribution_experiment : public equidistribution_experiment
-{
-public:
- template<class UnaryFunction>
- distribution_experiment(UnaryFunction probability , unsigned int classes)
- : equidistribution_experiment(classes), limit(classes)
- {
- for(unsigned int i = 0; i < classes-1; ++i)
- limit[i] = invert_monotone_inc(probability, (i+1)*0.05, 0, 1000);
- limit[classes-1] = std::numeric_limits<double>::infinity();
- if(limit[classes-1] < (std::numeric_limits<double>::max)())
- limit[classes-1] = (std::numeric_limits<double>::max)();
-#if 0
- std::cout << __PRETTY_FUNCTION__ << ": ";
- for(unsigned int i = 0; i < classes; ++i)
- std::cout << limit[i] << " ";
- std::cout << std::endl;
-#endif
- }
-
- template<class NumberGenerator, class Counter>
- void run(NumberGenerator f, Counter & count, int n) const
- {
- for(int i = 0; i < n; ++i) {
- limits_type::const_iterator it =
- std::lower_bound(limit.begin(), limit.end(), f());
- count(it-limit.begin());
- }
- }
-private:
- typedef std::vector<double> limits_type;
- limits_type limit;
-};
-
-// runs-up/runs-down experiment
-template<bool up>
-class runs_experiment : public experiment_base
-{
-public:
- explicit runs_experiment(unsigned int classes) : experiment_base(classes) { }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- result_type init = (up ? (f.min)() : (f.max)());
- result_type previous = init;
- unsigned int length = 0;
- for(int i = 0; i < n; ++i) {
- result_type val = f();
- if(up ? previous <= val : previous >= val) {
- previous = val;
- ++length;
- } else {
- count((std::min)(length, classes())-1);
- length = 0;
- previous = init;
- // don't use this value, so that runs are independent
- }
- }
- }
- double probability(unsigned int r) const
- {
- if(r == classes()-1)
- return 1.0/fac<double>(classes());
- else
- return static_cast<double>(r+1)/fac<double>(r+2);
- }
-};
-
-// gap length experiment
-class gap_experiment : public experiment_base
-{
-public:
- gap_experiment(unsigned int classes, double alpha, double beta)
- : experiment_base(classes), alpha(alpha), beta(beta) { }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- double range = (f.max)() - (f.min)() + 1.0;
- result_type low = static_cast<result_type>(alpha * range);
- result_type high = static_cast<result_type>(beta * range);
- unsigned int length = 0;
- for(int i = 0; i < n; ) {
- result_type value = f() - (f.min)();
- if(value < low || value > high)
- ++length;
- else {
- count((std::min)(length, classes()-1));
- length = 0;
- ++i;
- }
- }
- }
- double probability(unsigned int r) const
- {
- double p = beta-alpha;
- if(r == classes()-1)
- return std::pow(1-p, static_cast<double>(r));
- else
- return p * std::pow(1-p, static_cast<double>(r));
- }
-private:
- double alpha, beta;
-};
-
-// poker experiment
-class poker_experiment : public experiment_base
-{
-public:
- poker_experiment(unsigned int d, unsigned int k)
- : experiment_base(k), range(d)
- {
- assert(range > 1);
- }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- assert(std::numeric_limits<result_type>::is_integer);
- assert((f.min)() == 0);
- assert((f.max)() == static_cast<result_type>(range-1));
- std::vector<result_type> v(classes());
- for(int i = 0; i < n; ++i) {
- for(unsigned int j = 0; j < classes(); ++j)
- v[j] = f();
- std::sort(v.begin(), v.end());
- result_type prev = v[0];
- int r = 1; // count different values in v
- for(unsigned int i = 1; i < classes(); ++i) {
- if(prev != v[i]) {
- prev = v[i];
- ++r;
- }
- }
- count(r-1);
- }
- }
-
- double probability(unsigned int r) const
- {
- ++r; // transform to 1 <= r <= 5
- double result = range;
- for(unsigned int i = 1; i < r; ++i)
- result *= range-i;
- return result / std::pow(range, static_cast<double>(classes())) *
- stirling2<double>(classes(), r);
- }
-private:
- unsigned int range;
-};
-
-// coupon collector experiment
-class coupon_collector_experiment : public experiment_base
-{
-public:
- coupon_collector_experiment(unsigned int d, unsigned int cls)
- : experiment_base(cls), d(d)
- {
- assert(d > 1);
- }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- assert(std::numeric_limits<result_type>::is_integer);
- assert((f.min)() == 0);
- assert((f.max)() == static_cast<result_type>(d-1));
- std::vector<bool> occurs(d);
- for(int i = 0; i < n; ++i) {
- occurs.assign(d, false);
- unsigned int r = 0; // length of current sequence
- int q = 0; // number of non-duplicates in current set
- for(;;) {
- result_type val = f();
- ++r;
- if(!occurs[val]) { // new set element
- occurs[val] = true;
- ++q;
- if(q == d)
- break; // one complete set
- }
- }
- count((std::min)(r-d, classes()-1));
- }
- }
- double probability(unsigned int r) const
- {
- if(r == classes()-1)
- return 1-fac<double>(d)/std::pow(d, static_cast<double>(d+classes()-2))*
- stirling2<double>(d+classes()-2, d);
- else
- return fac<double>(d)/std::pow(d, static_cast<double>(d+r)) *
- stirling2<double>(d+r-1, d-1);
- }
-private:
- int d;
-};
-
-// permutation test
-class permutation_experiment : public equidistribution_experiment
-{
-public:
- permutation_experiment(unsigned int t)
- : equidistribution_experiment(fac<int>(t)), t(t)
- {
- assert(t > 1);
- }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- std::vector<result_type> v(t);
- for(int i = 0; i < n; ++i) {
- std::generate_n(v.begin(), t, f);
- int x = 0;
- for(int r = t-1; r > 0; r--) {
- typename std::vector<result_type>::iterator it =
- std::max_element(v.begin(), v.begin()+r+1);
- x = (r+1)*x + (it-v.begin());
- std::iter_swap(it, v.begin()+r);
- }
- count(x);
- }
- }
-private:
- int t;
-};
-
-// birthday spacing experiment test
-class birthday_spacing_experiment : public experiment_base
-{
-public:
- birthday_spacing_experiment(unsigned int d, int n, int m)
- : experiment_base(d), n(n), m(m)
- {
- }
-
- template<class UniformRandomNumberGenerator, class Counter>
- void run(UniformRandomNumberGenerator f, Counter & count, int n_total) const
- {
- typedef typename UniformRandomNumberGenerator::result_type result_type;
- assert(std::numeric_limits<result_type>::is_integer);
- assert((f.min)() == 0);
- assert((f.max)() == static_cast<result_type>(m-1));
-
- for(int j = 0; j < n_total; j++) {
- std::vector<result_type> v(n);
- std::generate_n(v.begin(), n, f);
- std::sort(v.begin(), v.end());
- std::vector<result_type> spacing(n);
- for(int i = 0; i < n-1; i++)
- spacing[i] = v[i+1]-v[i];
- spacing[n-1] = v[0] + m - v[n-1];
- std::sort(spacing.begin(), spacing.end());
- unsigned int k = 0;
- for(int i = 0; i < n-1; ++i) {
- if(spacing[i] == spacing[i+1])
- ++k;
- }
- count((std::min)(k, classes()-1));
- }
- }
-
- double probability(unsigned int r) const
- {
- assert(classes() == 4);
- assert(m == (1<<25));
- assert(n == 512);
- static const double prob[] = { 0.368801577, 0.369035243, 0.183471182,
- 0.078691997 };
- return prob[r];
- }
-private:
- int n, m;
-};
-/*
- * Misc. helper functions.
- */
-
-template<class Float>
-struct distribution_function
-{
- typedef Float result_type;
- typedef Float argument_type;
- typedef Float first_argument_type;
- typedef Float second_argument_type;
-};
-
-// computes P(K_n <= t) or P(t1 <= K_n <= t2). See Knuth, 3.3.1
-class kolmogorov_smirnov_probability : public distribution_function<double>
-{
-public:
- kolmogorov_smirnov_probability(int n)
- : approx(n > 50), n(n), sqrt_n(std::sqrt(double(n)))
- {
- if(!approx)
- n_n = std::pow(static_cast<double>(n), n);
- }
-
- double operator()(double t) const
- {
- if(approx) {
- return 1-std::exp(-2*t*t)*(1-2.0/3.0*t/sqrt_n);
- } else {
- t *= sqrt_n;
- double sum = 0;
- for(int k = static_cast<int>(std::ceil(t)); k <= n; k++)
- sum += binomial<double>(n, k) * std::pow(k-t, k) *
- std::pow(t+n-k, n-k-1);
- return 1 - t/n_n * sum;
- }
- }
- double operator()(double t1, double t2) const
- { return operator()(t2) - operator()(t1); }
-
-private:
- bool approx;
- int n;
- double sqrt_n;
- double n_n;
-};
-
-/*
- * Experiments for generators with continuous distribution functions
- */
-class kolmogorov_experiment
-{
-public:
- kolmogorov_experiment(int n) : n(n), ksp(n) { }
- template<class NumberGenerator, class Distribution>
- double run(NumberGenerator gen, Distribution distrib) const
- {
- const int m = n;
- typedef std::vector<double> saved_temp;
- saved_temp a(m,1.0), b(m,0);
- std::vector<int> c(m,0);
- for(int i = 0; i < n; ++i) {
- double val = gen();
- double y = distrib(val);
- int k = static_cast<int>(std::floor(m*y));
- if(k >= m)
- --k; // should not happen
- a[k] = (std::min)(a[k], y);
- b[k] = (std::max)(b[k], y);
- ++c[k];
- }
- double kplus = 0, kminus = 0;
- int j = 0;
- for(int k = 0; k < m; ++k) {
- if(c[k] > 0) {
- kminus = (std::max)(kminus, a[k]-j/static_cast<double>(n));
- j += c[k];
- kplus = (std::max)(kplus, j/static_cast<double>(n) - b[k]);
- }
- }
- kplus *= std::sqrt(double(n));
- kminus *= std::sqrt(double(n));
- // std::cout << "k+ " << kplus << " k- " << kminus << std::endl;
- return kplus;
- }
- double probability(double x) const
- {
- return ksp(x);
- }
-private:
- int n;
- kolmogorov_smirnov_probability ksp;
-};
-
-// maximum-of-t test (KS-based)
-template<class UniformRandomNumberGenerator>
-class maximum_experiment
-{
-public:
- typedef UniformRandomNumberGenerator base_type;
- maximum_experiment(base_type & f, int n, int t) : f(f), ke(n), t(t)
- { }
-
- double operator()() const
- {
- double res = ke.run(generator(f, t),
- std::bind2nd(std::ptr_fun(static_cast<double (*)(double, double)>(&std::pow)), t));
- return res;
- }
-
-private:
- struct generator {
- generator(base_type & f, int t) : f(f), t(t) { }
- double operator()()
- {
- double mx = f();
- for(int i = 1; i < t; ++i)
- mx = (std::max)(mx, f());
- return mx;
- }
- private:
- boost::uniform_01<base_type> f;
- int t;
- };
- base_type & f;
- kolmogorov_experiment ke;
- int t;
-};
-
-// compute a chi-square value for the distribution approximation error
-template<class ForwardIterator, class UnaryFunction>
-typename UnaryFunction::result_type
-chi_square_value(ForwardIterator first, ForwardIterator last,
- UnaryFunction probability)
-{
- typedef std::iterator_traits<ForwardIterator> iter_traits;
- typedef typename iter_traits::value_type counter_type;
- typedef typename UnaryFunction::result_type result_type;
- unsigned int classes = std::distance(first, last);
- result_type sum = 0;
- counter_type n = 0;
- for(unsigned int i = 0; i < classes; ++first, ++i) {
- counter_type count = *first;
- n += count;
- sum += (count/probability(i)) * count; // avoid overflow
- }
-#if 0
- for(unsigned int i = 0; i < classes; ++i) {
- // std::cout << (n*probability(i)) << " ";
- if(n * probability(i) < 5)
- std::cerr << "Not enough test runs for slot " << i
- << " p=" << probability(i) << ", n=" << n
- << std::endl;
- }
-#endif
- // std::cout << std::endl;
- // throw std::invalid_argument("not enough test runs");
-
- return sum/n - n;
-}
-template<class RandomAccessContainer>
-class generic_counter
-{
-public:
- explicit generic_counter(unsigned int classes) : container(classes, 0) { }
- void operator()(int i)
- {
- assert(i >= 0);
- assert(static_cast<unsigned int>(i) < container.size());
- ++container[i];
- }
- typename RandomAccessContainer::const_iterator begin() const
- { return container.begin(); }
- typename RandomAccessContainer::const_iterator end() const
- { return container.end(); }
-
-private:
- RandomAccessContainer container;
-};
-
-// chi_square test
-template<class Experiment, class Generator>
-double run_experiment(const Experiment & experiment, Generator gen, int n)
-{
- generic_counter<std::vector<int> > v(experiment.classes());
- experiment.run(gen, v, n);
- return chi_square_value(v.begin(), v.end(),
- std::bind1st(std::mem_fun_ref(&Experiment::probability),
- experiment));
-}
-
-// number generator with experiment results (for nesting)
-template<class Experiment, class Generator>
-class experiment_generator_t
-{
-public:
- experiment_generator_t(const Experiment & exper, Generator & gen, int n)
- : experiment(exper), generator(gen), n(n) { }
- double operator()() { return run_experiment(experiment, generator, n); }
-private:
- const Experiment & experiment;
- Generator & generator;
- int n;
-};
-
-template<class Experiment, class Generator>
-experiment_generator_t<Experiment, Generator>
-experiment_generator(const Experiment & e, Generator & gen, int n)
-{
- return experiment_generator_t<Experiment, Generator>(e, gen, n);
-}
-
-
-template<class Experiment, class Generator, class Distribution>
-class ks_experiment_generator_t
-{
-public:
- ks_experiment_generator_t(const Experiment & exper, Generator & gen,
- const Distribution & distrib)
- : experiment(exper), generator(gen), distribution(distrib) { }
- double operator()() { return experiment.run(generator, distribution); }
-private:
- const Experiment & experiment;
- Generator & generator;
- Distribution distribution;
-};
-
-template<class Experiment, class Generator, class Distribution>
-ks_experiment_generator_t<Experiment, Generator, Distribution>
-ks_experiment_generator(const Experiment & e, Generator & gen,
- const Distribution & distrib)
-{
- return ks_experiment_generator_t<Experiment, Generator, Distribution>
- (e, gen, distrib);
-}
-
-
-#endif /* STATISTIC_TESTS_HPP */
-
Modified: trunk/libs/random/test/Jamfile.v2
==============================================================================
--- trunk/libs/random/test/Jamfile.v2 (original)
+++ trunk/libs/random/test/Jamfile.v2 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
@@ -7,12 +7,10 @@
# bring in rules for testing
import testing ;
-project
- : source-location ..
- ;
+project /boost/random/test ;
run random_test.cpp ;
-run random_demo.cpp ;
+run ../example/random_demo.cpp ;
run validate.cpp ;
local all-urngs =
Deleted: trunk/libs/random/validate.cpp
==============================================================================
--- trunk/libs/random/validate.cpp 2010-03-05 14:12:45 EST (Fri, 05 Mar 2010)
+++ (empty file)
@@ -1,131 +0,0 @@
-/* boost validate.cpp
- *
- * Copyright Jens Maurer 2000
- * 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$
- */
-
-#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; }
-
-// validation by experiment from mt19937.c
-bool check(unsigned long x, const boost::mt19937&) { return x == 4123659995U; }
-
-// validation values from the publications
-bool check(int x, const boost::minstd_rand0&) { return x == 1043618065; }
-
-// validation values from the publications
-bool check(int x, const boost::minstd_rand&) { return x == 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; }
-#endif
-
-// ????
-bool check(unsigned long x, const boost::taus88&) { return x == 3535848941U; }
-
-// ????
-bool check(int x, const boost::ecuyer1988&) { return x == 2060321752; }
-
-// validation by experiment from Harry Erwin's generator.h (private e-mail)
-bool check(unsigned int x, const boost::kreutzer1986&) { return x == 139726; }
-
-bool check(double x, const boost::lagged_fibonacci607&) { return std::abs(x-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; }
-
-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; }
-
-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; }
-
-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());
-#endif
- validate("minstd_rand", minstd_rand());
- validate("minstd_rand0", minstd_rand0());
- validate("ecuyer combined", ecuyer1988());
- validate("mt11213b", mt11213b());
- validate("mt19937", mt19937());
- validate("kreutzer1986", kreutzer1986());
- 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("taus88", taus88());
- validate("lagged_fibonacci607", lagged_fibonacci607());
-}
-
-int test_main(int, char*[])
-{
- validate_all();
- 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