Merge branch 'master' of https://github.com/yandex/ClickHouse into CLICKHOUSE-2720

This commit is contained in:
Ivan Blinkov 2017-09-12 18:26:53 +03:00
commit b32445ca8b
416 changed files with 6504 additions and 18773 deletions

View File

@ -27,16 +27,16 @@ endif ()
cmake_policy (SET CMP0014 OLD) # Ignore warning about CMakeLists.txt in each directory cmake_policy (SET CMP0014 OLD) # Ignore warning about CMakeLists.txt in each directory
cmake_policy (SET CMP0012 NEW) # Don't dereference TRUE and FALSE cmake_policy (SET CMP0012 NEW) # Don't dereference TRUE and FALSE
find_program (CCACHE_FOUND ccache) # Write compile_commands.json
if (CCACHE_FOUND AND NOT CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache" AND NOT CMAKE_CXX_COMPILER MATCHES "ccache") set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
set_property (GLOBAL PROPERTY RULE_LAUNCH_COMPILE "ccache")
set_property (GLOBAL PROPERTY RULE_LAUNCH_LINK "ccache") include (cmake/find_ccache.cmake)
endif ()
if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None") if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None")
message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = RELWITHDEBINFO") message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = RELWITHDEBINFO")
set (CMAKE_BUILD_TYPE "RELWITHDEBINFO") set (CMAKE_BUILD_TYPE "RELWITHDEBINFO")
endif () endif ()
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
message (STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} ) message (STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
# ASan - build type with address sanitizer # ASan - build type with address sanitizer
@ -100,6 +100,13 @@ if (ARCHNATIVE)
set (COMPILER_FLAGS "${COMPILER_FLAGS} -march=native") set (COMPILER_FLAGS "${COMPILER_FLAGS} -march=native")
endif () endif ()
option (USE_LIBCXX "Use libc++ and libc++abi instead of libstdc++ (only make sense on Linux with Clang)" OFF)
if (USE_LIBCXX)
set (COMPILER_FLAGS "${COMPILER_FLAGS} -pthread") # NOTE: Why this is not the default and why this is needed only with libc++?
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_LIBCPP_DEBUG=1") # More checks in debug build.
endif ()
set (CMAKE_BUILD_COLOR_MAKEFILE ON) set (CMAKE_BUILD_COLOR_MAKEFILE ON)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} -std=gnu++1z ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} -std=gnu++1z ${PLATFORM_EXTRA_CXX_FLAG} -fno-omit-frame-pointer ${COMMON_WARNING_FLAGS} ${CXX_WARNING_FLAGS} ${GLIBC_COMPATIBILITY_COMPILE_FLAGS}")
#set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") #set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
@ -112,11 +119,16 @@ set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3")
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline") set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g3 -ggdb3 -fno-inline")
if (NOT APPLE AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM MATCHES "FreeBSD")) if (NOT APPLE AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_SYSTEM MATCHES "FreeBSD"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
endif () endif ()
if (NOT APPLE) if (NOT APPLE)
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GLIBC_COMPATIBILITY_LINK_FLAGS} ${CXX11_ABI_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GLIBC_COMPATIBILITY_LINK_FLAGS} ${CXX11_ABI_FLAGS}")
if (USE_LIBCXX AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
link_libraries (-Wl,-Bstatic -stdlib=libc++ c++ c++abi -Wl,-Bdynamic)
endif ()
endif () endif ()
include (cmake/test_compiler.cmake) include (cmake/test_compiler.cmake)
@ -145,6 +157,18 @@ set (CMAKE_C_FLAGS_MSAN "${CMAKE_C_FLAGS_MSAN} ${SAN_FLAGS}
set (CMAKE_CXX_FLAGS_TSAN "${CMAKE_CXX_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread") set (CMAKE_CXX_FLAGS_TSAN "${CMAKE_CXX_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread")
set (CMAKE_C_FLAGS_TSAN "${CMAKE_C_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread") set (CMAKE_C_FLAGS_TSAN "${CMAKE_C_FLAGS_TSAN} ${SAN_FLAGS} -fsanitize=thread")
# Using "include-what-you-use" tool.
option (USE_INCLUDE_WHAT_YOU_USE "Use 'include-what-you-use' tool" OFF)
if (USE_INCLUDE_WHAT_YOU_USE)
find_program(IWYU_PATH NAMES include-what-you-use iwyu)
if (NOT IWYU_PATH)
message(FATAL_ERROR "Could not find the program include-what-you-use")
endif()
if (${CMAKE_VERSION} VERSION_LESS "3.3.0")
message(FATAL_ERROR "include-what-you-use requires CMake version at least 3.3.")
endif()
endif ()
# Flags for test coverage # Flags for test coverage
if (TEST_COVERAGE) if (TEST_COVERAGE)
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -DIS_DEBUG") set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -DIS_DEBUG")
@ -173,7 +197,7 @@ if (UNBUNDLED OR NOT (CMAKE_SYSTEM MATCHES "Linux" OR APPLE) OR ARCH_32)
option (NO_WERROR "Disable -Werror compiler option" ON) option (NO_WERROR "Disable -Werror compiler option" ON)
endif () endif ()
message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE} ; USE_STATIC_LIBRARIES=${USE_STATIC_LIBRARIES} MAKE_STATIC_LIBRARIES=${MAKE_STATIC_LIBRARIES} UNBUNDLED=${UNBUNDLED} CCACHE=${CCACHE_FOUND}") message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE} ; USE_STATIC_LIBRARIES=${USE_STATIC_LIBRARIES} MAKE_STATIC_LIBRARIES=${MAKE_STATIC_LIBRARIES} UNBUNDLED=${UNBUNDLED} CCACHE=${CCACHE_FOUND} ${CCACHE_VERSION}")
include(GNUInstallDirs) include(GNUInstallDirs)
@ -211,8 +235,8 @@ include (libs/libmysqlxx/cmake/find_mysqlclient.cmake)
include (libs/libdaemon/cmake/find_unwind.cmake) include (libs/libdaemon/cmake/find_unwind.cmake)
set (FULL_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}") set (FULL_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
set (FULL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}") set (FULL_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
message (STATUS "C_FLAGS = ${FULL_C_FLAGS}") message (STATUS "C_FLAGS = ${FULL_C_FLAGS}")
message (STATUS "CXX_FLAGS = ${FULL_CXX_FLAGS}") message (STATUS "CXX_FLAGS = ${FULL_CXX_FLAGS}")
message (STATUS "LINK_FLAGS = ${CMAKE_EXE_LINKER_FLAGS}") message (STATUS "LINK_FLAGS = ${CMAKE_EXE_LINKER_FLAGS}")

14
cmake/find_ccache.cmake Normal file
View File

@ -0,0 +1,14 @@
find_program (CCACHE_FOUND ccache)
if (CCACHE_FOUND AND NOT CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache" AND NOT CMAKE_CXX_COMPILER MATCHES "ccache")
execute_process(COMMAND ${CCACHE_FOUND} "-V" OUTPUT_VARIABLE CCACHE_VERSION)
string(REGEX REPLACE "ccache version ([0-9\\.]+).*" "\\1" CCACHE_VERSION ${CCACHE_VERSION} )
if (CCACHE_VERSION VERSION_GREATER "3.2.0" OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
#message(STATUS "Using ${CCACHE_FOUND} ${CCACHE_VERSION}")
set_property (GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_FOUND})
set_property (GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_FOUND})
else ()
message(STATUS "Not using ${CCACHE_FOUND} ${CCACHE_VERSION} bug: https://bugzilla.samba.org/show_bug.cgi?id=8118")
endif ()
endif ()

View File

@ -4,3 +4,4 @@ set(CITYHASH_CONTRIB_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/libcityhash/in
set(COMMON_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/libs/libcommon/include ${ClickHouse_BINARY_DIR}/libs/libcommon/include) set(COMMON_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/libs/libcommon/include ${ClickHouse_BINARY_DIR}/libs/libcommon/include)
set(DBMS_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/dbms/src ${ClickHouse_BINARY_DIR}/dbms/src) set(DBMS_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/dbms/src ${ClickHouse_BINARY_DIR}/dbms/src)
set(DOUBLE_CONVERSION_CONTRIB_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/libdouble-conversion) set(DOUBLE_CONVERSION_CONTRIB_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/libdouble-conversion)
set(PCG_RANDOM_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/libpcg-random/include)

View File

@ -1,91 +0,0 @@
/* boost random.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/random for documentation.
*
* $Id$
*
* Revision history
* 2000-02-18 portability fixes (thanks to Beman Dawes)
* 2000-02-21 shuffle_output, inversive_congruential_schrage,
* generator_iterator, uniform_smallint
* 2000-02-23 generic modulus arithmetic helper, removed *_schrage classes,
* implemented Streamable and EqualityComparable concepts for
* generators, added Bernoulli distribution and Box-Muller
* transform
* 2000-03-01 cauchy, lognormal, triangle distributions; fixed
* uniform_smallint; renamed gaussian to normal distribution
* 2000-03-05 implemented iterator syntax for distribution functions
* 2000-04-21 removed some optimizations for better BCC/MSVC compatibility
* 2000-05-10 adapted to BCC and MSVC
* 2000-06-13 incorporated review results
* 2000-07-06 moved basic templates from namespace detail to random
* 2000-09-23 warning removals and int64 fixes (Ed Brey)
* 2000-09-24 added lagged_fibonacci generator (Matthias Troyer)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_HPP
#define BOOST_RANDOM_HPP
// generators
#include <boost/random/additive_combine.hpp>
#include <boost/random/discard_block.hpp>
#include <boost/random/independent_bits.hpp>
#include <boost/random/inversive_congruential.hpp>
#include <boost/random/lagged_fibonacci.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/linear_feedback_shift.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/ranlux.hpp>
#include <boost/random/shuffle_order.hpp>
#include <boost/random/shuffle_output.hpp>
#include <boost/random/subtract_with_carry.hpp>
#include <boost/random/taus88.hpp>
#include <boost/random/xor_combine.hpp>
// misc
#include <boost/random/generate_canonical.hpp>
#include <boost/random/seed_seq.hpp>
#include <boost/random/random_number_generator.hpp>
#include <boost/random/variate_generator.hpp>
// distributions
#include <boost/random/bernoulli_distribution.hpp>
#include <boost/random/beta_distribution.hpp>
#include <boost/random/binomial_distribution.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/chi_squared_distribution.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/random/extreme_value_distribution.hpp>
#include <boost/random/fisher_f_distribution.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/geometric_distribution.hpp>
#include <boost/random/hyperexponential_distribution.hpp>
#include <boost/random/laplace_distribution.hpp>
#include <boost/random/lognormal_distribution.hpp>
#include <boost/random/negative_binomial_distribution.hpp>
#include <boost/random/non_central_chi_squared_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/piecewise_constant_distribution.hpp>
#include <boost/random/piecewise_linear_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/student_t_distribution.hpp>
#include <boost/random/triangle_distribution.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/uniform_on_sphere.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/weibull_distribution.hpp>
#include <boost/random/generate_canonical.hpp>
#endif // BOOST_RANDOM_HPP

View File

@ -1,283 +0,0 @@
/* boost random/additive_combine.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP
#define BOOST_RANDOM_ADDITIVE_COMBINE_HPP
#include <istream>
#include <iosfwd>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
/**
* An instantiation of class template @c additive_combine_engine models a
* \pseudo_random_number_generator. It combines two multiplicative
* \linear_congruential_engine number generators, i.e. those with @c c = 0.
* It is described in
*
* @blockquote
* "Efficient and Portable Combined Random Number Generators", Pierre L'Ecuyer,
* Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774
* @endblockquote
*
* The template parameters MLCG1 and MLCG2 shall denote two different
* \linear_congruential_engine number generators, each with c = 0. Each
* invocation returns a random number
* X(n) := (MLCG1(n) - MLCG2(n)) mod (m1 - 1),
* where m1 denotes the modulus of MLCG1.
*/
template<class MLCG1, class MLCG2>
class additive_combine_engine
{
public:
typedef MLCG1 first_base;
typedef MLCG2 second_base;
typedef typename MLCG1::result_type result_type;
// Required by old Boost.Random concept
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
/**
* Returns the smallest value that the generator can produce
*/
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 1; }
/**
* Returns the largest value that the generator can produce
*/
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return MLCG1::modulus-1; }
/**
* Constructs an @c additive_combine_engine using the
* default constructors of the two base generators.
*/
additive_combine_engine() : _mlcg1(), _mlcg2() { }
/**
* Constructs an @c additive_combine_engine, using seed as
* the constructor argument for both base generators.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(additive_combine_engine,
result_type, seed_arg)
{
_mlcg1.seed(seed_arg);
_mlcg2.seed(seed_arg);
}
/**
* Constructs an @c additive_combine_engine, using seq as
* the constructor argument for both base generators.
*
* @xmlwarning
* The semantics of this function are liable to change.
* A @c seed_seq is designed to generate all the seeds
* in one shot, but this seeds the two base engines
* independantly and probably ends up giving the same
* sequence to both.
* @endxmlwarning
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(additive_combine_engine,
SeedSeq, seq)
{
_mlcg1.seed(seq);
_mlcg2.seed(seq);
}
/**
* Constructs an @c additive_combine_engine, using
* @c seed1 and @c seed2 as the constructor argument to
* the first and second base generators, respectively.
*/
additive_combine_engine(typename MLCG1::result_type seed1,
typename MLCG2::result_type seed2)
: _mlcg1(seed1), _mlcg2(seed2) { }
/**
* Contructs an @c additive_combine_engine with
* values from the range defined by the input iterators first
* and last. first will be modified to point to the element
* after the last one used.
*
* Throws: @c std::invalid_argument if the input range is too small.
*
* Exception Safety: Basic
*/
template<class It> additive_combine_engine(It& first, It last)
: _mlcg1(first, last), _mlcg2(first, last) { }
/**
* Seeds an @c additive_combine_engine using the default
* seeds of the two base generators.
*/
void seed()
{
_mlcg1.seed();
_mlcg2.seed();
}
/**
* Seeds an @c additive_combine_engine, using @c seed as the
* seed for both base generators.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(additive_combine_engine,
result_type, seed_arg)
{
_mlcg1.seed(seed_arg);
_mlcg2.seed(seed_arg);
}
/**
* Seeds an @c additive_combine_engine, using @c seq to
* seed both base generators.
*
* See the warning on the corresponding constructor.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(additive_combine_engine,
SeedSeq, seq)
{
_mlcg1.seed(seq);
_mlcg2.seed(seq);
}
/**
* Seeds an @c additive_combine generator, using @c seed1 and @c seed2 as
* the seeds to the first and second base generators, respectively.
*/
void seed(typename MLCG1::result_type seed1,
typename MLCG2::result_type seed2)
{
_mlcg1.seed(seed1);
_mlcg2.seed(seed2);
}
/**
* Seeds an @c additive_combine_engine with
* values from the range defined by the input iterators first
* and last. first will be modified to point to the element
* after the last one used.
*
* Throws: @c std::invalid_argument if the input range is too small.
*
* Exception Safety: Basic
*/
template<class It> void seed(It& first, It last)
{
_mlcg1.seed(first, last);
_mlcg2.seed(first, last);
}
/** Returns the next value of the generator. */
result_type operator()() {
result_type val1 = _mlcg1();
result_type val2 = _mlcg2();
if(val2 < val1) return val1 - val2;
else return val1 - val2 + MLCG1::modulus - 1;
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
_mlcg1.discard(z);
_mlcg2.discard(z);
}
/**
* Writes the state of an @c additive_combine_engine to a @c
* std::ostream. The textual representation of an @c
* additive_combine_engine is the textual representation of
* the first base generator followed by the textual representation
* of the second base generator.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, additive_combine_engine, r)
{ os << r._mlcg1 << ' ' << r._mlcg2; return os; }
/**
* Reads the state of an @c additive_combine_engine from a
* @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, additive_combine_engine, r)
{ is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
/**
* Returns: true iff the two @c additive_combine_engines will
* produce the same sequence of values.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(additive_combine_engine, x, y)
{ return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
/**
* Returns: true iff the two @c additive_combine_engines will
* produce different sequences of values.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(additive_combine_engine)
private:
MLCG1 _mlcg1;
MLCG2 _mlcg2;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template<class MLCG1, class MLCG2>
const bool additive_combine_engine<MLCG1, MLCG2>::has_fixed_range;
#endif
/// \cond show_deprecated
/** Provided for backwards compatibility. */
template<class MLCG1, class MLCG2, typename MLCG1::result_type val = 0>
class additive_combine : public additive_combine_engine<MLCG1, MLCG2>
{
typedef additive_combine_engine<MLCG1, MLCG2> base_t;
public:
typedef typename base_t::result_type result_type;
additive_combine() {}
template<class T>
additive_combine(T& arg) : base_t(arg) {}
template<class T>
additive_combine(const T& arg) : base_t(arg) {}
template<class It>
additive_combine(It& first, It last) : base_t(first, last) {}
};
/// \endcond
/**
* The specialization \ecuyer1988 was suggested in
*
* @blockquote
* "Efficient and Portable Combined Random Number Generators", Pierre L'Ecuyer,
* Communications of the ACM, Vol. 31, No. 6, June 1988, pp. 742-749, 774
* @endblockquote
*/
typedef additive_combine_engine<
linear_congruential_engine<uint32_t, 40014, 0, 2147483563>,
linear_congruential_engine<uint32_t, 40692, 0, 2147483399>
> ecuyer1988;
} // namespace random
using random::ecuyer1988;
} // namespace boost
#endif // BOOST_RANDOM_ADDITIVE_COMBINE_HPP

View File

@ -1,197 +0,0 @@
/* boost random/bernoulli_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#define BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template \bernoulli_distribution model a
* \random_distribution. Such a random distribution produces bool values
* distributed with probabilities P(true) = p and P(false) = 1-p. p is
* the parameter of the distribution.
*/
template<class RealType = double>
class bernoulli_distribution
{
public:
// In principle, this could work with both integer and floating-point
// types. Generating floating-point random numbers in the first
// place is probably more expensive, so use integer as input.
typedef int input_type;
typedef bool result_type;
class param_type
{
public:
typedef bernoulli_distribution distribution_type;
/**
* Constructs the parameters of the distribution.
*
* Requires: 0 <= p <= 1
*/
explicit param_type(RealType p_arg = RealType(0.5))
: _p(p_arg)
{
BOOST_ASSERT(_p >= 0);
BOOST_ASSERT(_p <= 1);
}
/** Returns the p parameter of the distribution. */
RealType p() const { return _p; }
/** Writes the parameters to a std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._p;
return os;
}
/** Reads the parameters from a std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._p;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._p == rhs._p; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _p;
};
/**
* Constructs a \bernoulli_distribution object.
* p is the parameter of the distribution.
*
* Requires: 0 <= p <= 1
*/
explicit bernoulli_distribution(const RealType& p_arg = RealType(0.5))
: _p(p_arg)
{
BOOST_ASSERT(_p >= 0);
BOOST_ASSERT(_p <= 1);
}
/**
* Constructs \bernoulli_distribution from its parameters
*/
explicit bernoulli_distribution(const param_type& parm)
: _p(parm.p()) {}
// compiler-generated copy ctor and assignment operator are fine
/**
* Returns: The "p" parameter of the distribution.
*/
RealType p() const { return _p; }
/** Returns the smallest value that the distribution can produce. */
bool min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return false; }
/** Returns the largest value that the distribution can produce. */
bool max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return true; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_p); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm) { _p = parm.p(); }
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/**
* Returns: a random variate distributed according to the
* \bernoulli_distribution.
*/
template<class Engine>
bool operator()(Engine& eng) const
{
if(_p == RealType(0))
return false;
else
return RealType(eng() - (eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
}
/**
* Returns: a random variate distributed according to the
* \bernoulli_distribution with parameters specified by param.
*/
template<class Engine>
bool operator()(Engine& eng, const param_type& parm) const
{
return bernoulli_distribution(parm)(eng);
}
/**
* Writes the parameters of the distribution to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, bernoulli_distribution, bd)
{
os << bd._p;
return os;
}
/**
* Reads the parameters of the distribution from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, bernoulli_distribution, bd)
{
is >> bd._p;
return is;
}
/**
* Returns true iff the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(bernoulli_distribution, lhs, rhs)
{ return lhs._p == rhs._p; }
/**
* Returns true iff the two distributions will produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(bernoulli_distribution)
private:
RealType _p;
};
} // namespace random
using random::bernoulli_distribution;
} // namespace boost
#endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP

View File

@ -1,184 +0,0 @@
/* boost random/beta_distribution.hpp header file
*
* Copyright Steven Watanabe 2014
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_BETA_DISTRIBUTION_HPP
#define BOOST_RANDOM_BETA_DISTRIBUTION_HPP
#include <cassert>
#include <istream>
#include <iosfwd>
#include <boost/random/detail/operators.hpp>
#include <boost/random/gamma_distribution.hpp>
namespace boost {
namespace random {
/**
* The beta distribution is a real-valued distribution which produces
* values in the range [0, 1]. It has two parameters, alpha and beta.
*
* It has \f$\displaystyle p(x) = \frac{x^{\alpha-1}(1-x)^{\beta-1}}{B(\alpha, \beta)}\f$.
*/
template<class RealType = double>
class beta_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef beta_distribution distribution_type;
/**
* Constructs a @c param_type from the "alpha" and "beta" parameters
* of the distribution.
*
* Requires: alpha > 0, beta > 0
*/
explicit param_type(RealType alpha_arg = RealType(1.0),
RealType beta_arg = RealType(1.0))
: _alpha(alpha_arg), _beta(beta_arg)
{
assert(alpha_arg > 0);
assert(beta_arg > 0);
}
/** Returns the "alpha" parameter of the distribtuion. */
RealType alpha() const { return _alpha; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._alpha << ' ' << parm._beta; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._alpha >> std::ws >> parm._beta; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _alpha;
RealType _beta;
};
/**
* Constructs an @c beta_distribution from its "alpha" and "beta" parameters.
*
* Requires: alpha > 0, beta > 0
*/
explicit beta_distribution(RealType alpha_arg = RealType(1.0),
RealType beta_arg = RealType(1.0))
: _alpha(alpha_arg), _beta(beta_arg)
{
assert(alpha_arg > 0);
assert(beta_arg > 0);
}
/** Constructs an @c beta_distribution from its parameters. */
explicit beta_distribution(const param_type& parm)
: _alpha(parm.alpha()), _beta(parm.beta())
{}
/**
* Returns a random variate distributed according to the
* beta distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
RealType a = gamma_distribution<RealType>(_alpha, RealType(1.0))(urng);
RealType b = gamma_distribution<RealType>(_beta, RealType(1.0))(urng);
return a / (a + b);
}
/**
* Returns a random variate distributed accordint to the beta
* distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return beta_distribution(parm)(urng);
}
/** Returns the "alpha" parameter of the distribution. */
RealType alpha() const { return _alpha; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(0.0); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(1.0); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_alpha, _beta); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_alpha = parm.alpha();
_beta = parm.beta();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Writes an @c beta_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, beta_distribution, wd)
{
os << wd.param();
return os;
}
/** Reads an @c beta_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, beta_distribution, wd)
{
param_type parm;
if(is >> parm) {
wd.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c beta_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(beta_distribution, lhs, rhs)
{ return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta; }
/**
* Returns true if the two instances of @c beta_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(beta_distribution)
private:
RealType _alpha;
RealType _beta;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_BETA_DISTRIBUTION_HPP

View File

@ -1,434 +0,0 @@
/* boost random/binomial_distribution.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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#include <boost/config/no_tr1/cmath.hpp>
#include <cstdlib>
#include <iosfwd>
#include <boost/random/detail/config.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
template<class RealType>
struct binomial_table {
static const RealType table[10];
};
template<class RealType>
const RealType binomial_table<RealType>::table[10] = {
0.08106146679532726,
0.04134069595540929,
0.02767792568499834,
0.02079067210376509,
0.01664469118982119,
0.01387612882307075,
0.01189670994589177,
0.01041126526197209,
0.009255462182712733,
0.008330563433362871
};
}
/**
* The binomial distribution is an integer valued distribution with
* two parameters, @c t and @c p. The values of the distribution
* are within the range [0,t].
*
* The distribution function is
* \f$\displaystyle P(k) = {t \choose k}p^k(1-p)^{t-k}\f$.
*
* The algorithm used is the BTRD algorithm described in
*
* @blockquote
* "The generation of binomial random variates", Wolfgang Hormann,
* Journal of Statistical Computation and Simulation, Volume 46,
* Issue 1 & 2 April 1993 , pages 101 - 110
* @endblockquote
*/
template<class IntType = int, class RealType = double>
class binomial_distribution {
public:
typedef IntType result_type;
typedef RealType input_type;
class param_type {
public:
typedef binomial_distribution distribution_type;
/**
* Construct a param_type object. @c t and @c p
* are the parameters of the distribution.
*
* Requires: t >=0 && 0 <= p <= 1
*/
explicit param_type(IntType t_arg = 1, RealType p_arg = RealType (0.5))
: _t(t_arg), _p(p_arg)
{}
/** Returns the @c t parameter of the distribution. */
IntType t() const { return _t; }
/** Returns the @c p parameter of the distribution. */
RealType p() const { return _p; }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const param_type& parm)
{
os << parm._p << " " << parm._t;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm)
{
is >> parm._p >> std::ws >> parm._t;
return is;
}
#endif
/** Returns true if the parameters have the same values. */
friend bool operator==(const param_type& lhs, const param_type& rhs)
{
return lhs._t == rhs._t && lhs._p == rhs._p;
}
/** Returns true if the parameters have different values. */
friend bool operator!=(const param_type& lhs, const param_type& rhs)
{
return !(lhs == rhs);
}
private:
IntType _t;
RealType _p;
};
/**
* Construct a @c binomial_distribution object. @c t and @c p
* are the parameters of the distribution.
*
* Requires: t >=0 && 0 <= p <= 1
*/
explicit binomial_distribution(IntType t_arg = 1,
RealType p_arg = RealType(0.5))
: _t(t_arg), _p(p_arg)
{
init();
}
/**
* Construct an @c binomial_distribution object from the
* parameters.
*/
explicit binomial_distribution(const param_type& parm)
: _t(parm.t()), _p(parm.p())
{
init();
}
/**
* Returns a random variate distributed according to the
* binomial distribution.
*/
template<class URNG>
IntType operator()(URNG& urng) const
{
if(use_inversion()) {
if(0.5 < _p) {
return _t - invert(_t, 1-_p, urng);
} else {
return invert(_t, _p, urng);
}
} else if(0.5 < _p) {
return _t - generate(urng);
} else {
return generate(urng);
}
}
/**
* Returns a random variate distributed according to the
* binomial distribution with parameters specified by @c param.
*/
template<class URNG>
IntType operator()(URNG& urng, const param_type& parm) const
{
return binomial_distribution(parm)(urng);
}
/** Returns the @c t parameter of the distribution. */
IntType t() const { return _t; }
/** Returns the @c p parameter of the distribution. */
RealType p() const { return _p; }
/** Returns the smallest value that the distribution can produce. */
IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
/** Returns the largest value that the distribution can produce. */
IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const { return _t; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_t, _p); }
/** Sets parameters of the distribution. */
void param(const param_type& parm)
{
_t = parm.t();
_p = parm.p();
init();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const binomial_distribution& bd)
{
os << bd.param();
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, binomial_distribution& bd)
{
bd.read(is);
return is;
}
#endif
/** Returns true if the two distributions will produce the same
sequence of values, given equal generators. */
friend bool operator==(const binomial_distribution& lhs,
const binomial_distribution& rhs)
{
return lhs._t == rhs._t && lhs._p == rhs._p;
}
/** Returns true if the two distributions could produce different
sequences of values, given equal generators. */
friend bool operator!=(const binomial_distribution& lhs,
const binomial_distribution& rhs)
{
return !(lhs == rhs);
}
private:
/// @cond show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
param_type parm;
if(is >> parm) {
param(parm);
}
}
bool use_inversion() const
{
// BTRD is safe when np >= 10
return m < 11;
}
// computes the correction factor for the Stirling approximation
// for log(k!)
static RealType fc(IntType k)
{
if(k < 10) return detail::binomial_table<RealType>::table[k];
else {
RealType ikp1 = RealType(1) / (k + 1);
return (RealType(1)/12
- (RealType(1)/360
- (RealType(1)/1260)*(ikp1*ikp1))*(ikp1*ikp1))*ikp1;
}
}
void init()
{
using std::sqrt;
using std::pow;
RealType p = (0.5 < _p)? (1 - _p) : _p;
IntType t = _t;
m = static_cast<IntType>((t+1)*p);
if(use_inversion()) {
q_n = pow((1 - p), static_cast<RealType>(t));
} else {
btrd.r = p/(1-p);
btrd.nr = (t+1)*btrd.r;
btrd.npq = t*p*(1-p);
RealType sqrt_npq = sqrt(btrd.npq);
btrd.b = 1.15 + 2.53 * sqrt_npq;
btrd.a = -0.0873 + 0.0248*btrd.b + 0.01*p;
btrd.c = t*p + 0.5;
btrd.alpha = (2.83 + 5.1/btrd.b) * sqrt_npq;
btrd.v_r = 0.92 - 4.2/btrd.b;
btrd.u_rv_r = 0.86*btrd.v_r;
}
}
template<class URNG>
result_type generate(URNG& urng) const
{
using std::floor;
using std::abs;
using std::log;
while(true) {
RealType u;
RealType v = uniform_01<RealType>()(urng);
if(v <= btrd.u_rv_r) {
u = v/btrd.v_r - 0.43;
return static_cast<IntType>(floor(
(2*btrd.a/(0.5 - abs(u)) + btrd.b)*u + btrd.c));
}
if(v >= btrd.v_r) {
u = uniform_01<RealType>()(urng) - 0.5;
} else {
u = v/btrd.v_r - 0.93;
u = ((u < 0)? -0.5 : 0.5) - u;
v = uniform_01<RealType>()(urng) * btrd.v_r;
}
RealType us = 0.5 - abs(u);
IntType k = static_cast<IntType>(floor((2*btrd.a/us + btrd.b)*u + btrd.c));
if(k < 0 || k > _t) continue;
v = v*btrd.alpha/(btrd.a/(us*us) + btrd.b);
RealType km = abs(k - m);
if(km <= 15) {
RealType f = 1;
if(m < k) {
IntType i = m;
do {
++i;
f = f*(btrd.nr/i - btrd.r);
} while(i != k);
} else if(m > k) {
IntType i = k;
do {
++i;
v = v*(btrd.nr/i - btrd.r);
} while(i != m);
}
if(v <= f) return k;
else continue;
} else {
// final acceptance/rejection
v = log(v);
RealType rho =
(km/btrd.npq)*(((km/3. + 0.625)*km + 1./6)/btrd.npq + 0.5);
RealType t = -km*km/(2*btrd.npq);
if(v < t - rho) return k;
if(v > t + rho) continue;
IntType nm = _t - m + 1;
RealType h = (m + 0.5)*log((m + 1)/(btrd.r*nm))
+ fc(m) + fc(_t - m);
IntType nk = _t - k + 1;
if(v <= h + (_t+1)*log(static_cast<RealType>(nm)/nk)
+ (k + 0.5)*log(nk*btrd.r/(k+1))
- fc(k)
- fc(_t - k))
{
return k;
} else {
continue;
}
}
}
}
template<class URNG>
IntType invert(IntType t, RealType p, URNG& urng) const
{
RealType q = 1 - p;
RealType s = p / q;
RealType a = (t + 1) * s;
RealType r = q_n;
RealType u = uniform_01<RealType>()(urng);
IntType x = 0;
while(u > r) {
u = u - r;
++x;
RealType r1 = ((a/x) - s) * r;
// If r gets too small then the round-off error
// becomes a problem. At this point, p(i) is
// decreasing exponentially, so if we just call
// it 0, it's close enough. Note that the
// minimum value of q_n is about 1e-7, so we
// may need to be a little careful to make sure that
// we don't terminate the first time through the loop
// for float. (Hence the test that r is decreasing)
if(r1 < std::numeric_limits<RealType>::epsilon() && r1 < r) {
break;
}
r = r1;
}
return x;
}
// parameters
IntType _t;
RealType _p;
// common data
IntType m;
union {
// for btrd
struct {
RealType r;
RealType nr;
RealType npq;
RealType b;
RealType a;
RealType c;
RealType alpha;
RealType v_r;
RealType u_rv_r;
} btrd;
// for inversion
RealType q_n;
};
/// @endcond
};
}
// backwards compatibility
using random::binomial_distribution;
}
#include <boost/random/detail/enable_warnings.hpp>
#endif

View File

@ -1,214 +0,0 @@
/* boost random/cauchy_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
#define BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <istream>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
// Cauchy distribution:
/**
* The cauchy distribution is a continuous distribution with two
* parameters, median and sigma.
*
* It has \f$\displaystyle p(x) = \frac{\sigma}{\pi(\sigma^2 + (x-m)^2)}\f$
*/
template<class RealType = double>
class cauchy_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type
{
public:
typedef cauchy_distribution distribution_type;
/** Constructs the parameters of the cauchy distribution. */
explicit param_type(RealType median_arg = RealType(0.0),
RealType sigma_arg = RealType(1.0))
: _median(median_arg), _sigma(sigma_arg) {}
// backwards compatibility for Boost.Random
/** Returns the median of the distribution. */
RealType median() const { return _median; }
/** Returns the sigma parameter of the distribution. */
RealType sigma() const { return _sigma; }
// The new names in C++0x.
/** Returns the median of the distribution. */
RealType a() const { return _median; }
/** Returns the sigma parameter of the distribution. */
RealType b() const { return _sigma; }
/** Writes the parameters to a std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._median << " " << parm._sigma;
return os;
}
/** Reads the parameters from a std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._median >> std::ws >> parm._sigma;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._median == rhs._median && lhs._sigma == rhs._sigma; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _median;
RealType _sigma;
};
/**
* Constructs a \cauchy_distribution with the paramters @c median
* and @c sigma.
*/
explicit cauchy_distribution(RealType median_arg = RealType(0.0),
RealType sigma_arg = RealType(1.0))
: _median(median_arg), _sigma(sigma_arg) { }
/**
* Constructs a \cauchy_distribution from it's parameters.
*/
explicit cauchy_distribution(const param_type& parm)
: _median(parm.median()), _sigma(parm.sigma()) { }
// compiler-generated copy ctor and assignment operator are fine
// backwards compatibility for Boost.Random
/** Returns: the "median" parameter of the distribution */
RealType median() const { return _median; }
/** Returns: the "sigma" parameter of the distribution */
RealType sigma() const { return _sigma; }
// The new names in C++0x
/** Returns: the "median" parameter of the distribution */
RealType a() const { return _median; }
/** Returns: the "sigma" parameter of the distribution */
RealType b() const { return _sigma; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -(std::numeric_limits<RealType>::infinity)(); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return (std::numeric_limits<RealType>::infinity)(); }
param_type param() const { return param_type(_median, _sigma); }
void param(const param_type& parm)
{
_median = parm.median();
_sigma = parm.sigma();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/**
* Returns: A random variate distributed according to the
* cauchy distribution.
*/
template<class Engine>
result_type operator()(Engine& eng)
{
// Can we have a boost::mathconst please?
const result_type pi = result_type(3.14159265358979323846);
using std::tan;
RealType val = uniform_01<RealType>()(eng)-result_type(0.5);
return _median + _sigma * tan(pi*val);
}
/**
* Returns: A random variate distributed according to the
* cauchy distribution with parameters specified by param.
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm)
{
return cauchy_distribution(parm)(eng);
}
/**
* Writes the distribution to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, cauchy_distribution, cd)
{
os << cd._median << " " << cd._sigma;
return os;
}
/**
* Reads the distribution from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, cauchy_distribution, cd)
{
is >> cd._median >> std::ws >> cd._sigma;
return is;
}
/**
* Returns true if the two distributions will produce
* identical sequences of values, given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(cauchy_distribution, lhs, rhs)
{ return lhs._median == rhs._median && lhs._sigma == rhs._sigma; }
/**
* Returns true if the two distributions may produce
* different sequences of values, given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(cauchy_distribution)
private:
RealType _median;
RealType _sigma;
};
} // namespace random
using random::cauchy_distribution;
} // namespace boost
#endif // BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP

View File

@ -1,209 +0,0 @@
/* boost random/chi_squared_distribution.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_CHI_SQUARED_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_CHI_SQUARED_DISTRIBUTION_HPP_INCLUDED
#include <iosfwd>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/gamma_distribution.hpp>
namespace boost {
namespace random {
/**
* The chi squared distribution is a real valued distribution with
* one parameter, @c n. The distribution produces values > 0.
*
* The distribution function is
* \f$\displaystyle P(x) = \frac{x^{(n/2)-1}e^{-x/2}}{\Gamma(n/2)2^{n/2}}\f$.
*/
template<class RealType = double>
class chi_squared_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef chi_squared_distribution distribution_type;
/**
* Construct a param_type object. @c n
* is the parameter of the distribution.
*
* Requires: t >=0 && 0 <= p <= 1
*/
explicit param_type(RealType n_arg = RealType(1))
: _n(n_arg)
{}
/** Returns the @c n parameter of the distribution. */
RealType n() const { return _n; }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const param_type& parm)
{
os << parm._n;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm)
{
is >> parm._n;
return is;
}
#endif
/** Returns true if the parameters have the same values. */
friend bool operator==(const param_type& lhs, const param_type& rhs)
{
return lhs._n == rhs._n;
}
/** Returns true if the parameters have different values. */
friend bool operator!=(const param_type& lhs, const param_type& rhs)
{
return !(lhs == rhs);
}
private:
RealType _n;
};
/**
* Construct a @c chi_squared_distribution object. @c n
* is the parameter of the distribution.
*
* Requires: t >=0 && 0 <= p <= 1
*/
explicit chi_squared_distribution(RealType n_arg = RealType(1))
: _impl(static_cast<RealType>(n_arg / 2))
{
}
/**
* Construct an @c chi_squared_distribution object from the
* parameters.
*/
explicit chi_squared_distribution(const param_type& parm)
: _impl(static_cast<RealType>(parm.n() / 2))
{
}
/**
* Returns a random variate distributed according to the
* chi squared distribution.
*/
template<class URNG>
RealType operator()(URNG& urng)
{
return 2 * _impl(urng);
}
/**
* Returns a random variate distributed according to the
* chi squared distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return chi_squared_distribution(parm)(urng);
}
/** Returns the @c n parameter of the distribution. */
RealType n() const { return 2 * _impl.alpha(); }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(n()); }
/** Sets parameters of the distribution. */
void param(const param_type& parm)
{
typedef gamma_distribution<RealType> impl_type;
typename impl_type::param_type impl_parm(static_cast<RealType>(parm.n() / 2));
_impl.param(impl_parm);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { _impl.reset(); }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const chi_squared_distribution& c2d)
{
os << c2d.param();
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
chi_squared_distribution& c2d)
{
c2d.read(is);
return is;
}
#endif
/** Returns true if the two distributions will produce the same
sequence of values, given equal generators. */
friend bool operator==(const chi_squared_distribution& lhs,
const chi_squared_distribution& rhs)
{
return lhs._impl == rhs._impl;
}
/** Returns true if the two distributions could produce different
sequences of values, given equal generators. */
friend bool operator!=(const chi_squared_distribution& lhs,
const chi_squared_distribution& rhs)
{
return !(lhs == rhs);
}
private:
/// @cond show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
param_type parm;
if(is >> parm) {
param(parm);
}
}
gamma_distribution<RealType> _impl;
/// @endcond
};
}
}
#endif

View File

@ -1,40 +0,0 @@
/* 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>
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_RANDOM_DYN_LINK)
#if defined(BOOST_RANDOM_SOURCE)
#define BOOST_RANDOM_DECL BOOST_SYMBOL_EXPORT
#else
#define BOOST_RANDOM_DECL BOOST_SYMBOL_IMPORT
#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

View File

@ -1,18 +0,0 @@
/* boost random/detail/config.hpp header file
*
* Copyright Steven Watanabe 2009
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#include <boost/config.hpp>
#if (defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)) \
&& !defined(BOOST_MSVC)
#define BOOST_RANDOM_NO_STREAM_OPERATORS
#endif

View File

@ -1,216 +0,0 @@
/* boost random/detail/const_mod.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_CONST_MOD_HPP
#define BOOST_RANDOM_CONST_MOD_HPP
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/integer_traits.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/random/detail/large_arithmetic.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
template<class IntType, IntType m>
class const_mod
{
public:
static IntType apply(IntType x)
{
if(((unsigned_m() - 1) & unsigned_m()) == 0)
return (unsigned_type(x)) & (unsigned_m() - 1);
else {
IntType suppress_warnings = (m == 0);
BOOST_ASSERT(suppress_warnings == 0);
return x % (m + suppress_warnings);
}
}
static IntType add(IntType x, IntType c)
{
if(((unsigned_m() - 1) & unsigned_m()) == 0)
return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
else if(c == 0)
return x;
else if(x < m - c)
return x + c;
else
return x - (m - c);
}
static IntType mult(IntType a, IntType x)
{
if(((unsigned_m() - 1) & unsigned_m()) == 0)
return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1);
else if(a == 0)
return 0;
else if(a == 1)
return x;
else if(m <= traits::const_max/a) // i.e. a*m <= max
return mult_small(a, x);
else if(traits::is_signed && (m%a < m/a))
return mult_schrage(a, x);
else
return mult_general(a, x);
}
static IntType mult_add(IntType a, IntType x, IntType c)
{
if(((unsigned_m() - 1) & unsigned_m()) == 0)
return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1);
else if(a == 0)
return c;
else if(m <= (traits::const_max-c)/a) { // i.e. a*m+c <= max
IntType suppress_warnings = (m == 0);
BOOST_ASSERT(suppress_warnings == 0);
return (a*x+c) % (m + suppress_warnings);
} else
return add(mult(a, x), c);
}
static IntType pow(IntType a, boost::uintmax_t exponent)
{
IntType result = 1;
while(exponent != 0) {
if(exponent % 2 == 1) {
result = mult(result, a);
}
a = mult(a, a);
exponent /= 2;
}
return result;
}
static IntType invert(IntType x)
{ return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); }
private:
typedef integer_traits<IntType> traits;
typedef typename make_unsigned<IntType>::type unsigned_type;
const_mod(); // don't instantiate
static IntType mult_small(IntType a, IntType x)
{
IntType suppress_warnings = (m == 0);
BOOST_ASSERT(suppress_warnings == 0);
return a*x % (m + suppress_warnings);
}
static IntType mult_schrage(IntType a, IntType value)
{
const IntType q = m / a;
const IntType r = m % a;
BOOST_ASSERT(r < q); // check that overflow cannot happen
return sub(a*(value%q), r*(value/q));
}
static IntType mult_general(IntType a, IntType b)
{
IntType suppress_warnings = (m == 0);
BOOST_ASSERT(suppress_warnings == 0);
IntType modulus = m + suppress_warnings;
BOOST_ASSERT(modulus == m);
if(::boost::uintmax_t(modulus) <=
(::std::numeric_limits< ::boost::uintmax_t>::max)() / modulus)
{
return static_cast<IntType>(boost::uintmax_t(a) * b % modulus);
} else {
return static_cast<IntType>(detail::mulmod(a, b, modulus));
}
}
static IntType sub(IntType a, IntType b)
{
if(a < b)
return m - (b - a);
else
return a - b;
}
static unsigned_type unsigned_m()
{
if(m == 0) {
return unsigned_type((std::numeric_limits<IntType>::max)()) + 1;
} else {
return unsigned_type(m);
}
}
// invert c in the finite field (mod m) (m must be prime)
static IntType invert_euclidian(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
BOOST_ASSERT(c > 0);
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
for(;;) {
IntType q = p / n;
l1 += q * l2;
p -= q * n;
if(p == 0)
return l2;
IntType q2 = n / p;
l2 += q2 * l1;
n -= q2 * p;
if(n == 0)
return m - l1;
}
}
// invert c in the finite field (mod m) (c must be relatively prime to m)
static IntType invert_euclidian0(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
BOOST_ASSERT(c > 0);
if(c == 1) return 1;
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
IntType max = (std::numeric_limits<IntType>::max)();
IntType q = max / n;
BOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m.");
l1 += q * l2;
p = max - q * n + 1;
for(;;) {
if(p == 0)
return l2;
IntType q2 = n / p;
l2 += q2 * l1;
n -= q2 * p;
if(n == 0)
return m - l1;
q = p / n;
l1 += q * l2;
p -= q * n;
}
}
};
} // namespace random
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_CONST_MOD_HPP

View File

@ -1,29 +0,0 @@
/* boost random/detail/disable_warnings.hpp header file
*
* Copyright Steven Watanabe 2009
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
// No #include guard. This header is intended to be included multiple times.
#include <boost/config.hpp>
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4512)
#pragma warning(disable:4127)
#pragma warning(disable:4724)
#pragma warning(disable:4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
#endif
#if defined(BOOST_GCC) && BOOST_GCC >= 40600
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wlogical-op"
#endif

View File

@ -1,22 +0,0 @@
/* boost random/detail/enable_warnings.hpp header file
*
* Copyright Steven Watanabe 2009
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
// No #include guard. This header is intended to be included multiple times.
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#if defined(BOOST_GCC) && BOOST_GCC >= 40600
#pragma GCC diagnostic pop
#endif

View File

@ -1,36 +0,0 @@
/* boost random/detail/generator_bits.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP
#include <boost/limits.hpp>
namespace boost {
namespace random {
namespace detail {
// This is a temporary measure that retains backwards
// compatibility.
template<class URNG>
struct generator_bits {
static std::size_t value() {
return std::numeric_limits<typename URNG::result_type>::digits;
}
};
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP

View File

@ -1,40 +0,0 @@
/* boost random/mersenne_twister.hpp header file
*
* Copyright Jens Maurer 2000-2001
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_GENERATOR_SEED_SEQ_HPP_INCLUDED
#define BOOST_RANDOM_DETAIL_GENERATOR_SEED_SEQ_HPP_INCLUDED
namespace boost {
namespace random {
namespace detail {
template<class Generator>
class generator_seed_seq {
public:
generator_seed_seq(Generator& g) : gen(&g) {}
template<class It>
void generate(It first, It last) {
for(; first != last; ++first) {
*first = (*gen)();
}
}
private:
Generator* gen;
};
}
}
}
#endif

View File

@ -1,121 +0,0 @@
/* boost random/detail/int_float_pair.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
#define BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP
#include <utility>
#include <boost/integer.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/detail/integer_log2.hpp>
#include <boost/mpl/bool.hpp>
namespace boost {
namespace random {
namespace detail {
template<class Engine>
inline typename boost::make_unsigned<typename Engine::result_type>::type
generate_one_digit(Engine& eng, std::size_t bits)
{
typedef typename Engine::result_type base_result;
typedef typename boost::make_unsigned<base_result>::type base_unsigned;
base_unsigned range =
detail::subtract<base_result>()((eng.max)(), (eng.min)());
base_unsigned y0_mask = (base_unsigned(2) << (bits - 1)) - 1;
base_unsigned y0 = (range + 1) & ~y0_mask;
base_unsigned u;
do {
u = detail::subtract<base_result>()(eng(), (eng.min)());
} while(y0 != 0 && u > base_unsigned(y0 - 1));
return u & y0_mask;
}
template<class RealType, std::size_t w, class Engine>
std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::true_)
{
typedef typename Engine::result_type base_result;
typedef typename boost::make_unsigned<base_result>::type base_unsigned;
base_unsigned range =
detail::subtract<base_result>()((eng.max)(), (eng.min)());
std::size_t m =
(range == (std::numeric_limits<base_unsigned>::max)()) ?
std::numeric_limits<base_unsigned>::digits :
detail::integer_log2(range + 1);
int bucket = 0;
// process as many full digits as possible into the int part
for(std::size_t i = 0; i < w/m; ++i) {
base_unsigned u = generate_one_digit(eng, m);
bucket = (bucket << m) | u;
}
RealType r;
const std::size_t digits = std::numeric_limits<RealType>::digits;
{
base_unsigned u = generate_one_digit(eng, m);
base_unsigned mask = (base_unsigned(1) << (w%m)) - 1;
bucket = (bucket << (w%m)) | (mask & u);
const RealType mult = RealType(1)/RealType(base_unsigned(1) << (m - w%m));
// zero out unused bits
if (m - w%m > digits) {
u &= ~(base_unsigned(1) << (m - digits));
}
r = RealType(u >> (w%m)) * mult;
}
for(std::size_t i = m - w%m; i + m < digits; ++i) {
base_unsigned u = generate_one_digit(eng, m);
r += u;
r *= RealType(0.5)/RealType(base_unsigned(1) << (m - 1));
}
if (m - w%m < digits)
{
const std::size_t remaining = (digits - m + w%m) % m;
base_unsigned u = generate_one_digit(eng, m);
r += u & ((base_unsigned(2) << (remaining - 1)) - 1);
const RealType mult = RealType(0.5)/RealType(base_unsigned(1) << (remaining - 1));
r *= mult;
}
return std::make_pair(r, bucket);
}
template<class RealType, std::size_t w, class Engine>
inline std::pair<RealType, int> generate_int_float_pair(Engine& eng, boost::mpl::false_)
{
int bucket = uniform_int_distribution<>(0, (1 << w) - 1)(eng);
RealType r = uniform_01<RealType>()(eng);
return std::make_pair(r, bucket);
}
template<class RealType, std::size_t w, class Engine>
inline std::pair<RealType, int> generate_int_float_pair(Engine& eng)
{
typedef typename Engine::result_type base_result;
return generate_int_float_pair<RealType, w>(eng,
boost::is_integral<base_result>());
}
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_INT_FLOAT_PAIR_HPP

View File

@ -1,84 +0,0 @@
/* boost random/detail/integer_log2.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
#define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/pending/integer_log2.hpp>
namespace boost {
namespace random {
namespace detail {
#if !defined(BOOST_NO_CXX11_CONSTEXPR)
#define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr
#elif defined(BOOST_MSVC)
#define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline
#elif defined(__GNUC__) && __GNUC__ >= 4
#define BOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((__const__)) __attribute__((__always_inline__))
#else
#define BOOST_RANDOM_DETAIL_CONSTEXPR inline
#endif
template<int Shift>
struct integer_log2_impl
{
#if defined(BOOST_NO_CXX11_CONSTEXPR)
template<class T>
BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
{
int update = ((t >> Shift) != 0) * Shift;
return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
}
#else
template<class T>
BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update)
{
return integer_log2_impl<Shift / 2>::apply(t >> update, accum + update);
}
template<class T>
BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
{
return apply2(t, accum, ((t >> Shift) != 0) * Shift);
}
#endif
};
template<>
struct integer_log2_impl<1>
{
template<class T>
BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum)
{
return int(t >> 1) + accum;
}
};
template<class T>
BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t)
{
return integer_log2_impl<
::boost::detail::max_pow2_less<
::std::numeric_limits<T>::digits, 4
>::value
>::apply(t, 0);
}
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP

View File

@ -1,45 +0,0 @@
/* boost random/detail/iterator_mixin.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* Revision history
*/
#ifndef BOOST_ITERATOR_MIXIN_HPP
#define BOOST_ITERATOR_MIXIN_HPP
#include <boost/operators.hpp>
namespace boost {
// must be in boost namespace, otherwise the inline friend trick fails
template<class Generator, class ResultType>
class generator_iterator_mixin_adapter
: incrementable<Generator>, equality_comparable<Generator>
{
public:
typedef std::input_iterator_tag iterator_category;
typedef ResultType value_type;
typedef std::ptrdiff_t difference_type;
typedef const value_type * pointer;
typedef const value_type & reference;
Generator& operator++() { v = cast()(); return cast(); }
const value_type& operator*() const { return v; }
protected:
// instantiate from derived classes only
generator_iterator_mixin_adapter() { }
void iterator_init() { operator++(); }
private:
Generator & cast() { return static_cast<Generator&>(*this); }
value_type v;
};
} // namespace boost
#endif // BOOST_ITERATOR_MIXIN_HPP

View File

@ -1,122 +0,0 @@
/* boost random/detail/large_arithmetic.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
#define BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP
#include <boost/cstdint.hpp>
#include <boost/integer.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
struct div_t {
boost::uintmax_t quotient;
boost::uintmax_t remainder;
};
inline div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{
const int bits =
::std::numeric_limits< ::boost::uintmax_t>::digits / 2;
const ::boost::uintmax_t mask = (::boost::uintmax_t(1) << bits) - 1;
typedef ::boost::uint_t<bits>::fast digit_t;
int shift = std::numeric_limits< ::boost::uintmax_t>::digits - 1
- detail::integer_log2(m);
a <<= shift;
m <<= shift;
digit_t product[4] = { 0, 0, 0, 0 };
digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) };
digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) };
digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) };
// multiply a * b
for(int i = 0; i < 2; ++i) {
digit_t carry = 0;
for(int j = 0; j < 2; ++j) {
::boost::uint64_t temp = ::boost::uintmax_t(a_[i]) * b_[j] +
carry + product[i + j];
product[i + j] = digit_t(temp & mask);
carry = digit_t(temp >> bits);
}
if(carry != 0) {
product[i + 2] += carry;
}
}
digit_t quotient[2];
if(m == 0) {
div_t result = {
((::boost::uintmax_t(product[3]) << bits) | product[2]),
((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
};
return result;
}
// divide product / m
for(int i = 3; i >= 2; --i) {
::boost::uintmax_t temp =
::boost::uintmax_t(product[i]) << bits | product[i - 1];
digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]);
::boost::uintmax_t rem =
((temp - ::boost::uintmax_t(q) * m_[1]) << bits) + product[i - 2];
::boost::uintmax_t diff = m_[0] * ::boost::uintmax_t(q);
int error = 0;
if(diff > rem) {
if(diff - rem > m) {
error = 2;
} else {
error = 1;
}
}
q -= error;
rem = rem + error * m - diff;
quotient[i - 2] = q;
product[i] = 0;
product[i-1] = static_cast<digit_t>((rem >> bits) & mask);
product[i-2] = static_cast<digit_t>(rem & mask);
}
div_t result = {
((::boost::uintmax_t(quotient[1]) << bits) | quotient[0]),
((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift,
};
return result;
}
inline boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{ return detail::muldivmod(a, b, m).quotient; }
inline boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m)
{ return detail::muldivmod(a, b, m).remainder; }
} // namespace detail
} // namespace random
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP

View File

@ -1,84 +0,0 @@
/* boost random/detail/operators.hpp header file
*
* Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_OPERATORS_HPP
#define BOOST_RANDOM_DETAIL_OPERATORS_HPP
#include <boost/random/detail/config.hpp>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
template<class CharT, class Traits> \
friend std::basic_ostream<CharT,Traits>& \
operator<<(std::basic_ostream<CharT,Traits>& os, const T& t) { \
t.print(os, t); \
return os; \
} \
template<class CharT, class Traits> \
static std::basic_ostream<CharT,Traits>& \
print(std::basic_ostream<CharT,Traits>& os, const T& t)
#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
template<class CharT, class Traits> \
friend std::basic_istream<CharT,Traits>& \
operator>>(std::basic_istream<CharT,Traits>& is, T& t) { \
t.read(is, t); \
return is; \
} \
template<class CharT, class Traits> \
static std::basic_istream<CharT,Traits>& \
read(std::basic_istream<CharT,Traits>& is, T& t)
#endif
#if defined(__BORLANDC__)
#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
bool operator==(const T& rhs) const \
{ return T::is_equal(*this, rhs); } \
static bool is_equal(const T& lhs, const T& rhs)
#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
bool operator!=(const T& rhs) const \
{ return !T::is_equal(*this, rhs); }
#endif
#ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR
#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \
template<class CharT, class Traits> \
friend std::basic_ostream<CharT,Traits>& \
operator<<(std::basic_ostream<CharT,Traits>& os, const T& t)
#endif
#ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR
#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \
template<class CharT, class Traits> \
friend std::basic_istream<CharT,Traits>& \
operator>>(std::basic_istream<CharT,Traits>& is, T& t)
#endif
#ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR
#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \
friend bool operator==(const T& lhs, const T& rhs)
#endif
#ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR
#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \
friend bool operator!=(const T& lhs, const T& rhs) \
{ return !(lhs == rhs); }
#endif
#endif

View File

@ -1,384 +0,0 @@
/* boost random/detail/polynomial.hpp header file
*
* Copyright Steven Watanabe 2014
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP
#define BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP
#include <cstddef>
#include <limits>
#include <vector>
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
namespace boost {
namespace random {
namespace detail {
class polynomial_ops {
public:
typedef unsigned long digit_t;
static void add(std::size_t size, const digit_t * lhs,
const digit_t * rhs, digit_t * output)
{
for(std::size_t i = 0; i < size; ++i) {
output[i] = lhs[i] ^ rhs[i];
}
}
static void add_shifted_inplace(std::size_t size, const digit_t * lhs,
digit_t * output, std::size_t shift)
{
if(shift == 0) {
add(size, lhs, output, output);
return;
}
std::size_t bits = std::numeric_limits<digit_t>::digits;
digit_t prev = 0;
for(std::size_t i = 0; i < size; ++i) {
digit_t tmp = lhs[i];
output[i] ^= (tmp << shift) | (prev >> (bits-shift));
prev = tmp;
}
output[size] ^= (prev >> (bits-shift));
}
static void multiply_simple(std::size_t size, const digit_t * lhs,
const digit_t * rhs, digit_t * output)
{
std::size_t bits = std::numeric_limits<digit_t>::digits;
for(std::size_t i = 0; i < 2*size; ++i) {
output[i] = 0;
}
for(std::size_t i = 0; i < size; ++i) {
for(std::size_t j = 0; j < bits; ++j) {
if((lhs[i] & (digit_t(1) << j)) != 0) {
add_shifted_inplace(size, rhs, output + i, j);
}
}
}
}
// memory requirements: (size - cutoff) * 4 + next_smaller
static void multiply_karatsuba(std::size_t size,
const digit_t * lhs, const digit_t * rhs,
digit_t * output)
{
if(size < 64) {
multiply_simple(size, lhs, rhs, output);
return;
}
// split in half
std::size_t cutoff = size/2;
multiply_karatsuba(cutoff, lhs, rhs, output);
multiply_karatsuba(size - cutoff, lhs + cutoff, rhs + cutoff,
output + cutoff*2);
std::vector<digit_t> local1(size - cutoff);
std::vector<digit_t> local2(size - cutoff);
// combine the digits for the inner multiply
add(cutoff, lhs, lhs + cutoff, &local1[0]);
if(size & 1) local1[cutoff] = lhs[size - 1];
add(cutoff, rhs + cutoff, rhs, &local2[0]);
if(size & 1) local2[cutoff] = rhs[size - 1];
std::vector<digit_t> local3((size - cutoff) * 2);
multiply_karatsuba(size - cutoff, &local1[0], &local2[0], &local3[0]);
add(cutoff * 2, output, &local3[0], &local3[0]);
add((size - cutoff) * 2, output + cutoff*2, &local3[0], &local3[0]);
// Finally, add the inner result
add((size - cutoff) * 2, output + cutoff, &local3[0], output + cutoff);
}
static void multiply_add_karatsuba(std::size_t size,
const digit_t * lhs, const digit_t * rhs,
digit_t * output)
{
std::vector<digit_t> buf(size * 2);
multiply_karatsuba(size, lhs, rhs, &buf[0]);
add(size * 2, &buf[0], output, output);
}
static void multiply(const digit_t * lhs, std::size_t lhs_size,
const digit_t * rhs, std::size_t rhs_size,
digit_t * output)
{
std::fill_n(output, lhs_size + rhs_size, digit_t(0));
multiply_add(lhs, lhs_size, rhs, rhs_size, output);
}
static void multiply_add(const digit_t * lhs, std::size_t lhs_size,
const digit_t * rhs, std::size_t rhs_size,
digit_t * output)
{
// split into pieces that can be passed to
// karatsuba multiply.
while(lhs_size != 0) {
if(lhs_size < rhs_size) {
std::swap(lhs, rhs);
std::swap(lhs_size, rhs_size);
}
multiply_add_karatsuba(rhs_size, lhs, rhs, output);
lhs += rhs_size;
lhs_size -= rhs_size;
output += rhs_size;
}
}
static void copy_bits(const digit_t * x, std::size_t low, std::size_t high,
digit_t * out)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
std::size_t offset = low/bits;
x += offset;
low -= offset*bits;
high -= offset*bits;
std::size_t n = (high-low)/bits;
if(low == 0) {
for(std::size_t i = 0; i < n; ++i) {
out[i] = x[i];
}
} else {
for(std::size_t i = 0; i < n; ++i) {
out[i] = (x[i] >> low) | (x[i+1] << (bits-low));
}
}
if((high-low)%bits) {
digit_t low_mask = (digit_t(1) << ((high-low)%bits)) - 1;
digit_t result = (x[n] >> low);
if(low != 0 && (n+1)*bits < high) {
result |= (x[n+1] << (bits-low));
}
out[n] = (result & low_mask);
}
}
static void shift_left(digit_t * val, std::size_t size, std::size_t shift)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
BOOST_ASSERT(shift > 0);
BOOST_ASSERT(shift < bits);
digit_t prev = 0;
for(std::size_t i = 0; i < size; ++i) {
digit_t tmp = val[i];
val[i] = (prev >> (bits - shift)) | (val[i] << shift);
prev = tmp;
}
}
static digit_t sqr(digit_t val) {
const std::size_t bits = std::numeric_limits<digit_t>::digits;
digit_t mask = (digit_t(1) << bits/2) - 1;
for(std::size_t i = bits; i > 1; i /= 2) {
val = ((val & ~mask) << i/2) | (val & mask);
mask = mask & (mask >> i/4);
mask = mask | (mask << i/2);
}
return val;
}
static void sqr(digit_t * val, std::size_t size)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
digit_t mask = (digit_t(1) << bits/2) - 1;
for(std::size_t i = 0; i < size; ++i) {
digit_t x = val[size - i - 1];
val[(size - i - 1) * 2] = sqr(x & mask);
val[(size - i - 1) * 2 + 1] = sqr(x >> bits/2);
}
}
// optimized for the case when the modulus has few bits set.
struct sparse_mod {
sparse_mod(const digit_t * divisor, std::size_t divisor_bits)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
_remainder_bits = divisor_bits - 1;
for(std::size_t i = 0; i < divisor_bits; ++i) {
if(divisor[i/bits] & (digit_t(1) << i%bits)) {
_bit_indices.push_back(i);
}
}
BOOST_ASSERT(_bit_indices.back() == divisor_bits - 1);
_bit_indices.pop_back();
if(_bit_indices.empty()) {
_block_bits = divisor_bits;
_lower_bits = 0;
} else {
_block_bits = divisor_bits - _bit_indices.back() - 1;
_lower_bits = _bit_indices.back() + 1;
}
_partial_quotient.resize((_block_bits + bits - 1)/bits);
}
void operator()(digit_t * dividend, std::size_t dividend_bits)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
while(dividend_bits > _remainder_bits) {
std::size_t block_start = (std::max)(dividend_bits - _block_bits, _remainder_bits);
std::size_t block_size = (dividend_bits - block_start + bits - 1) / bits;
copy_bits(dividend, block_start, dividend_bits, &_partial_quotient[0]);
for(std::size_t i = 0; i < _bit_indices.size(); ++i) {
std::size_t pos = _bit_indices[i] + block_start - _remainder_bits;
add_shifted_inplace(block_size, &_partial_quotient[0], dividend + pos/bits, pos%bits);
}
add_shifted_inplace(block_size, &_partial_quotient[0], dividend + block_start/bits, block_start%bits);
dividend_bits = block_start;
}
}
std::vector<digit_t> _partial_quotient;
std::size_t _remainder_bits;
std::size_t _block_bits;
std::size_t _lower_bits;
std::vector<std::size_t> _bit_indices;
};
// base should have the same number of bits as mod
// base, and mod should both be able to hold a power
// of 2 >= mod_bits. out needs to be twice as large.
static void mod_pow_x(boost::uintmax_t exponent, const digit_t * mod, std::size_t mod_bits, digit_t * out)
{
const std::size_t bits = std::numeric_limits<digit_t>::digits;
const std::size_t n = (mod_bits + bits - 1) / bits;
const std::size_t highbit = mod_bits - 1;
if(exponent == 0) {
out[0] = 1;
std::fill_n(out + 1, n - 1, digit_t(0));
return;
}
boost::uintmax_t i = std::numeric_limits<boost::uintmax_t>::digits - 1;
while(((boost::uintmax_t(1) << i) & exponent) == 0) {
--i;
}
out[0] = 2;
std::fill_n(out + 1, n - 1, digit_t(0));
sparse_mod m(mod, mod_bits);
while(i--) {
sqr(out, n);
m(out, 2 * mod_bits - 1);
if((boost::uintmax_t(1) << i) & exponent) {
shift_left(out, n, 1);
if(out[highbit / bits] & (digit_t(1) << highbit%bits))
add(n, out, mod, out);
}
}
}
};
class polynomial
{
typedef polynomial_ops::digit_t digit_t;
public:
polynomial() : _size(0) {}
class reference {
public:
reference(digit_t &value, int idx)
: _value(value), _idx(idx) {}
operator bool() const { return (_value & (digit_t(1) << _idx)) != 0; }
reference& operator=(bool b)
{
if(b) {
_value |= (digit_t(1) << _idx);
} else {
_value &= ~(digit_t(1) << _idx);
}
return *this;
}
reference &operator^=(bool b)
{
_value ^= (digit_t(b) << _idx);
return *this;
}
reference &operator=(const reference &other)
{
return *this = static_cast<bool>(other);
}
private:
digit_t &_value;
int _idx;
};
reference operator[](std::size_t i)
{
static const std::size_t bits = std::numeric_limits<digit_t>::digits;
ensure_bit(i);
return reference(_storage[i/bits], i%bits);
}
bool operator[](std::size_t i) const
{
static const std::size_t bits = std::numeric_limits<digit_t>::digits;
if(i < size())
return (_storage[i/bits] & (digit_t(1) << (i%bits))) != 0;
else
return false;
}
std::size_t size() const
{
return _size;
}
void resize(std::size_t n)
{
static const std::size_t bits = std::numeric_limits<digit_t>::digits;
_storage.resize((n + bits - 1)/bits);
// clear the high order bits in case we're shrinking.
if(n%bits) {
_storage.back() &= ((digit_t(1) << (n%bits)) - 1);
}
_size = n;
}
friend polynomial operator*(const polynomial &lhs, const polynomial &rhs);
friend polynomial mod_pow_x(boost::uintmax_t exponent, polynomial mod);
private:
std::vector<polynomial_ops::digit_t> _storage;
std::size_t _size;
void ensure_bit(std::size_t i)
{
if(i >= size()) {
resize(i + 1);
}
}
void normalize()
{
while(size() && (*this)[size() - 1] == 0)
resize(size() - 1);
}
};
inline polynomial operator*(const polynomial &lhs, const polynomial &rhs)
{
polynomial result;
result._storage.resize(lhs._storage.size() + rhs._storage.size());
polynomial_ops::multiply(&lhs._storage[0], lhs._storage.size(),
&rhs._storage[0], rhs._storage.size(),
&result._storage[0]);
result._size = lhs._size + rhs._size;
return result;
}
inline polynomial mod_pow_x(boost::uintmax_t exponent, polynomial mod)
{
polynomial result;
mod.normalize();
std::size_t mod_size = mod.size();
result._storage.resize(mod._storage.size() * 2);
result._size = mod.size() * 2;
polynomial_ops::mod_pow_x(exponent, &mod._storage[0], mod_size, &result._storage[0]);
result.resize(mod.size() - 1);
return result;
}
}
}
}
#endif // BOOST_RANDOM_DETAIL_POLYNOMIAL_HPP

View File

@ -1,67 +0,0 @@
/* boost random/detail/ptr_helper.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_PTR_HELPER_HPP
#define BOOST_RANDOM_DETAIL_PTR_HELPER_HPP
#include <boost/config.hpp>
namespace boost {
namespace random {
namespace detail {
// type_traits could help here, but I don't want to depend on type_traits.
template<class T>
struct ptr_helper
{
typedef T value_type;
typedef T& reference_type;
typedef const T& rvalue_type;
static reference_type ref(T& r) { return r; }
static const T& ref(const T& r) { return r; }
};
template<class T>
struct ptr_helper<T&>
{
typedef T value_type;
typedef T& reference_type;
typedef T& rvalue_type;
static reference_type ref(T& r) { return r; }
static const T& ref(const T& r) { return r; }
};
template<class T>
struct ptr_helper<T*>
{
typedef T value_type;
typedef T& reference_type;
typedef T* rvalue_type;
static reference_type ref(T * p) { return *p; }
static const T& ref(const T * p) { return *p; }
};
} // namespace detail
} // namespace random
} // namespace boost
//
// BOOST_RANDOM_PTR_HELPER_SPEC --
//
// Helper macro for broken compilers defines specializations of
// ptr_helper.
//
# define BOOST_RANDOM_PTR_HELPER_SPEC(T)
#endif // BOOST_RANDOM_DETAIL_PTR_HELPER_HPP

View File

@ -1,115 +0,0 @@
/* boost random/detail/seed.hpp header file
*
* Copyright Steven Watanabe 2009
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_SEED_HPP
#define BOOST_RANDOM_DETAIL_SEED_HPP
#include <boost/config.hpp>
// Sun seems to have trouble with the use of SFINAE for the
// templated constructor. So does Borland.
#if !defined(BOOST_NO_SFINAE) && !defined(__SUNPRO_CC) && !defined(__BORLANDC__)
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/mpl/bool.hpp>
namespace boost {
namespace random {
namespace detail {
template<class T>
struct disable_seed : boost::disable_if<boost::is_arithmetic<T> > {};
template<class Engine, class T>
struct disable_constructor : disable_seed<T> {};
template<class Engine>
struct disable_constructor<Engine, Engine> {};
#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \
template<class Generator> \
explicit Self(Generator& gen, typename ::boost::random::detail::disable_constructor<Self, Generator>::type* = 0)
#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \
template<class Generator> \
void seed(Generator& gen, typename ::boost::random::detail::disable_seed<Generator>::type* = 0)
#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \
template<class SeedSeq> \
explicit Self(SeedSeq& seq, typename ::boost::random::detail::disable_constructor<Self, SeedSeq>::type* = 0)
#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \
template<class SeedSeq> \
void seed(SeedSeq& seq, typename ::boost::random::detail::disable_seed<SeedSeq>::type* = 0)
#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \
explicit Self(const T& x)
#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \
void seed(const T& x)
}
}
}
#else
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/mpl/bool.hpp>
#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \
Self(Self& other) { *this = other; } \
Self(const Self& other) { *this = other; } \
template<class Generator> \
explicit Self(Generator& gen) { \
boost_random_constructor_impl(gen, ::boost::is_arithmetic<Generator>());\
} \
template<class Generator> \
void boost_random_constructor_impl(Generator& gen, ::boost::mpl::false_)
#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \
template<class Generator> \
void seed(Generator& gen) { \
boost_random_seed_impl(gen, ::boost::is_arithmetic<Generator>());\
}\
template<class Generator>\
void boost_random_seed_impl(Generator& gen, ::boost::mpl::false_)
#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \
Self(Self& other) { *this = other; } \
Self(const Self& other) { *this = other; } \
template<class SeedSeq> \
explicit Self(SeedSeq& seq) { \
boost_random_constructor_impl(seq, ::boost::is_arithmetic<SeedSeq>());\
} \
template<class SeedSeq> \
void boost_random_constructor_impl(SeedSeq& seq, ::boost::mpl::false_)
#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \
template<class SeedSeq> \
void seed(SeedSeq& seq) { \
boost_random_seed_impl(seq, ::boost::is_arithmetic<SeedSeq>()); \
} \
template<class SeedSeq> \
void boost_random_seed_impl(SeedSeq& seq, ::boost::mpl::false_)
#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \
explicit Self(const T& x) { boost_random_constructor_impl(x, ::boost::mpl::true_()); }\
void boost_random_constructor_impl(const T& x, ::boost::mpl::true_)
#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \
void seed(const T& x) { boost_random_seed_impl(x, ::boost::mpl::true_()); }\
void boost_random_seed_impl(const T& x, ::boost::mpl::true_)
#endif
#endif

View File

@ -1,398 +0,0 @@
/* boost random/detail/seed.hpp header file
*
* Copyright Steven Watanabe 2009
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_SEED_IMPL_HPP
#define BOOST_RANDOM_DETAIL_SEED_IMPL_HPP
#include <stdexcept>
#include <boost/cstdint.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/random/traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/random/detail/const_mod.hpp>
#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/detail/generator_bits.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
// finds the seed type of an engine, given its
// result_type. If the result_type is integral
// the seed type is the same. If the result_type
// is floating point, the seed type is uint32_t
template<class T>
struct seed_type
{
typedef typename boost::mpl::if_<boost::is_integral<T>,
T,
boost::uint32_t
>::type type;
};
template<int N>
struct const_pow_impl
{
template<class T>
static T call(T arg, int n, T result)
{
return const_pow_impl<N / 2>::call(T(arg * arg), n / 2,
n%2 == 0? result : T(result * arg));
}
};
template<>
struct const_pow_impl<0>
{
template<class T>
static T call(T, int, T result)
{
return result;
}
};
// requires N is an upper bound on n
template<int N, class T>
inline T const_pow(T arg, int n) { return const_pow_impl<N>::call(arg, n, T(1)); }
template<class T>
inline T pow2(int n)
{
typedef unsigned int_type;
const int max_bits = std::numeric_limits<int_type>::digits;
T multiplier = T(int_type(1) << (max_bits - 1)) * 2;
return (int_type(1) << (n % max_bits)) *
const_pow<std::numeric_limits<T>::digits / max_bits>(multiplier, n / max_bits);
}
template<class Engine, class Iter>
void generate_from_real(Engine& eng, Iter begin, Iter end)
{
using std::fmod;
typedef typename Engine::result_type RealType;
const int Bits = detail::generator_bits<Engine>::value();
int remaining_bits = 0;
boost::uint_least32_t saved_bits = 0;
RealType multiplier = pow2<RealType>( Bits);
RealType mult32 = RealType(4294967296.0); // 2^32
while(true) {
RealType val = eng() * multiplier;
int available_bits = Bits;
// Make sure the compiler can optimize this out
// if it isn't possible.
if(Bits < 32 && available_bits < 32 - remaining_bits) {
saved_bits |= boost::uint_least32_t(val) << remaining_bits;
remaining_bits += Bits;
} else {
// If Bits < 32, then remaining_bits != 0, since
// if remaining_bits == 0, available_bits < 32 - 0,
// and we won't get here to begin with.
if(Bits < 32 || remaining_bits != 0) {
boost::uint_least32_t divisor =
(boost::uint_least32_t(1) << (32 - remaining_bits));
boost::uint_least32_t extra_bits = boost::uint_least32_t(fmod(val, mult32)) & (divisor - 1);
val = val / divisor;
*begin++ = saved_bits | (extra_bits << remaining_bits);
if(begin == end) return;
available_bits -= 32 - remaining_bits;
remaining_bits = 0;
}
// If Bits < 32 we should never enter this loop
if(Bits >= 32) {
for(; available_bits >= 32; available_bits -= 32) {
boost::uint_least32_t word = boost::uint_least32_t(fmod(val, mult32));
val /= mult32;
*begin++ = word;
if(begin == end) return;
}
}
remaining_bits = available_bits;
saved_bits = static_cast<boost::uint_least32_t>(val);
}
}
}
template<class Engine, class Iter>
void generate_from_int(Engine& eng, Iter begin, Iter end)
{
typedef typename Engine::result_type IntType;
typedef typename boost::random::traits::make_unsigned<IntType>::type unsigned_type;
int remaining_bits = 0;
boost::uint_least32_t saved_bits = 0;
unsigned_type range = boost::random::detail::subtract<IntType>()((eng.max)(), (eng.min)());
int bits =
(range == (std::numeric_limits<unsigned_type>::max)()) ?
std::numeric_limits<unsigned_type>::digits :
detail::integer_log2(range + 1);
{
int discarded_bits = detail::integer_log2(bits);
unsigned_type excess = (range + 1) >> (bits - discarded_bits);
if(excess != 0) {
int extra_bits = detail::integer_log2((excess - 1) ^ excess);
bits = bits - discarded_bits + extra_bits;
}
}
unsigned_type mask = (static_cast<unsigned_type>(2) << (bits - 1)) - 1;
unsigned_type limit = ((range + 1) & ~mask) - 1;
while(true) {
unsigned_type val;
do {
val = boost::random::detail::subtract<IntType>()(eng(), (eng.min)());
} while(limit != range && val > limit);
val &= mask;
int available_bits = bits;
if(available_bits == 32) {
*begin++ = static_cast<boost::uint_least32_t>(val) & 0xFFFFFFFFu;
if(begin == end) return;
} else if(available_bits % 32 == 0) {
for(int i = 0; i < available_bits / 32; ++i) {
boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu;
int suppress_warning = (bits >= 32);
BOOST_ASSERT(suppress_warning == 1);
val >>= (32 * suppress_warning);
*begin++ = word;
if(begin == end) return;
}
} else if(bits < 32 && available_bits < 32 - remaining_bits) {
saved_bits |= boost::uint_least32_t(val) << remaining_bits;
remaining_bits += bits;
} else {
if(bits < 32 || remaining_bits != 0) {
boost::uint_least32_t extra_bits = boost::uint_least32_t(val) & ((boost::uint_least32_t(1) << (32 - remaining_bits)) - 1);
val >>= 32 - remaining_bits;
*begin++ = saved_bits | (extra_bits << remaining_bits);
if(begin == end) return;
available_bits -= 32 - remaining_bits;
remaining_bits = 0;
}
if(bits >= 32) {
for(; available_bits >= 32; available_bits -= 32) {
boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu;
int suppress_warning = (bits >= 32);
BOOST_ASSERT(suppress_warning == 1);
val >>= (32 * suppress_warning);
*begin++ = word;
if(begin == end) return;
}
}
remaining_bits = available_bits;
saved_bits = static_cast<boost::uint_least32_t>(val);
}
}
}
template<class Engine, class Iter>
void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::true_)
{
return detail::generate_from_int(eng, first, last);
}
template<class Engine, class Iter>
void generate_impl(Engine& eng, Iter first, Iter last, boost::mpl::false_)
{
return detail::generate_from_real(eng, first, last);
}
template<class Engine, class Iter>
void generate(Engine& eng, Iter first, Iter last)
{
return detail::generate_impl(eng, first, last, boost::random::traits::is_integral<typename Engine::result_type>());
}
template<class IntType, IntType m, class SeedSeq>
IntType seed_one_int(SeedSeq& seq)
{
static const int log = ::boost::mpl::if_c<(m == 0),
::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
::boost::static_log2<m> >::type::value;
static const int k =
(log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
::boost::uint_least32_t array[log / 32 + 4];
seq.generate(&array[0], &array[0] + k + 3);
IntType s = 0;
for(int j = 0; j < k; ++j) {
IntType digit = const_mod<IntType, m>::apply(IntType(array[j+3]));
IntType mult = IntType(1) << 32*j;
s = const_mod<IntType, m>::mult_add(mult, digit, s);
}
return s;
}
template<class IntType, IntType m, class Iter>
IntType get_one_int(Iter& first, Iter last)
{
static const int log = ::boost::mpl::if_c<(m == 0),
::boost::mpl::int_<(::std::numeric_limits<IntType>::digits)>,
::boost::static_log2<m> >::type::value;
static const int k =
(log + ((~(static_cast<IntType>(2) << (log - 1)) & m)? 32 : 31)) / 32;
IntType s = 0;
for(int j = 0; j < k; ++j) {
if(first == last) {
boost::throw_exception(::std::invalid_argument("Not enough elements in call to seed."));
}
IntType digit = const_mod<IntType, m>::apply(IntType(*first++));
IntType mult = IntType(1) << 32*j;
s = const_mod<IntType, m>::mult_add(mult, digit, s);
}
return s;
}
// TODO: work in-place whenever possible
template<int w, std::size_t n, class SeedSeq, class UIntType>
void seed_array_int_impl(SeedSeq& seq, UIntType (&x)[n])
{
boost::uint_least32_t storage[((w+31)/32) * n];
seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n);
for(std::size_t j = 0; j < n; j++) {
UIntType val = 0;
for(std::size_t k = 0; k < (w+31)/32; ++k) {
val += static_cast<UIntType>(storage[(w+31)/32*j + k]) << 32*k;
}
x[j] = val & ::boost::low_bits_mask_t<w>::sig_bits;
}
}
template<int w, std::size_t n, class SeedSeq, class IntType>
inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::mpl::true_)
{
BOOST_STATIC_ASSERT_MSG(boost::is_integral<IntType>::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast.");
typedef typename boost::make_unsigned<IntType>::type unsigned_array[n];
seed_array_int_impl<w>(seq, reinterpret_cast<unsigned_array&>(x));
}
template<int w, std::size_t n, class SeedSeq, class IntType>
inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::mpl::false_)
{
seed_array_int_impl<w>(seq, x);
}
template<int w, std::size_t n, class SeedSeq, class IntType>
inline void seed_array_int(SeedSeq& seq, IntType (&x)[n])
{
seed_array_int_impl<w>(seq, x, boost::random::traits::is_signed<IntType>());
}
template<int w, std::size_t n, class Iter, class UIntType>
void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n])
{
for(std::size_t j = 0; j < n; j++) {
UIntType val = 0;
for(std::size_t k = 0; k < (w+31)/32; ++k) {
if(first == last) {
boost::throw_exception(std::invalid_argument("Not enough elements in call to seed."));
}
val += static_cast<UIntType>(*first++) << 32*k;
}
x[j] = val & ::boost::low_bits_mask_t<w>::sig_bits;
}
}
template<int w, std::size_t n, class Iter, class IntType>
inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::true_)
{
BOOST_STATIC_ASSERT_MSG(boost::is_integral<IntType>::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast.");
typedef typename boost::make_unsigned<IntType>::type unsigned_array[n];
fill_array_int_impl<w>(first, last, reinterpret_cast<unsigned_array&>(x));
}
template<int w, std::size_t n, class Iter, class IntType>
inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::mpl::false_)
{
fill_array_int_impl<w>(first, last, x);
}
template<int w, std::size_t n, class Iter, class IntType>
inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n])
{
fill_array_int_impl<w>(first, last, x, boost::random::traits::is_signed<IntType>());
}
template<int w, std::size_t n, class RealType>
void seed_array_real_impl(const boost::uint_least32_t* storage, RealType (&x)[n])
{
boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32));
RealType two32 = 4294967296.0;
const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
unsigned int j;
for(j = 0; j < n; ++j) {
RealType val = RealType(0);
RealType mult = divisor;
for(int k = 0; k < w/32; ++k) {
val += *storage++ * mult;
mult *= two32;
}
if(mask != 0) {
val += (*storage++ & mask) * mult;
}
BOOST_ASSERT(val >= 0);
BOOST_ASSERT(val < 1);
x[j] = val;
}
}
template<int w, std::size_t n, class SeedSeq, class RealType>
void seed_array_real(SeedSeq& seq, RealType (&x)[n])
{
using std::pow;
boost::uint_least32_t storage[((w+31)/32) * n];
seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n);
seed_array_real_impl<w>(storage, x);
}
template<int w, std::size_t n, class Iter, class RealType>
void fill_array_real(Iter& first, Iter last, RealType (&x)[n])
{
boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32));
RealType two32 = 4294967296.0;
const RealType divisor = RealType(1)/detail::pow2<RealType>(w);
unsigned int j;
for(j = 0; j < n; ++j) {
RealType val = RealType(0);
RealType mult = divisor;
for(int k = 0; k < w/32; ++k, ++first) {
if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed."));
val += *first * mult;
mult *= two32;
}
if(mask != 0) {
if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed."));
val += (*first & mask) * mult;
++first;
}
BOOST_ASSERT(val >= 0);
BOOST_ASSERT(val < 1);
x[j] = val;
}
}
}
}
}
#include <boost/random/detail/enable_warnings.hpp>
#endif

View File

@ -1,89 +0,0 @@
/* boost random/detail/signed_unsigned_tools.hpp header file
*
* Copyright Jens Maurer 2006
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*/
#ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
#define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <boost/random/traits.hpp>
namespace boost {
namespace random {
namespace detail {
/*
* Compute x - y, we know that x >= y, return an unsigned value.
*/
template<class T, bool sgn = std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_bounded>
struct subtract { };
template<class T>
struct subtract<T, /* signed */ false>
{
typedef T result_type;
result_type operator()(T x, T y) { return x - y; }
};
template<class T>
struct subtract<T, /* signed */ true>
{
typedef typename boost::random::traits::make_unsigned_or_unbounded<T>::type result_type;
result_type operator()(T x, T y)
{
if (y >= 0) // because x >= y, it follows that x >= 0, too
return result_type(x) - result_type(y);
if (x >= 0) // y < 0
// avoid the nasty two's complement case for y == min()
return result_type(x) + result_type(-(y+1)) + 1;
// both x and y are negative: no signed overflow
return result_type(x - y);
}
};
/*
* Compute x + y, x is unsigned, result fits in type of "y".
*/
template<class T1, class T2, bool sgn = (std::numeric_limits<T2>::is_signed && (std::numeric_limits<T1>::digits >= std::numeric_limits<T2>::digits))>
struct add { };
template<class T1, class T2>
struct add<T1, T2, /* signed or else T2 has more digits than T1 so the cast always works - needed when T2 is a multiprecision type and T1 is a native integer */ false>
{
typedef T2 result_type;
result_type operator()(T1 x, T2 y) { return T2(x) + y; }
};
template<class T1, class T2>
struct add<T1, T2, /* signed */ true>
{
typedef T2 result_type;
result_type operator()(T1 x, T2 y)
{
if (y >= 0)
return T2(x) + y;
// y < 0
if (x > T1(-(y+1))) // result >= 0 after subtraction
// avoid the nasty two's complement edge case for y == min()
return T2(x - T1(-(y+1)) - 1);
// abs(x) < abs(y), thus T2 able to represent x
return T2(x) + y;
}
};
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS

View File

@ -1,76 +0,0 @@
/* boost random/detail/uniform_int_float.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#define BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <boost/integer.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/generator_bits.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
template<class URNG>
class uniform_int_float
{
public:
typedef URNG base_type;
typedef typename base_type::result_type base_result;
typedef typename boost::uint_t<
(std::numeric_limits<boost::uintmax_t>::digits <
std::numeric_limits<base_result>::digits)?
std::numeric_limits<boost::uintmax_t>::digits :
std::numeric_limits<base_result>::digits
>::fast result_type;
uniform_int_float(base_type& rng)
: _rng(rng) {}
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0; }
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{
std::size_t digits = std::numeric_limits<result_type>::digits;
if(detail::generator_bits<URNG>::value() < digits) {
digits = detail::generator_bits<URNG>::value();
}
return (result_type(2) << (digits - 1)) - 1;
}
base_type& base() { return _rng; }
const base_type& base() const { return _rng; }
result_type operator()()
{
base_result range = static_cast<base_result>((max)())+1;
return static_cast<result_type>(_rng() * range);
}
private:
base_type& _rng;
};
} // namespace detail
} // namespace random
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP

View File

@ -1,75 +0,0 @@
/* boost random/vector_io.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_VECTOR_IO_HPP
#define BOOST_RANDOM_DETAIL_VECTOR_IO_HPP
#include <vector>
#include <iosfwd>
#include <istream>
namespace boost {
namespace random {
namespace detail {
template<class CharT, class Traits, class T>
void print_vector(std::basic_ostream<CharT, Traits>& os,
const std::vector<T>& vec)
{
typename std::vector<T>::const_iterator
iter = vec.begin(),
end = vec.end();
os << os.widen('[');
if(iter != end) {
os << *iter;
++iter;
for(; iter != end; ++iter)
{
os << os.widen(' ') << *iter;
}
}
os << os.widen(']');
}
template<class CharT, class Traits, class T>
void read_vector(std::basic_istream<CharT, Traits>& is, std::vector<T>& vec)
{
CharT ch;
if(!(is >> ch)) {
return;
}
if(ch != is.widen('[')) {
is.putback(ch);
is.setstate(std::ios_base::failbit);
return;
}
T val;
while(is >> std::ws >> val) {
vec.push_back(val);
}
if(is.fail()) {
is.clear();
if(!(is >> ch)) {
return;
}
if(ch != is.widen(']')) {
is.putback(ch);
is.setstate(std::ios_base::failbit);
}
}
}
}
}
}
#endif // BOOST_RANDOM_DETAIL_VECTOR_IO_HPP

View File

@ -1,241 +0,0 @@
/* boost random/discard_block.hpp header file
*
* Copyright Jens Maurer 2002
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-03-02 created
*/
#ifndef BOOST_RANDOM_DISCARD_BLOCK_HPP
#define BOOST_RANDOM_DISCARD_BLOCK_HPP
#include <iostream>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
namespace boost {
namespace random {
/**
* The class template \discard_block_engine is a model of
* \pseudo_random_number_generator. It modifies
* another generator by discarding parts of its output.
* Out of every block of @c p results, the first @c r
* will be returned and the rest discarded.
*
* Requires: 0 < p <= r
*/
template<class UniformRandomNumberGenerator, std::size_t p, std::size_t r>
class discard_block_engine
{
typedef typename detail::seed_type<
typename UniformRandomNumberGenerator::result_type>::type seed_type;
public:
typedef UniformRandomNumberGenerator base_type;
typedef typename base_type::result_type result_type;
BOOST_STATIC_CONSTANT(std::size_t, block_size = p);
BOOST_STATIC_CONSTANT(std::size_t, used_block = r);
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(std::size_t, total_block = p);
BOOST_STATIC_CONSTANT(std::size_t, returned_block = r);
BOOST_STATIC_ASSERT(total_block >= returned_block);
/** Uses the default seed for the base generator. */
discard_block_engine() : _rng(), _n(0) { }
/** Constructs a new \discard_block_engine with a copy of rng. */
explicit discard_block_engine(const base_type & rng) : _rng(rng), _n(0) { }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
/** Constructs a new \discard_block_engine with rng. */
explicit discard_block_engine(base_type && rng) : _rng(rng), _n(0) { }
#endif
/**
* Creates a new \discard_block_engine and seeds the underlying
* generator with @c value
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(discard_block_engine,
seed_type, value)
{ _rng.seed(value); _n = 0; }
/**
* Creates a new \discard_block_engine and seeds the underlying
* generator with @c seq
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(discard_block_engine, SeedSeq, seq)
{ _rng.seed(seq); _n = 0; }
/**
* Creates a new \discard_block_engine and seeds the underlying
* generator with first and last.
*/
template<class It> discard_block_engine(It& first, It last)
: _rng(first, last), _n(0) { }
/** default seeds the underlying generator. */
void seed() { _rng.seed(); _n = 0; }
/** Seeds the underlying generator with s. */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(discard_block_engine, seed_type, s)
{ _rng.seed(s); _n = 0; }
/** Seeds the underlying generator with seq. */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(discard_block_engine, SeedSeq, seq)
{ _rng.seed(seq); _n = 0; }
/** Seeds the underlying generator with first and last. */
template<class It> void seed(It& first, It last)
{ _rng.seed(first, last); _n = 0; }
/** Returns the underlying engine. */
const base_type& base() const { return _rng; }
/** Returns the next value of the generator. */
result_type operator()()
{
if(_n >= returned_block) {
// discard values of random number generator
// Don't use discard, since we still need to
// be somewhat compatible with TR1.
// _rng.discard(total_block - _n);
for(std::size_t i = 0; i < total_block - _n; ++i) {
_rng();
}
_n = 0;
}
++_n;
return _rng();
}
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
template<class It>
void generate(It first, It last)
{ detail::generate(*this, first, last); }
/**
* Returns the smallest value that the generator can produce.
* This is the same as the minimum of the underlying generator.
*/
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (base_type::min)(); }
/**
* Returns the largest value that the generator can produce.
* This is the same as the maximum of the underlying generator.
*/
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (base_type::max)(); }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a \discard_block_engine to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const discard_block_engine& s)
{
os << s._rng << ' ' << s._n;
return os;
}
/** Reads a \discard_block_engine from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, discard_block_engine& s)
{
is >> s._rng >> std::ws >> s._n;
return is;
}
#endif
/** Returns true if the two generators will produce identical sequences. */
friend bool operator==(const discard_block_engine& x,
const discard_block_engine& y)
{ return x._rng == y._rng && x._n == y._n; }
/** Returns true if the two generators will produce different sequences. */
friend bool operator!=(const discard_block_engine& x,
const discard_block_engine& y)
{ return !(x == y); }
private:
base_type _rng;
std::size_t _n;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class URNG, std::size_t p, std::size_t r>
const bool discard_block_engine<URNG, p, r>::has_fixed_range;
template<class URNG, std::size_t p, std::size_t r>
const std::size_t discard_block_engine<URNG, p, r>::total_block;
template<class URNG, std::size_t p, std::size_t r>
const std::size_t discard_block_engine<URNG, p, r>::returned_block;
template<class URNG, std::size_t p, std::size_t r>
const std::size_t discard_block_engine<URNG, p, r>::block_size;
template<class URNG, std::size_t p, std::size_t r>
const std::size_t discard_block_engine<URNG, p, r>::used_block;
#endif
/// \cond \show_deprecated
template<class URNG, int p, int r>
class discard_block : public discard_block_engine<URNG, p, r>
{
typedef discard_block_engine<URNG, p, r> base_t;
public:
typedef typename base_t::result_type result_type;
discard_block() {}
template<class T>
discard_block(T& arg) : base_t(arg) {}
template<class T>
discard_block(const T& arg) : base_t(arg) {}
template<class It>
discard_block(It& first, It last) : base_t(first, last) {}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (this->base().min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (this->base().max)(); }
};
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class URNG, std::size_t p, std::size_t r>
struct generator_bits<discard_block_engine<URNG, p, r> > {
static std::size_t value() { return generator_bits<URNG>::value(); }
};
template<class URNG, int p, int r>
struct generator_bits<discard_block<URNG, p, r> > {
static std::size_t value() { return generator_bits<URNG>::value(); }
};
}
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DISCARD_BLOCK_HPP

View File

@ -1,636 +0,0 @@
/* boost random/discrete_distribution.hpp header file
*
* Copyright Steven Watanabe 2009-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_DISCRETE_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_DISCRETE_DISTRIBUTION_HPP_INCLUDED
#include <vector>
#include <limits>
#include <numeric>
#include <utility>
#include <iterator>
#include <boost/assert.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/vector_io.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
template<class IntType, class WeightType>
struct integer_alias_table {
WeightType get_weight(IntType bin) const {
WeightType result = _average;
if(bin < _excess) ++result;
return result;
}
template<class Iter>
WeightType init_average(Iter begin, Iter end) {
WeightType weight_average = 0;
IntType excess = 0;
IntType n = 0;
// weight_average * n + excess == current partial sum
// This is a bit messy, but it's guaranteed not to overflow
for(Iter iter = begin; iter != end; ++iter) {
++n;
if(*iter < weight_average) {
WeightType diff = weight_average - *iter;
weight_average -= diff / n;
if(diff % n > excess) {
--weight_average;
excess += n - diff % n;
} else {
excess -= diff % n;
}
} else {
WeightType diff = *iter - weight_average;
weight_average += diff / n;
if(diff % n < n - excess) {
excess += diff % n;
} else {
++weight_average;
excess -= n - diff % n;
}
}
}
_alias_table.resize(static_cast<std::size_t>(n));
_average = weight_average;
_excess = excess;
return weight_average;
}
void init_empty()
{
_alias_table.clear();
_alias_table.push_back(std::make_pair(static_cast<WeightType>(1),
static_cast<IntType>(0)));
_average = static_cast<WeightType>(1);
_excess = static_cast<IntType>(0);
}
bool operator==(const integer_alias_table& other) const
{
return _alias_table == other._alias_table &&
_average == other._average && _excess == other._excess;
}
static WeightType normalize(WeightType val, WeightType average)
{
return val;
}
static void normalize(std::vector<WeightType>&) {}
template<class URNG>
WeightType test(URNG &urng) const
{
return uniform_int_distribution<WeightType>(0, _average)(urng);
}
bool accept(IntType result, WeightType val) const
{
return result < _excess || val < _average;
}
static WeightType try_get_sum(const std::vector<WeightType>& weights)
{
WeightType result = static_cast<WeightType>(0);
for(typename std::vector<WeightType>::const_iterator
iter = weights.begin(), end = weights.end();
iter != end; ++iter)
{
if((std::numeric_limits<WeightType>::max)() - result > *iter) {
return static_cast<WeightType>(0);
}
result += *iter;
}
return result;
}
template<class URNG>
static WeightType generate_in_range(URNG &urng, WeightType max)
{
return uniform_int_distribution<WeightType>(
static_cast<WeightType>(0), max-1)(urng);
}
typedef std::vector<std::pair<WeightType, IntType> > alias_table_t;
alias_table_t _alias_table;
WeightType _average;
IntType _excess;
};
template<class IntType, class WeightType>
struct real_alias_table {
WeightType get_weight(IntType) const
{
return WeightType(1.0);
}
template<class Iter>
WeightType init_average(Iter first, Iter last)
{
std::size_t size = std::distance(first, last);
WeightType weight_sum =
std::accumulate(first, last, static_cast<WeightType>(0));
_alias_table.resize(size);
return weight_sum / size;
}
void init_empty()
{
_alias_table.clear();
_alias_table.push_back(std::make_pair(static_cast<WeightType>(1),
static_cast<IntType>(0)));
}
bool operator==(const real_alias_table& other) const
{
return _alias_table == other._alias_table;
}
static WeightType normalize(WeightType val, WeightType average)
{
return val / average;
}
static void normalize(std::vector<WeightType>& weights)
{
WeightType sum =
std::accumulate(weights.begin(), weights.end(),
static_cast<WeightType>(0));
for(typename std::vector<WeightType>::iterator
iter = weights.begin(),
end = weights.end();
iter != end; ++iter)
{
*iter /= sum;
}
}
template<class URNG>
WeightType test(URNG &urng) const
{
return uniform_01<WeightType>()(urng);
}
bool accept(IntType, WeightType) const
{
return true;
}
static WeightType try_get_sum(const std::vector<WeightType>& weights)
{
return static_cast<WeightType>(1);
}
template<class URNG>
static WeightType generate_in_range(URNG &urng, WeightType)
{
return uniform_01<WeightType>()(urng);
}
typedef std::vector<std::pair<WeightType, IntType> > alias_table_t;
alias_table_t _alias_table;
};
template<bool IsIntegral>
struct select_alias_table;
template<>
struct select_alias_table<true> {
template<class IntType, class WeightType>
struct apply {
typedef integer_alias_table<IntType, WeightType> type;
};
};
template<>
struct select_alias_table<false> {
template<class IntType, class WeightType>
struct apply {
typedef real_alias_table<IntType, WeightType> type;
};
};
}
/**
* The class @c discrete_distribution models a \random_distribution.
* It produces integers in the range [0, n) with the probability
* of producing each value is specified by the parameters of the
* distribution.
*/
template<class IntType = int, class WeightType = double>
class discrete_distribution {
public:
typedef WeightType input_type;
typedef IntType result_type;
class param_type {
public:
typedef discrete_distribution distribution_type;
/**
* Constructs a @c param_type object, representing a distribution
* with \f$p(0) = 1\f$ and \f$p(k|k>0) = 0\f$.
*/
param_type() : _probabilities(1, static_cast<WeightType>(1)) {}
/**
* If @c first == @c last, equivalent to the default constructor.
* Otherwise, the values of the range represent weights for the
* possible values of the distribution.
*/
template<class Iter>
param_type(Iter first, Iter last) : _probabilities(first, last)
{
normalize();
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* If wl.size() == 0, equivalent to the default constructor.
* Otherwise, the values of the @c initializer_list represent
* weights for the possible values of the distribution.
*/
param_type(const std::initializer_list<WeightType>& wl)
: _probabilities(wl)
{
normalize();
}
#endif
/**
* If the range is empty, equivalent to the default constructor.
* Otherwise, the elements of the range represent
* weights for the possible values of the distribution.
*/
template<class Range>
explicit param_type(const Range& range)
: _probabilities(boost::begin(range), boost::end(range))
{
normalize();
}
/**
* If nw is zero, equivalent to the default constructor.
* Otherwise, the range of the distribution is [0, nw),
* and the weights are found by calling fw with values
* evenly distributed between \f$\mbox{xmin} + \delta/2\f$ and
* \f$\mbox{xmax} - \delta/2\f$, where
* \f$\delta = (\mbox{xmax} - \mbox{xmin})/\mbox{nw}\f$.
*/
template<class Func>
param_type(std::size_t nw, double xmin, double xmax, Func fw)
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_probabilities.push_back(fw(xmin + k*delta + delta/2));
}
normalize();
}
/**
* Returns a vector containing the probabilities of each possible
* value of the distribution.
*/
std::vector<WeightType> probabilities() const
{
return _probabilities;
}
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
detail::print_vector(os, parm._probabilities);
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
std::vector<WeightType> temp;
detail::read_vector(is, temp);
if(is) {
parm._probabilities.swap(temp);
}
return is;
}
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{
return lhs._probabilities == rhs._probabilities;
}
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
/// @cond show_private
friend class discrete_distribution;
explicit param_type(const discrete_distribution& dist)
: _probabilities(dist.probabilities())
{}
void normalize()
{
impl_type::normalize(_probabilities);
}
std::vector<WeightType> _probabilities;
/// @endcond
};
/**
* Creates a new @c discrete_distribution object that has
* \f$p(0) = 1\f$ and \f$p(i|i>0) = 0\f$.
*/
discrete_distribution()
{
_impl.init_empty();
}
/**
* Constructs a discrete_distribution from an iterator range.
* If @c first == @c last, equivalent to the default constructor.
* Otherwise, the values of the range represent weights for the
* possible values of the distribution.
*/
template<class Iter>
discrete_distribution(Iter first, Iter last)
{
init(first, last);
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a @c discrete_distribution from a @c std::initializer_list.
* If the @c initializer_list is empty, equivalent to the default
* constructor. Otherwise, the values of the @c initializer_list
* represent weights for the possible values of the distribution.
* For example, given the distribution
*
* @code
* discrete_distribution<> dist{1, 4, 5};
* @endcode
*
* The probability of a 0 is 1/10, the probability of a 1 is 2/5,
* the probability of a 2 is 1/2, and no other values are possible.
*/
discrete_distribution(std::initializer_list<WeightType> wl)
{
init(wl.begin(), wl.end());
}
#endif
/**
* Constructs a discrete_distribution from a Boost.Range range.
* If the range is empty, equivalent to the default constructor.
* Otherwise, the values of the range represent weights for the
* possible values of the distribution.
*/
template<class Range>
explicit discrete_distribution(const Range& range)
{
init(boost::begin(range), boost::end(range));
}
/**
* Constructs a discrete_distribution that approximates a function.
* If nw is zero, equivalent to the default constructor.
* Otherwise, the range of the distribution is [0, nw),
* and the weights are found by calling fw with values
* evenly distributed between \f$\mbox{xmin} + \delta/2\f$ and
* \f$\mbox{xmax} - \delta/2\f$, where
* \f$\delta = (\mbox{xmax} - \mbox{xmin})/\mbox{nw}\f$.
*/
template<class Func>
discrete_distribution(std::size_t nw, double xmin, double xmax, Func fw)
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
BOOST_ASSERT(delta > 0);
std::vector<WeightType> weights;
for(std::size_t k = 0; k < n; ++k) {
weights.push_back(fw(xmin + k*delta + delta/2));
}
init(weights.begin(), weights.end());
}
/**
* Constructs a discrete_distribution from its parameters.
*/
explicit discrete_distribution(const param_type& parm)
{
param(parm);
}
/**
* Returns a value distributed according to the parameters of the
* discrete_distribution.
*/
template<class URNG>
IntType operator()(URNG& urng) const
{
BOOST_ASSERT(!_impl._alias_table.empty());
IntType result;
WeightType test;
do {
result = uniform_int_distribution<IntType>((min)(), (max)())(urng);
test = _impl.test(urng);
} while(!_impl.accept(result, test));
if(test < _impl._alias_table[static_cast<std::size_t>(result)].first) {
return result;
} else {
return(_impl._alias_table[static_cast<std::size_t>(result)].second);
}
}
/**
* Returns a value distributed according to the parameters
* specified by param.
*/
template<class URNG>
IntType operator()(URNG& urng, const param_type& parm) const
{
if(WeightType limit = impl_type::try_get_sum(parm._probabilities)) {
WeightType val = impl_type::generate_in_range(urng, limit);
WeightType sum = 0;
std::size_t result = 0;
for(typename std::vector<WeightType>::const_iterator
iter = parm._probabilities.begin(),
end = parm._probabilities.end();
iter != end; ++iter, ++result)
{
sum += *iter;
if(sum > val) {
return result;
}
}
// This shouldn't be reachable, but round-off error
// can prevent any match from being found when val is
// very close to 1.
return static_cast<IntType>(parm._probabilities.size() - 1);
} else {
// WeightType is integral and sum(parm._probabilities)
// would overflow. Just use the easy solution.
return discrete_distribution(parm)(urng);
}
}
/** Returns the smallest value that the distribution can produce. */
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/** Returns the largest value that the distribution can produce. */
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return static_cast<result_type>(_impl._alias_table.size() - 1); }
/**
* Returns a vector containing the probabilities of each
* value of the distribution. For example, given
*
* @code
* discrete_distribution<> dist = { 1, 4, 5 };
* std::vector<double> p = dist.param();
* @endcode
*
* the vector, p will contain {0.1, 0.4, 0.5}.
*
* If @c WeightType is integral, then the weights
* will be returned unchanged.
*/
std::vector<WeightType> probabilities() const
{
std::vector<WeightType> result(_impl._alias_table.size(), static_cast<WeightType>(0));
std::size_t i = 0;
for(typename impl_type::alias_table_t::const_iterator
iter = _impl._alias_table.begin(),
end = _impl._alias_table.end();
iter != end; ++iter, ++i)
{
WeightType val = iter->first;
result[i] += val;
result[static_cast<std::size_t>(iter->second)] += _impl.get_weight(i) - val;
}
impl_type::normalize(result);
return(result);
}
/** Returns the parameters of the distribution. */
param_type param() const
{
return param_type(*this);
}
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
init(parm._probabilities.begin(), parm._probabilities.end());
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() {}
/** Writes a distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, discrete_distribution, dd)
{
os << dd.param();
return os;
}
/** Reads a distribution from a @c std::istream */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, discrete_distribution, dd)
{
param_type parm;
if(is >> parm) {
dd.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will return the
* same sequence of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(discrete_distribution, lhs, rhs)
{
return lhs._impl == rhs._impl;
}
/**
* Returns true if the two distributions may return different
* sequences of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(discrete_distribution)
private:
/// @cond show_private
template<class Iter>
void init(Iter first, Iter last, std::input_iterator_tag)
{
std::vector<WeightType> temp(first, last);
init(temp.begin(), temp.end());
}
template<class Iter>
void init(Iter first, Iter last, std::forward_iterator_tag)
{
std::vector<std::pair<WeightType, IntType> > below_average;
std::vector<std::pair<WeightType, IntType> > above_average;
WeightType weight_average = _impl.init_average(first, last);
WeightType normalized_average = _impl.get_weight(0);
std::size_t i = 0;
for(; first != last; ++first, ++i) {
WeightType val = impl_type::normalize(*first, weight_average);
std::pair<WeightType, IntType> elem(val, static_cast<IntType>(i));
if(val < normalized_average) {
below_average.push_back(elem);
} else {
above_average.push_back(elem);
}
}
typename impl_type::alias_table_t::iterator
b_iter = below_average.begin(),
b_end = below_average.end(),
a_iter = above_average.begin(),
a_end = above_average.end()
;
while(b_iter != b_end && a_iter != a_end) {
_impl._alias_table[static_cast<std::size_t>(b_iter->second)] =
std::make_pair(b_iter->first, a_iter->second);
a_iter->first -= (_impl.get_weight(b_iter->second) - b_iter->first);
if(a_iter->first < normalized_average) {
*b_iter = *a_iter++;
} else {
++b_iter;
}
}
for(; b_iter != b_end; ++b_iter) {
_impl._alias_table[static_cast<std::size_t>(b_iter->second)].first =
_impl.get_weight(b_iter->second);
}
for(; a_iter != a_end; ++a_iter) {
_impl._alias_table[static_cast<std::size_t>(a_iter->second)].first =
_impl.get_weight(a_iter->second);
}
}
template<class Iter>
void init(Iter first, Iter last)
{
if(first == last) {
_impl.init_empty();
} else {
typename std::iterator_traits<Iter>::iterator_category category;
init(first, last, category);
}
}
typedef typename detail::select_alias_table<
(::boost::is_integral<WeightType>::value)
>::template apply<IntType, WeightType>::type impl_type;
impl_type _impl;
/// @endcond
};
}
}
#include <boost/random/detail/enable_warnings.hpp>
#endif

View File

@ -1,386 +0,0 @@
/* boost random/exponential_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Copyright Jason Rhinelander 2016
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/int_float_pair.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
namespace detail {
// tables for the ziggurat algorithm
template<class RealType>
struct exponential_table {
static const RealType table_x[257];
static const RealType table_y[257];
};
template<class RealType>
const RealType exponential_table<RealType>::table_x[257] = {
8.6971174701310497140, 7.6971174701310497140, 6.9410336293772123602, 6.4783784938325698538,
6.1441646657724730491, 5.8821443157953997963, 5.6664101674540337371, 5.4828906275260628694,
5.3230905057543986131, 5.1814872813015010392, 5.0542884899813047117, 4.9387770859012514838,
4.8329397410251125881, 4.7352429966017412526, 4.6444918854200854873, 4.5597370617073515513,
4.4802117465284221949, 4.4052876934735729805, 4.3344436803172730116, 4.2672424802773661873,
4.2033137137351843802, 4.1423408656640511251, 4.0840513104082974638, 4.0282085446479365106,
3.9746060666737884793, 3.9230625001354895926, 3.8734176703995089983, 3.8255294185223367372,
3.7792709924116678992, 3.7345288940397975350, 3.6912010902374189454, 3.6491955157608538478,
3.6084288131289096339, 3.5688252656483374051, 3.5303158891293438633, 3.4928376547740601814,
3.4563328211327607625, 3.4207483572511205323, 3.3860354424603017887, 3.3521490309001100106,
3.3190474709707487166, 3.2866921715990692095, 3.2550473085704501813, 3.2240795652862645207,
3.1937579032122407483, 3.1640533580259734580, 3.1349388580844407393, 3.1063890623398246660,
3.0783802152540905188, 3.0508900166154554479, 3.0238975044556767713, 2.9973829495161306949,
2.9713277599210896472, 2.9457143948950456386, 2.9205262865127406647, 2.8957477686001416838,
2.8713640120155362592, 2.8473609656351888266, 2.8237253024500354905, 2.8004443702507381944,
2.7775061464397572041, 2.7548991965623453650, 2.7326126361947007411, 2.7106360958679293686,
2.6889596887418041593, 2.6675739807732670816, 2.6464699631518093905, 2.6256390267977886123,
2.6050729387408355373, 2.5847638202141406911, 2.5647041263169053687, 2.5448866271118700928,
2.5253043900378279427, 2.5059507635285939648, 2.4868193617402096807, 2.4679040502973649846,
2.4491989329782498908, 2.4306983392644199088, 2.4123968126888708336, 2.3942890999214583288,
2.3763701405361408194, 2.3586350574093374601, 2.3410791477030346875, 2.3236978743901964559,
2.3064868582835798692, 2.2894418705322694265, 2.2725588255531546952, 2.2558337743672190441,
2.2392628983129087111, 2.2228425031110364013, 2.2065690132576635755, 2.1904389667232199235,
2.1744490099377744673, 2.1585958930438856781, 2.1428764653998416425, 2.1272876713173679737,
2.1118265460190418108, 2.0964902118017147637, 2.0812758743932248696, 2.0661808194905755036,
2.0512024094685848641, 2.0363380802487695916, 2.0215853383189260770, 2.0069417578945183144,
1.9924049782135764992, 1.9779727009573602295, 1.9636426877895480401, 1.9494127580071845659,
1.9352807862970511135, 1.9212447005915276767, 1.9073024800183871196, 1.8934521529393077332,
1.8796917950722108462, 1.8660195276928275962, 1.8524335159111751661, 1.8389319670188793980,
1.8255131289035192212, 1.8121752885263901413, 1.7989167704602903934, 1.7857359354841254047,
1.7726311792313049959, 1.7596009308890742369, 1.7466436519460739352, 1.7337578349855711926,
1.7209420025219350428, 1.7081947058780575683, 1.6955145241015377061, 1.6829000629175537544,
1.6703499537164519163, 1.6578628525741725325, 1.6454374393037234057, 1.6330724165359912048,
1.6207665088282577216, 1.6085184617988580769, 1.5963270412864831349, 1.5841910325326886695,
1.5721092393862294810, 1.5600804835278879161, 1.5481036037145133070, 1.5361774550410318943,
1.5243009082192260050, 1.5124728488721167573, 1.5006921768428164936, 1.4889578055167456003,
1.4772686611561334579, 1.4656236822457450411, 1.4540218188487932264, 1.4424620319720121876,
1.4309432929388794104, 1.4194645827699828254, 1.4080248915695353509, 1.3966232179170417110,
1.3852585682631217189, 1.3739299563284902176, 1.3626364025050864742, 1.3513769332583349176,
1.3401505805295045843, 1.3289563811371163220, 1.3177933761763245480, 1.3066606104151739482,
1.2955571316866007210, 1.2844819902750125450, 1.2734342382962410994, 1.2624129290696153434,
1.2514171164808525098, 1.2404458543344064544, 1.2294981956938491599, 1.2185731922087903071,
1.2076698934267612830, 1.1967873460884031665, 1.1859245934042023557, 1.1750806743109117687,
1.1642546227056790397, 1.1534454666557748056, 1.1426522275816728928, 1.1318739194110786733,
1.1211095477013306083, 1.1103581087274114281, 1.0996185885325976575, 1.0888899619385472598,
1.0781711915113727024, 1.0674612264799681530, 1.0567590016025518414, 1.0460634359770445503,
1.0353734317905289496, 1.0246878730026178052, 1.0140056239570971074, 1.0033255279156973717,
0.99264640550727647009, 0.98196705308506317914, 0.97128624098390397896, 0.96060271166866709917,
0.94991517776407659940, 0.93922231995526297952, 0.92852278474721113999, 0.91781518207004493915,
0.90709808271569100600, 0.89637001558989069006, 0.88562946476175228052, 0.87487486629102585352,
0.86410460481100519511, 0.85331700984237406386, 0.84251035181036928333, 0.83168283773427388393,
0.82083260655441252290, 0.80995772405741906620, 0.79905617735548788109, 0.78812586886949324977,
0.77716460975913043936, 0.76617011273543541328, 0.75513998418198289808, 0.74407171550050873971,
0.73296267358436604916, 0.72181009030875689912, 0.71061105090965570413, 0.69936248110323266174,
0.68806113277374858613, 0.67670356802952337911, 0.66528614139267855405, 0.65380497984766565353,
0.64225596042453703448, 0.63063468493349100113, 0.61893645139487678178, 0.60715622162030085137,
0.59528858429150359384, 0.58332771274877027785, 0.57126731653258903915, 0.55910058551154127652,
0.54682012516331112550, 0.53441788123716615385, 0.52188505159213564105, 0.50921198244365495319,
0.49638804551867159754, 0.48340149165346224782, 0.47023927508216945338, 0.45688684093142071279,
0.44332786607355296305, 0.42954394022541129589, 0.41551416960035700100, 0.40121467889627836229,
0.38661797794112021568, 0.37169214532991786118, 0.35639976025839443721, 0.34069648106484979674,
0.32452911701691008547, 0.30783295467493287307, 0.29052795549123115167, 0.27251318547846547924,
0.25365836338591284433, 0.23379048305967553619, 0.21267151063096745264, 0.18995868962243277774,
0.16512762256418831796, 0.13730498094001380420, 0.10483850756582017915, 0.063852163815003480173,
0
};
template<class RealType>
const RealType exponential_table<RealType>::table_y[257] = {
0, 0.00045413435384149675545, 0.00096726928232717452884, 0.0015362997803015723824,
0.0021459677437189061793, 0.0027887987935740759640, 0.0034602647778369039855, 0.0041572951208337952532,
0.0048776559835423925804, 0.0056196422072054831710, 0.0063819059373191794422, 0.0071633531836349841425,
0.0079630774380170392396, 0.0087803149858089752347, 0.0096144136425022094101, 0.010464810181029979488,
0.011331013597834597488, 0.012212592426255380661, 0.013109164931254991070, 0.014020391403181937334,
0.014945968011691148079, 0.015885621839973162490, 0.016839106826039946359, 0.017806200410911360563,
0.018786700744696029497, 0.019780424338009741737, 0.020787204072578117603, 0.021806887504283582125,
0.022839335406385238829, 0.023884420511558170348, 0.024942026419731782971, 0.026012046645134218076,
0.027094383780955798424, 0.028188948763978634421, 0.029295660224637394015, 0.030414443910466605492,
0.031545232172893605499, 0.032687963508959533317, 0.033842582150874329031, 0.035009037697397411067,
0.036187284781931419754, 0.037377282772959360128, 0.038578995503074859626, 0.039792391023374122670,
0.041017441380414820816, 0.042254122413316231413, 0.043502413568888183301, 0.044762297732943280694,
0.046033761076175166762, 0.047316792913181548703, 0.048611385573379494401, 0.049917534282706374944,
0.051235237055126279830, 0.052564494593071689595, 0.053905310196046085104, 0.055257689676697038322,
0.056621641283742874438, 0.057997175631200659098, 0.059384305633420264487, 0.060783046445479636051,
0.062193415408540996150, 0.063615431999807331076, 0.065049117786753755036, 0.066494496385339779043,
0.067951593421936607770, 0.069420436498728751675, 0.070901055162371828426, 0.072393480875708743023,
0.073897746992364746308, 0.075413888734058408453, 0.076941943170480510100, 0.078481949201606426042,
0.080033947542319910023, 0.081597980709237420930, 0.083174093009632380354, 0.084762330532368125386,
0.086362741140756912277, 0.087975374467270219300, 0.089600281910032864534, 0.091237516631040162057,
0.092887133556043546523, 0.094549189376055853718, 0.096223742550432800103, 0.097910853311492199618,
0.099610583670637128826, 0.10132299742595363588, 0.10304816017125771553, 0.10478613930657016928,
0.10653700405000166218, 0.10830082545103379867, 0.11007767640518539026, 0.11186763167005629731,
0.11367076788274431301, 0.11548716357863353664, 0.11731689921155557057, 0.11916005717532768467,
0.12101672182667483729, 0.12288697950954513498, 0.12477091858083096578, 0.12666862943751066518,
0.12858020454522817870, 0.13050573846833078225, 0.13244532790138752023, 0.13439907170221363078,
0.13636707092642885841, 0.13834942886358021406, 0.14034625107486244210, 0.14235764543247220043,
0.14438372216063476473, 0.14642459387834493787, 0.14848037564386679222, 0.15055118500103990354,
0.15263714202744286154, 0.15473836938446807312, 0.15685499236936522013, 0.15898713896931420572,
0.16113493991759203183, 0.16329852875190180795, 0.16547804187493600915, 0.16767361861725019322,
0.16988540130252766513, 0.17211353531532005700, 0.17435816917135348788, 0.17661945459049489581,
0.17889754657247831241, 0.18119260347549629488, 0.18350478709776746150, 0.18583426276219711495,
0.18818119940425430485, 0.19054576966319540013, 0.19292814997677133873, 0.19532852067956322315,
0.19774706610509886464, 0.20018397469191127727, 0.20263943909370901930, 0.20511365629383770880,
0.20760682772422204205, 0.21011915938898825914, 0.21265086199297827522, 0.21520215107537867786,
0.21777324714870053264, 0.22036437584335949720, 0.22297576805812018050, 0.22560766011668406495,
0.22826029393071670664, 0.23093391716962742173, 0.23362878343743333945, 0.23634515245705964715,
0.23908329026244917002, 0.24184346939887722761, 0.24462596913189210901, 0.24743107566532763894,
0.25025908236886230967, 0.25311029001562948171, 0.25598500703041538015, 0.25888354974901621678,
0.26180624268936295243, 0.26475341883506220209, 0.26772541993204481808, 0.27072259679906003167,
0.27374530965280298302, 0.27679392844851734458, 0.27986883323697289920, 0.28297041453878076010,
0.28609907373707684673, 0.28925522348967773308, 0.29243928816189258772, 0.29565170428126120948,
0.29889292101558177099, 0.30216340067569352897, 0.30546361924459023541, 0.30879406693456016794,
0.31215524877417956945, 0.31554768522712893632, 0.31897191284495723773, 0.32242848495608914289,
0.32591797239355619822, 0.32944096426413633091, 0.33299806876180896713, 0.33658991402867758144,
0.34021714906678004560, 0.34388044470450243010, 0.34758049462163698567, 0.35131801643748334681,
0.35509375286678745925, 0.35890847294874976196, 0.36276297335481777335, 0.36665807978151414890,
0.37059464843514599421, 0.37457356761590215193, 0.37859575940958081092, 0.38266218149600982112,
0.38677382908413768115, 0.39093173698479710717, 0.39513698183329015336, 0.39939068447523107877,
0.40369401253053026739, 0.40804818315203238238, 0.41245446599716116772, 0.41691418643300289465,
0.42142872899761659635, 0.42599954114303435739, 0.43062813728845883923, 0.43531610321563659758,
0.44006510084235387501, 0.44487687341454851593, 0.44975325116275498919, 0.45469615747461548049,
0.45970761564213768669, 0.46478975625042618067, 0.46994482528395999841, 0.47517519303737738299,
0.48048336393045423016, 0.48587198734188493564, 0.49134386959403255500, 0.49690198724154955294,
0.50254950184134769289, 0.50828977641064283495, 0.51412639381474855788, 0.52006317736823356823,
0.52610421398361972602, 0.53225388026304326945, 0.53851687200286186590, 0.54489823767243963663,
0.55140341654064131685, 0.55803828226258748140, 0.56480919291240022434, 0.57172304866482579008,
0.57878735860284503057, 0.58601031847726802755, 0.59340090169173341521, 0.60096896636523224742,
0.60872538207962206507, 0.61668218091520762326, 0.62485273870366592605, 0.63325199421436607968,
0.64189671642726607018, 0.65080583341457104881, 0.66000084107899974178, 0.66950631673192477684,
0.67935057226476538741, 0.68956649611707798890, 0.70019265508278816709, 0.71127476080507597882,
0.72286765959357200702, 0.73503809243142351530, 0.74786862198519510742, 0.76146338884989624862,
0.77595685204011559675, 0.79152763697249565519, 0.80842165152300838005, 0.82699329664305033399,
0.84778550062398962096, 0.87170433238120363669, 0.90046992992574643800, 0.93814368086217467916,
1
};
template<class RealType = double>
struct unit_exponential_distribution
{
template<class Engine>
RealType operator()(Engine& eng) {
const double * const table_x = exponential_table<double>::table_x;
const double * const table_y = exponential_table<double>::table_y;
RealType shift(0);
for(;;) {
std::pair<RealType, int> vals = generate_int_float_pair<RealType, 8>(eng);
int i = vals.second;
RealType x = vals.first * RealType(table_x[i]);
if(x < RealType(table_x[i + 1])) return shift + x;
// For i=0 we need to generate from the tail, but because this is an exponential
// distribution, the tail looks exactly like the body, so we can simply repeat with a
// shift:
if (i == 0) shift += RealType(table_x[1]);
else {
RealType y01 = uniform_01<RealType>()(eng);
RealType y = RealType(table_y[i]) + y01 * RealType(table_y[i+1] - table_y[i]);
// All we care about is whether these are < or > 0; these values are equal to
// (lbound) or proportional to (ubound) `y` minus the lower/upper bound.
RealType y_above_ubound = RealType(table_x[i] - table_x[i+1]) * y01 - (RealType(table_x[i]) - x),
y_above_lbound = y - (RealType(table_y[i+1]) + (RealType(table_x[i+1]) - x) * RealType(table_y[i+1]));
if (y_above_ubound < 0 // if above the upper bound reject immediately
&&
(
y_above_lbound < 0 // If below the lower bound accept immediately
||
y < f(x) // Otherwise it's between the bounds and we need a full check
)
) {
return x + shift;
}
}
}
}
static RealType f(RealType x) {
using std::exp;
return exp(-x);
}
};
} // namespace detail
/**
* The exponential distribution is a model of \random_distribution with
* a single parameter lambda.
*
* It has \f$\displaystyle p(x) = \lambda e^{-\lambda x}\f$
*
* The implementation uses the "ziggurat" algorithm, as described in
*
* @blockquote
* "The Ziggurat Method for Generating Random Variables",
* George Marsaglia and Wai Wan Tsang, Journal of Statistical Software
* Volume 5, Number 8 (2000), 1-7.
* @endblockquote
*/
template<class RealType = double>
class exponential_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type
{
public:
typedef exponential_distribution distribution_type;
/**
* Constructs parameters with a given lambda.
*
* Requires: lambda > 0
*/
param_type(RealType lambda_arg = RealType(1.0))
: _lambda(lambda_arg) { BOOST_ASSERT(_lambda > RealType(0)); }
/** Returns the lambda parameter of the distribution. */
RealType lambda() const { return _lambda; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._lambda;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._lambda;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._lambda == rhs._lambda; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _lambda;
};
/**
* Constructs an exponential_distribution with a given lambda.
*
* Requires: lambda > 0
*/
explicit exponential_distribution(RealType lambda_arg = RealType(1.0))
: _lambda(lambda_arg) { BOOST_ASSERT(_lambda > RealType(0)); }
/**
* Constructs an exponential_distribution from its parameters
*/
explicit exponential_distribution(const param_type& parm)
: _lambda(parm.lambda()) {}
// compiler-generated copy ctor and assignment operator are fine
/** Returns the lambda parameter of the distribution. */
RealType lambda() const { return _lambda; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(0); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_lambda); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm) { _lambda = parm.lambda(); }
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/**
* Returns a random variate distributed according to the
* exponential distribution.
*/
template<class Engine>
result_type operator()(Engine& eng) const
{
detail::unit_exponential_distribution<RealType> impl;
return impl(eng) / _lambda;
}
/**
* Returns a random variate distributed according to the exponential
* distribution with parameters specified by param.
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{
return exponential_distribution(parm)(eng);
}
/** Writes the distribution to a std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, exponential_distribution, ed)
{
os << ed._lambda;
return os;
}
/** Reads the distribution from a std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, exponential_distribution, ed)
{
is >> ed._lambda;
return is;
}
/**
* Returns true iff the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(exponential_distribution, lhs, rhs)
{ return lhs._lambda == rhs._lambda; }
/**
* Returns true iff the two distributions will produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(exponential_distribution)
private:
result_type _lambda;
};
} // namespace random
using random::exponential_distribution;
} // namespace boost
#endif // BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP

View File

@ -1,177 +0,0 @@
/* boost random/extreme_value_distribution.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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_EXTREME_VALUE_DISTRIBUTION_HPP
#define BOOST_RANDOM_EXTREME_VALUE_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <istream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
/**
* The extreme value distribution is a real valued distribution with two
* parameters a and b.
*
* It has \f$\displaystyle p(x) = \frac{1}{b}e^{\frac{a-x}{b} - e^\frac{a-x}{b}}\f$.
*/
template<class RealType = double>
class extreme_value_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef extreme_value_distribution distribution_type;
/**
* Constructs a @c param_type from the "a" and "b" parameters
* of the distribution.
*
* Requires: b > 0
*/
explicit param_type(RealType a_arg = 1.0, RealType b_arg = 1.0)
: _a(a_arg), _b(b_arg)
{}
/** Returns the "a" parameter of the distribtuion. */
RealType a() const { return _a; }
/** Returns the "b" parameter of the distribution. */
RealType b() const { return _b; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._a << ' ' << parm._b; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._a >> std::ws >> parm._b; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _a;
RealType _b;
};
/**
* Constructs an @c extreme_value_distribution from its "a" and "b" parameters.
*
* Requires: b > 0
*/
explicit extreme_value_distribution(RealType a_arg = 1.0, RealType b_arg = 1.0)
: _a(a_arg), _b(b_arg)
{}
/** Constructs an @c extreme_value_distribution from its parameters. */
explicit extreme_value_distribution(const param_type& parm)
: _a(parm.a()), _b(parm.b())
{}
/**
* Returns a random variate distributed according to the
* @c extreme_value_distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
using std::log;
return _a - log(-log(uniform_01<RealType>()(urng))) * _b;
}
/**
* Returns a random variate distributed accordint to the extreme
* value distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return extreme_value_distribution(parm)(urng);
}
/** Returns the "a" parameter of the distribution. */
RealType a() const { return _a; }
/** Returns the "b" parameter of the distribution. */
RealType b() const { return _b; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -std::numeric_limits<RealType>::infinity(); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_a, _b); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_a = parm.a();
_b = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Writes an @c extreme_value_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, extreme_value_distribution, wd)
{
os << wd.param();
return os;
}
/** Reads an @c extreme_value_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, extreme_value_distribution, wd)
{
param_type parm;
if(is >> parm) {
wd.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c extreme_value_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(extreme_value_distribution, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b; }
/**
* Returns true if the two instances of @c extreme_value_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(extreme_value_distribution)
private:
RealType _a;
RealType _b;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_EXTREME_VALUE_DISTRIBUTION_HPP

View File

@ -1,183 +0,0 @@
/* boost random/fisher_f_distribution.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_FISHER_F_DISTRIBUTION_HPP
#define BOOST_RANDOM_FISHER_F_DISTRIBUTION_HPP
#include <iosfwd>
#include <istream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/chi_squared_distribution.hpp>
namespace boost {
namespace random {
/**
* The Fisher F distribution is a real valued distribution with two
* parameters m and n.
*
* It has \f$\displaystyle p(x) =
* \frac{\Gamma((m+n)/2)}{\Gamma(m/2)\Gamma(n/2)}
* \left(\frac{m}{n}\right)^{m/2}
* x^{(m/2)-1} \left(1+\frac{mx}{n}\right)^{-(m+n)/2}
* \f$.
*/
template<class RealType = double>
class fisher_f_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef fisher_f_distribution distribution_type;
/**
* Constructs a @c param_type from the "m" and "n" parameters
* of the distribution.
*
* Requires: m > 0 and n > 0
*/
explicit param_type(RealType m_arg = RealType(1.0),
RealType n_arg = RealType(1.0))
: _m(m_arg), _n(n_arg)
{}
/** Returns the "m" parameter of the distribtuion. */
RealType m() const { return _m; }
/** Returns the "n" parameter of the distribution. */
RealType n() const { return _n; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._m << ' ' << parm._n; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._m >> std::ws >> parm._n; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._m == rhs._m && lhs._n == rhs._n; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _m;
RealType _n;
};
/**
* Constructs a @c fisher_f_distribution from its "m" and "n" parameters.
*
* Requires: m > 0 and n > 0
*/
explicit fisher_f_distribution(RealType m_arg = RealType(1.0),
RealType n_arg = RealType(1.0))
: _impl_m(m_arg), _impl_n(n_arg)
{}
/** Constructs an @c fisher_f_distribution from its parameters. */
explicit fisher_f_distribution(const param_type& parm)
: _impl_m(parm.m()), _impl_n(parm.n())
{}
/**
* Returns a random variate distributed according to the
* F distribution.
*/
template<class URNG>
RealType operator()(URNG& urng)
{
return (_impl_m(urng) * n()) / (_impl_n(urng) * m());
}
/**
* Returns a random variate distributed according to the
* F distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return fisher_f_distribution(parm)(urng);
}
/** Returns the "m" parameter of the distribution. */
RealType m() const { return _impl_m.n(); }
/** Returns the "n" parameter of the distribution. */
RealType n() const { return _impl_n.n(); }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(m(), n()); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
typedef chi_squared_distribution<RealType> impl_type;
typename impl_type::param_type m_param(parm.m());
_impl_m.param(m_param);
typename impl_type::param_type n_param(parm.n());
_impl_n.param(n_param);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Writes an @c fisher_f_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, fisher_f_distribution, fd)
{
os << fd.param();
return os;
}
/** Reads an @c fisher_f_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, fisher_f_distribution, fd)
{
param_type parm;
if(is >> parm) {
fd.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c fisher_f_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(fisher_f_distribution, lhs, rhs)
{ return lhs._impl_m == rhs._impl_m && lhs._impl_n == rhs._impl_n; }
/**
* Returns true if the two instances of @c fisher_f_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(fisher_f_distribution)
private:
chi_squared_distribution<RealType> _impl_m;
chi_squared_distribution<RealType> _impl_n;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_EXTREME_VALUE_DISTRIBUTION_HPP

View File

@ -1,292 +0,0 @@
/* boost random/gamma_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#define BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/exponential_distribution.hpp>
namespace boost {
namespace random {
// The algorithm is taken from Knuth
/**
* The gamma distribution is a continuous distribution with two
* parameters alpha and beta. It produces values > 0.
*
* It has
* \f$\displaystyle p(x) = x^{\alpha-1}\frac{e^{-x/\beta}}{\beta^\alpha\Gamma(\alpha)}\f$.
*/
template<class RealType = double>
class gamma_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type
{
public:
typedef gamma_distribution distribution_type;
/**
* Constructs a @c param_type object from the "alpha" and "beta"
* parameters.
*
* Requires: alpha > 0 && beta > 0
*/
param_type(const RealType& alpha_arg = RealType(1.0),
const RealType& beta_arg = RealType(1.0))
: _alpha(alpha_arg), _beta(beta_arg)
{
}
/** Returns the "alpha" parameter of the distribution. */
RealType alpha() const { return _alpha; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const param_type& parm)
{
os << parm._alpha << ' ' << parm._beta;
return os;
}
/** Reads the parameters from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
{
is >> parm._alpha >> std::ws >> parm._beta;
return is;
}
#endif
/** Returns true if the two sets of parameters are the same. */
friend bool operator==(const param_type& lhs, const param_type& rhs)
{
return lhs._alpha == rhs._alpha && lhs._beta == rhs._beta;
}
/** Returns true if the two sets fo parameters are different. */
friend bool operator!=(const param_type& lhs, const param_type& rhs)
{
return !(lhs == rhs);
}
private:
RealType _alpha;
RealType _beta;
};
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
/**
* Creates a new gamma_distribution with parameters "alpha" and "beta".
*
* Requires: alpha > 0 && beta > 0
*/
explicit gamma_distribution(const result_type& alpha_arg = result_type(1.0),
const result_type& beta_arg = result_type(1.0))
: _exp(result_type(1)), _alpha(alpha_arg), _beta(beta_arg)
{
BOOST_ASSERT(_alpha > result_type(0));
BOOST_ASSERT(_beta > result_type(0));
init();
}
/** Constructs a @c gamma_distribution from its parameters. */
explicit gamma_distribution(const param_type& parm)
: _exp(result_type(1)), _alpha(parm.alpha()), _beta(parm.beta())
{
init();
}
// compiler-generated copy ctor and assignment operator are fine
/** Returns the "alpha" paramter of the distribution. */
RealType alpha() const { return _alpha; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/* Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_alpha, _beta); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_alpha = parm.alpha();
_beta = parm.beta();
init();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { _exp.reset(); }
/**
* Returns a random variate distributed according to
* the gamma distribution.
*/
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::tan; using std::sqrt; using std::exp; using std::log;
using std::pow;
#endif
if(_alpha == result_type(1)) {
return _exp(eng) * _beta;
} else if(_alpha > result_type(1)) {
// Can we have a boost::mathconst please?
const result_type pi = result_type(3.14159265358979323846);
for(;;) {
result_type y = tan(pi * uniform_01<RealType>()(eng));
result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
+ _alpha-result_type(1);
if(x <= result_type(0))
continue;
if(uniform_01<RealType>()(eng) >
(result_type(1)+y*y) * exp((_alpha-result_type(1))
*log(x/(_alpha-result_type(1)))
- sqrt(result_type(2)*_alpha
-result_type(1))*y))
continue;
return x * _beta;
}
} else /* alpha < 1.0 */ {
for(;;) {
result_type u = uniform_01<RealType>()(eng);
result_type y = _exp(eng);
result_type x, q;
if(u < _p) {
x = exp(-y/_alpha);
q = _p*exp(-x);
} else {
x = result_type(1)+y;
q = _p + (result_type(1)-_p) * pow(x,_alpha-result_type(1));
}
if(u >= q)
continue;
return x * _beta;
}
}
}
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return gamma_distribution(parm)(urng);
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a @c gamma_distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const gamma_distribution& gd)
{
os << gd.param();
return os;
}
/** Reads a @c gamma_distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
{
gd.read(is);
return is;
}
#endif
/**
* Returns true if the two distributions will produce identical
* sequences of random variates given equal generators.
*/
friend bool operator==(const gamma_distribution& lhs,
const gamma_distribution& rhs)
{
return lhs._alpha == rhs._alpha
&& lhs._beta == rhs._beta
&& lhs._exp == rhs._exp;
}
/**
* Returns true if the two distributions can produce different
* sequences of random variates, given equal generators.
*/
friend bool operator!=(const gamma_distribution& lhs,
const gamma_distribution& rhs)
{
return !(lhs == rhs);
}
private:
/// \cond hide_private_members
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is)
{
param_type parm;
if(is >> parm) {
param(parm);
}
}
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::exp;
#endif
_p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
}
/// \endcond
exponential_distribution<RealType> _exp;
result_type _alpha;
result_type _beta;
// some data precomputed from the parameters
result_type _p;
};
} // namespace random
using random::gamma_distribution;
} // namespace boost
#endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP

View File

@ -1,96 +0,0 @@
/* boost random/generate_canonical.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_GENERATE_CANONICAL_HPP
#define BOOST_RANDOM_GENERATE_CANONICAL_HPP
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/detail/generator_bits.hpp>
namespace boost {
namespace random {
namespace detail {
template<class RealType, std::size_t bits, class URNG>
RealType generate_canonical_impl(URNG& g, boost::mpl::true_ /*is_integral*/)
{
using std::pow;
typedef typename URNG::result_type base_result;
std::size_t digits = std::numeric_limits<RealType>::digits;
RealType R = RealType((g.max)()) - RealType((g.min)()) + 1;
RealType mult = R;
RealType limit =
pow(RealType(2),
RealType((std::min)(static_cast<std::size_t>(bits), digits)));
RealType S = RealType(detail::subtract<base_result>()(g(), (g.min)()));
while(mult < limit) {
RealType inc = RealType(detail::subtract<base_result>()(g(), (g.min)()));
S += inc * mult;
mult *= R;
}
return S / mult;
}
template<class RealType, std::size_t bits, class URNG>
RealType generate_canonical_impl(URNG& g, boost::mpl::false_ /*is_integral*/)
{
using std::pow;
using std::floor;
BOOST_ASSERT((g.min)() == 0);
BOOST_ASSERT((g.max)() == 1);
std::size_t digits = std::numeric_limits<RealType>::digits;
std::size_t engine_bits = detail::generator_bits<URNG>::value();
std::size_t b = (std::min)(bits, digits);
RealType R = pow(RealType(2), RealType(engine_bits));
RealType mult = R;
RealType limit = pow(RealType(2), RealType(b));
RealType S = RealType(g() - (g.min)());
while(mult < limit) {
RealType inc(floor((RealType(g()) - RealType((g.min)())) * R));
S += inc * mult;
mult *= R;
}
return S / mult;
}
}
/**
* Returns a value uniformly distributed in the range [0, 1)
* with at least @c bits random bits.
*/
template<class RealType, std::size_t bits, class URNG>
RealType generate_canonical(URNG& g)
{
RealType result = detail::generate_canonical_impl<RealType, bits>(
g, boost::random::traits::is_integral<typename URNG::result_type>());
BOOST_ASSERT(result >= 0);
BOOST_ASSERT(result <= 1);
if(result == 1) {
result -= std::numeric_limits<RealType>::epsilon() / 2;
BOOST_ASSERT(result != 1);
}
return result;
}
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_GENERATE_CANONICAL_HPP

View File

@ -1,267 +0,0 @@
/* boost random/geometric_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
#define BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp> // std::log
#include <iosfwd>
#include <ios>
#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
/**
* An instantiation of the class template @c geometric_distribution models
* a \random_distribution. The distribution produces positive
* integers which are the number of bernoulli trials
* with probability @c p required to get one that fails.
*
* For the geometric distribution, \f$p(i) = p(1-p)^{i}\f$.
*
* @xmlwarning
* This distribution has been updated to match the C++ standard.
* Its behavior has changed from the original
* boost::geometric_distribution. A backwards compatible
* wrapper is provided in namespace boost.
* @endxmlwarning
*/
template<class IntType = int, class RealType = double>
class geometric_distribution
{
public:
typedef RealType input_type;
typedef IntType result_type;
class param_type
{
public:
typedef geometric_distribution distribution_type;
/** Constructs the parameters with p. */
explicit param_type(RealType p_arg = RealType(0.5))
: _p(p_arg)
{
BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
}
/** Returns the p parameter of the distribution. */
RealType p() const { return _p; }
/** Writes the parameters to a std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._p;
return os;
}
/** Reads the parameters from a std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
double p_in;
if(is >> p_in) {
if(p_in > RealType(0) && p_in < RealType(1)) {
parm._p = p_in;
} else {
is.setstate(std::ios_base::failbit);
}
}
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._p == rhs._p; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _p;
};
/**
* Contructs a new geometric_distribution with the paramter @c p.
*
* Requires: 0 < p < 1
*/
explicit geometric_distribution(const RealType& p_arg = RealType(0.5))
: _p(p_arg)
{
BOOST_ASSERT(RealType(0) < _p && _p < RealType(1));
init();
}
/** Constructs a new geometric_distribution from its parameters. */
explicit geometric_distribution(const param_type& parm)
: _p(parm.p())
{
init();
}
// compiler-generated copy ctor and assignment operator are fine
/** Returns: the distribution parameter @c p */
RealType p() const { return _p; }
/** Returns the smallest value that the distribution can produce. */
IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return IntType(0); }
/** Returns the largest value that the distribution can produce. */
IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return (std::numeric_limits<IntType>::max)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_p); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_p = parm.p();
init();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/**
* Returns a random variate distributed according to the
* geometric_distribution.
*/
template<class Engine>
result_type operator()(Engine& eng) const
{
using std::log;
using std::floor;
RealType x = RealType(1) - boost::uniform_01<RealType>()(eng);
return IntType(floor(log(x) / _log_1mp));
}
/**
* Returns a random variate distributed according to the
* geometric distribution with parameters specified by param.
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{ return geometric_distribution(parm)(eng); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
{
os << gd._p;
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
{
param_type parm;
if(is >> parm) {
gd.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(geometric_distribution, lhs, rhs)
{ return lhs._p == rhs._p; }
/**
* Returns true if the two distributions may produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(geometric_distribution)
private:
/// \cond show_private
void init()
{
using std::log;
_log_1mp = log(1 - _p);
}
RealType _p;
RealType _log_1mp;
/// \endcond
};
} // namespace random
/// \cond show_deprecated
/**
* Provided for backwards compatibility. This class is
* deprecated. It provides the old behavior of geometric_distribution
* with \f$p(i) = (1-p) p^{i-1}\f$.
*/
template<class IntType = int, class RealType = double>
class geometric_distribution
{
public:
typedef RealType input_type;
typedef IntType result_type;
explicit geometric_distribution(RealType p_arg = RealType(0.5))
: _impl(1 - p_arg) {}
RealType p() const { return 1 - _impl.p(); }
void reset() {}
template<class Engine>
IntType operator()(Engine& eng) const { return _impl(eng) + IntType(1); }
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, geometric_distribution, gd)
{
os << gd.p();
return os;
}
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, geometric_distribution, gd)
{
RealType val;
if(is >> val) {
typename impl_type::param_type impl_param(1 - val);
gd._impl.param(impl_param);
}
return is;
}
private:
typedef random::geometric_distribution<IntType, RealType> impl_type;
impl_type _impl;
};
/// \endcond
} // namespace boost
#endif // BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP

View File

@ -1,883 +0,0 @@
/* boost random/hyperexponential_distribution.hpp header file
*
* Copyright Marco Guazzone 2014
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* Much of the code here taken by boost::math::hyperexponential_distribution.
* To this end, we would like to thank Paul Bristow and John Maddock for their
* valuable feedback.
*
* \author Marco Guazzone (marco.guazzone@gmail.com)
*/
#ifndef BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP
#include <boost/config.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/vector_io.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/size.hpp>
#include <boost/type_traits/has_pre_increment.hpp>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <iterator>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
# include <initializer_list>
#endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <iostream>
#include <limits>
#include <numeric>
#include <vector>
namespace boost { namespace random {
namespace hyperexp_detail {
template <typename T>
std::vector<T>& normalize(std::vector<T>& v)
{
if (v.size() == 0)
{
return v;
}
const T sum = std::accumulate(v.begin(), v.end(), static_cast<T>(0));
T final_sum = 0;
const typename std::vector<T>::iterator end = --v.end();
for (typename std::vector<T>::iterator it = v.begin();
it != end;
++it)
{
*it /= sum;
final_sum += *it;
}
*end = 1-final_sum; // avoids round off errors thus ensuring the probabilities really sum to 1
return v;
}
template <typename RealT>
bool check_probabilities(std::vector<RealT> const& probabilities)
{
const std::size_t n = probabilities.size();
RealT sum = 0;
for (std::size_t i = 0; i < n; ++i)
{
if (probabilities[i] < 0
|| probabilities[i] > 1
|| !(boost::math::isfinite)(probabilities[i]))
{
return false;
}
sum += probabilities[i];
}
//NOTE: the check below seems to fail on some architectures.
// So we commented it.
//// - We try to keep phase probabilities correctly normalized in the distribution constructors
//// - However in practice we have to allow for a very slight divergence from a sum of exactly 1:
////if (std::abs(sum-1) > (std::numeric_limits<RealT>::epsilon()*2))
//// This is from Knuth "The Art of Computer Programming: Vol.2, 3rd Ed", and can be used to
//// check is two numbers are approximately equal
//const RealT one = 1;
//const RealT tol = std::numeric_limits<RealT>::epsilon()*2.0;
//if (std::abs(sum-one) > (std::max(std::abs(sum), std::abs(one))*tol))
//{
// return false;
//}
return true;
}
template <typename RealT>
bool check_rates(std::vector<RealT> const& rates)
{
const std::size_t n = rates.size();
for (std::size_t i = 0; i < n; ++i)
{
if (rates[i] <= 0
|| !(boost::math::isfinite)(rates[i]))
{
return false;
}
}
return true;
}
template <typename RealT>
bool check_params(std::vector<RealT> const& probabilities, std::vector<RealT> const& rates)
{
if (probabilities.size() != rates.size())
{
return false;
}
return check_probabilities(probabilities)
&& check_rates(rates);
}
} // Namespace hyperexp_detail
/**
* The hyperexponential distribution is a real-valued continuous distribution
* with two parameters, the <em>phase probability vector</em> \c probs and the
* <em>rate vector</em> \c rates.
*
* A \f$k\f$-phase hyperexponential distribution is a mixture of \f$k\f$
* exponential distributions.
* For this reason, it is also referred to as <em>mixed exponential
* distribution</em> or <em>parallel \f$k\f$-phase exponential
* distribution</em>.
*
* A \f$k\f$-phase hyperexponential distribution is characterized by two
* parameters, namely a <em>phase probability vector</em> \f$\mathbf{\alpha}=(\alpha_1,\ldots,\alpha_k)\f$ and a <em>rate vector</em> \f$\mathbf{\lambda}=(\lambda_1,\ldots,\lambda_k)\f$.
*
* A \f$k\f$-phase hyperexponential distribution is frequently used in
* <em>queueing theory</em> to model the distribution of the superposition of
* \f$k\f$ independent events, like, for instance, the service time distribution
* of a queueing station with \f$k\f$ servers in parallel where the \f$i\f$-th
* server is chosen with probability \f$\alpha_i\f$ and its service time
* distribution is an exponential distribution with rate \f$\lambda_i\f$
* (Allen,1990; Papadopolous et al.,1993; Trivedi,2002).
*
* For instance, CPUs service-time distribution in a computing system has often
* been observed to possess such a distribution (Rosin,1965).
* Also, the arrival of different types of customer to a single queueing station
* is often modeled as a hyperexponential distribution (Papadopolous et al.,1993).
* Similarly, if a product manufactured in several parallel assemply lines and
* the outputs are merged, the failure density of the overall product is likely
* to be hyperexponential (Trivedi,2002).
*
* Finally, since the hyperexponential distribution exhibits a high Coefficient
* of Variation (CoV), that is a CoV > 1, it is especially suited to fit
* empirical data with large CoV (Feitelson,2014; Wolski et al.,2013) and to
* approximate <em>long-tail probability distributions</em> (Feldmann et al.,1998).
*
* See (Boost,2014) for more information and examples.
*
* A \f$k\f$-phase hyperexponential distribution has a probability density
* function
* \f[
* f(x) = \sum_{i=1}^k \alpha_i \lambda_i e^{-x\lambda_i}
* \f]
* where:
* - \f$k\f$ is the <em>number of phases</em> and also the size of the input
* vector parameters,
* - \f$\mathbf{\alpha}=(\alpha_1,\ldots,\alpha_k)\f$ is the <em>phase probability
* vector</em> parameter, and
* - \f$\mathbf{\lambda}=(\lambda_1,\ldots,\lambda_k)\f$ is the <em>rate vector</em>
* parameter.
* .
*
* Given a \f$k\f$-phase hyperexponential distribution with phase probability
* vector \f$\mathbf{\alpha}\f$ and rate vector \f$\mathbf{\lambda}\f$, the
* random variate generation algorithm consists of the following steps (Tyszer,1999):
* -# Generate a random variable \f$U\f$ uniformly distribution on the interval \f$(0,1)\f$.
* -# Use \f$U\f$ to select the appropriate \f$\lambda_i\f$ (e.g., the
* <em>alias method</em> can possibly be used for this step).
* -# Generate an exponentially distributed random variable \f$X\f$ with rate parameter \f$\lambda_i\f$.
* -# Return \f$X\f$.
* .
*
* References:
* -# A.O. Allen, <em>Probability, Statistics, and Queuing Theory with Computer Science Applications, Second Edition</em>, Academic Press, 1990.
* -# Boost C++ Libraries, <em>Boost.Math / Statistical Distributions: Hyperexponential Distribution</em>, Online: http://www.boost.org/doc/libs/release/libs/math/doc/html/dist.html , 2014.
* -# D.G. Feitelson, <em>Workload Modeling for Computer Systems Performance Evaluation</em>, Cambridge University Press, 2014
* -# A. Feldmann and W. Whitt, <em>Fitting mixtures of exponentials to long-tail distributions to analyze network performance models</em>, Performance Evaluation 31(3-4):245, doi:10.1016/S0166-5316(97)00003-5, 1998.
* -# H.T. Papadopolous, C. Heavey and J. Browne, <em>Queueing Theory in Manufacturing Systems Analysis and Design</em>, Chapman & Hall/CRC, 1993, p. 35.
* -# R.F. Rosin, <em>Determining a computing center environment</em>, Communications of the ACM 8(7):463-468, 1965.
* -# K.S. Trivedi, <em>Probability and Statistics with Reliability, Queueing, and Computer Science Applications</em>, John Wiley & Sons, Inc., 2002.
* -# J. Tyszer, <em>Object-Oriented Computer Simulation of Discrete-Event Systems</em>, Springer, 1999.
* -# Wikipedia, <em>Hyperexponential Distribution</em>, Online: http://en.wikipedia.org/wiki/Hyperexponential_distribution , 2014.
* -# Wolfram Mathematica, <em>Hyperexponential Distribution</em>, Online: http://reference.wolfram.com/language/ref/HyperexponentialDistribution.html , 2014.
* .
*
* \author Marco Guazzone (marco.guazzone@gmail.com)
*/
template<class RealT = double>
class hyperexponential_distribution
{
public: typedef RealT result_type;
public: typedef RealT input_type;
/**
* The parameters of a hyperexponential distribution.
*
* Stores the <em>phase probability vector</em> and the <em>rate vector</em>
* of the hyperexponential distribution.
*
* \author Marco Guazzone (marco.guazzone@gmail.com)
*/
public: class param_type
{
public: typedef hyperexponential_distribution distribution_type;
/**
* Constructs a \c param_type with the default parameters
* of the distribution.
*/
public: param_type()
: probs_(1, 1),
rates_(1, 1)
{
}
/**
* Constructs a \c param_type from the <em>phase probability vector</em>
* and <em>rate vector</em> parameters of the distribution.
*
* The <em>phase probability vector</em> parameter is given by the range
* defined by [\a prob_first, \a prob_last) iterator pair, and the
* <em>rate vector</em> parameter is given by the range defined by
* [\a rate_first, \a rate_last) iterator pair.
*
* \tparam ProbIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
* \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
*
* \param prob_first The iterator to the beginning of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param prob_last The iterator to the ending of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
* \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: template <typename ProbIterT, typename RateIterT>
param_type(ProbIterT prob_first, ProbIterT prob_last,
RateIterT rate_first, RateIterT rate_last)
: probs_(prob_first, prob_last),
rates_(rate_first, rate_last)
{
hyperexp_detail::normalize(probs_);
assert( hyperexp_detail::check_params(probs_, rates_) );
}
/**
* Constructs a \c param_type from the <em>phase probability vector</em>
* and <em>rate vector</em> parameters of the distribution.
*
* The <em>phase probability vector</em> parameter is given by the range
* defined by \a prob_range, and the <em>rate vector</em> parameter is
* given by the range defined by \a rate_range.
*
* \tparam ProbRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
* \tparam RateRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
*
* \param prob_range The range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param rate_range The range of positive real elements representing the rates.
*
* \note
* The final \c disable_if parameter is an implementation detail that
* differentiates between this two argument constructor and the
* iterator-based two argument constructor described below.
*/
// We SFINAE this out of existance if either argument type is
// incrementable as in that case the type is probably an iterator:
public: template <typename ProbRangeT, typename RateRangeT>
param_type(ProbRangeT const& prob_range,
RateRangeT const& rate_range,
typename boost::disable_if_c<boost::has_pre_increment<ProbRangeT>::value || boost::has_pre_increment<RateRangeT>::value>::type* = 0)
: probs_(boost::begin(prob_range), boost::end(prob_range)),
rates_(boost::begin(rate_range), boost::end(rate_range))
{
hyperexp_detail::normalize(probs_);
assert( hyperexp_detail::check_params(probs_, rates_) );
}
/**
* Constructs a \c param_type from the <em>rate vector</em> parameter of
* the distribution and with equal phase probabilities.
*
* The <em>rate vector</em> parameter is given by the range defined by
* [\a rate_first, \a rate_last) iterator pair, and the <em>phase
* probability vector</em> parameter is set to the equal phase
* probabilities (i.e., to a vector of the same length \f$k\f$ of the
* <em>rate vector</em> and with each element set to \f$1.0/k\f$).
*
* \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
* \tparam RateIterT2 Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
*
* \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
* \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
*
* \note
* The final \c disable_if parameter is an implementation detail that
* differentiates between this two argument constructor and the
* range-based two argument constructor described above.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
// We SFINAE this out of existance if the argument type is
// incrementable as in that case the type is probably an iterator.
public: template <typename RateIterT>
param_type(RateIterT rate_first,
RateIterT rate_last,
typename boost::enable_if_c<boost::has_pre_increment<RateIterT>::value>::type* = 0)
: probs_(std::distance(rate_first, rate_last), 1), // will be normalized below
rates_(rate_first, rate_last)
{
assert(probs_.size() == rates_.size());
}
/**
* Constructs a @c param_type from the "rates" parameters
* of the distribution and with equal phase probabilities.
*
* The <em>rate vector</em> parameter is given by the range defined by
* \a rate_range, and the <em>phase probability vector</em> parameter is
* set to the equal phase probabilities (i.e., to a vector of the same
* length \f$k\f$ of the <em>rate vector</em> and with each element set
* to \f$1.0/k\f$).
*
* \tparam RateRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
*
* \param rate_range The range of positive real elements representing the rates.
*/
public: template <typename RateRangeT>
param_type(RateRangeT const& rate_range)
: probs_(boost::size(rate_range), 1), // Will be normalized below
rates_(boost::begin(rate_range), boost::end(rate_range))
{
hyperexp_detail::normalize(probs_);
assert( hyperexp_detail::check_params(probs_, rates_) );
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a \c param_type from the <em>phase probability vector</em>
* and <em>rate vector</em> parameters of the distribution.
*
* The <em>phase probability vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l1, and the <em>rate vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l2.
*
* \param l1 The initializer list for inizializing the phase probability vector.
* \param l2 The initializer list for inizializing the rate vector.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: param_type(std::initializer_list<RealT> l1, std::initializer_list<RealT> l2)
: probs_(l1.begin(), l1.end()),
rates_(l2.begin(), l2.end())
{
hyperexp_detail::normalize(probs_);
assert( hyperexp_detail::check_params(probs_, rates_) );
}
/**
* Constructs a \c param_type from the <em>rate vector</em> parameter
* of the distribution and with equal phase probabilities.
*
* The <em>rate vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l1, and the <em>phase probability vector</em> parameter is
* set to the equal phase probabilities (i.e., to a vector of the same
* length \f$k\f$ of the <em>rate vector</em> and with each element set
* to \f$1.0/k\f$).
*
* \param l1 The initializer list for inizializing the rate vector.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: param_type(std::initializer_list<RealT> l1)
: probs_(std::distance(l1.begin(), l1.end()), 1), // Will be normalized below
rates_(l1.begin(), l1.end())
{
hyperexp_detail::normalize(probs_);
assert( hyperexp_detail::check_params(probs_, rates_) );
}
#endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Gets the <em>phase probability vector</em> parameter of the distribtuion.
*
* \return The <em>phase probability vector</em> parameter of the distribution.
*
* \note
* The returned probabilities are the normalized version of the ones
* passed at construction time.
*/
public: std::vector<RealT> probabilities() const
{
return probs_;
}
/**
* Gets the <em>rate vector</em> parameter of the distribtuion.
*
* \return The <em>rate vector</em> parameter of the distribution.
*/
public: std::vector<RealT> rates() const
{
return rates_;
}
/** Writes a \c param_type to a \c std::ostream. */
public: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, param)
{
detail::print_vector(os, param.probs_);
os << ' ';
detail::print_vector(os, param.rates_);
return os;
}
/** Reads a \c param_type from a \c std::istream. */
public: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, param)
{
// NOTE: if \c std::ios_base::exceptions is set, the code below may
// throw in case of a I/O failure.
// To prevent leaving the state of \c param inconsistent:
// - if an exception is thrown, the state of \c param is left
// unchanged (i.e., is the same as the one at the beginning
// of the function's execution), and
// - the state of \c param only after reading the whole input.
std::vector<RealT> probs;
std::vector<RealT> rates;
// Reads probability and rate vectors
detail::read_vector(is, probs);
if (!is)
{
return is;
}
is >> std::ws;
detail::read_vector(is, rates);
if (!is)
{
return is;
}
// Update the state of the param_type object
if (probs.size() > 0)
{
param.probs_.swap(probs);
probs.clear();
}
if (rates.size() > 0)
{
param.rates_.swap(rates);
rates.clear();
}
bool fail = false;
// Adjust vector sizes (if needed)
if (param.probs_.size() != param.rates_.size()
|| param.probs_.size() == 0)
{
fail = true;
const std::size_t np = param.probs_.size();
const std::size_t nr = param.rates_.size();
if (np > nr)
{
param.rates_.resize(np, 1);
}
else if (nr > np)
{
param.probs_.resize(nr, 1);
}
else
{
param.probs_.resize(1, 1);
param.rates_.resize(1, 1);
}
}
// Normalize probabilities
// NOTE: this cannot be done earlier since the probability vector
// can be changed due to size conformance
hyperexp_detail::normalize(param.probs_);
// Set the error state in the underlying stream in case of invalid input
if (fail)
{
// This throws an exception if ios_base::exception(failbit) is enabled
is.setstate(std::ios_base::failbit);
}
//post: vector size conformance
assert(param.probs_.size() == param.rates_.size());
return is;
}
/** Returns true if the two sets of parameters are the same. */
public: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{
return lhs.probs_ == rhs.probs_
&& lhs.rates_ == rhs.rates_;
}
/** Returns true if the two sets of parameters are the different. */
public: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private: std::vector<RealT> probs_; ///< The <em>phase probability vector</em> parameter of the distribution
private: std::vector<RealT> rates_; ///< The <em>rate vector</em> parameter of the distribution
}; // param_type
/**
* Constructs a 1-phase \c hyperexponential_distribution (i.e., an
* exponential distribution) with rate 1.
*/
public: hyperexponential_distribution()
: dd_(std::vector<RealT>(1, 1)),
rates_(1, 1)
{
// empty
}
/**
* Constructs a \c hyperexponential_distribution from the <em>phase
* probability vector</em> and <em>rate vector</em> parameters of the
* distribution.
*
* The <em>phase probability vector</em> parameter is given by the range
* defined by [\a prob_first, \a prob_last) iterator pair, and the
* <em>rate vector</em> parameter is given by the range defined by
* [\a rate_first, \a rate_last) iterator pair.
*
* \tparam ProbIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
* \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
*
* \param prob_first The iterator to the beginning of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param prob_last The iterator to the ending of the range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
* \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: template <typename ProbIterT, typename RateIterT>
hyperexponential_distribution(ProbIterT prob_first, ProbIterT prob_last,
RateIterT rate_first, RateIterT rate_last)
: dd_(prob_first, prob_last),
rates_(rate_first, rate_last)
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
/**
* Constructs a \c hyperexponential_distribution from the <em>phase
* probability vector</em> and <em>rate vector</em> parameters of the
* distribution.
*
* The <em>phase probability vector</em> parameter is given by the range
* defined by \a prob_range, and the <em>rate vector</em> parameter is
* given by the range defined by \a rate_range.
*
* \tparam ProbRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
* \tparam RateRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
*
* \param prob_range The range of non-negative real elements representing the phase probabilities; if elements don't sum to 1, they are normalized.
* \param rate_range The range of positive real elements representing the rates.
*
* \note
* The final \c disable_if parameter is an implementation detail that
* differentiates between this two argument constructor and the
* iterator-based two argument constructor described below.
*/
// We SFINAE this out of existance if either argument type is
// incrementable as in that case the type is probably an iterator:
public: template <typename ProbRangeT, typename RateRangeT>
hyperexponential_distribution(ProbRangeT const& prob_range,
RateRangeT const& rate_range,
typename boost::disable_if_c<boost::has_pre_increment<ProbRangeT>::value || boost::has_pre_increment<RateRangeT>::value>::type* = 0)
: dd_(prob_range),
rates_(boost::begin(rate_range), boost::end(rate_range))
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
/**
* Constructs a \c hyperexponential_distribution from the <em>rate
* vector</em> parameter of the distribution and with equal phase
* probabilities.
*
* The <em>rate vector</em> parameter is given by the range defined by
* [\a rate_first, \a rate_last) iterator pair, and the <em>phase
* probability vector</em> parameter is set to the equal phase
* probabilities (i.e., to a vector of the same length \f$k\f$ of the
* <em>rate vector</em> and with each element set to \f$1.0/k\f$).
*
* \tparam RateIterT Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
* \tparam RateIterT2 Must meet the requirements of \c InputIterator concept (ISO,2014,sec. 24.2.3 [input.iterators]).
*
* \param rate_first The iterator to the beginning of the range of non-negative real elements representing the rates.
* \param rate_last The iterator to the ending of the range of non-negative real elements representing the rates.
*
* \note
* The final \c disable_if parameter is an implementation detail that
* differentiates between this two argument constructor and the
* range-based two argument constructor described above.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
// We SFINAE this out of existance if the argument type is
// incrementable as in that case the type is probably an iterator.
public: template <typename RateIterT>
hyperexponential_distribution(RateIterT rate_first,
RateIterT rate_last,
typename boost::enable_if_c<boost::has_pre_increment<RateIterT>::value>::type* = 0)
: dd_(std::vector<RealT>(std::distance(rate_first, rate_last), 1)),
rates_(rate_first, rate_last)
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
/**
* Constructs a @c param_type from the "rates" parameters
* of the distribution and with equal phase probabilities.
*
* The <em>rate vector</em> parameter is given by the range defined by
* \a rate_range, and the <em>phase probability vector</em> parameter is
* set to the equal phase probabilities (i.e., to a vector of the same
* length \f$k\f$ of the <em>rate vector</em> and with each element set
* to \f$1.0/k\f$).
*
* \tparam RateRangeT Must meet the requirements of <a href="boost:/libs/range/doc/html/range/concepts.html">Range</a> concept.
*
* \param rate_range The range of positive real elements representing the rates.
*/
public: template <typename RateRangeT>
hyperexponential_distribution(RateRangeT const& rate_range)
: dd_(std::vector<RealT>(boost::size(rate_range), 1)),
rates_(boost::begin(rate_range), boost::end(rate_range))
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
/**
* Constructs a \c hyperexponential_distribution from its parameters.
*
* \param param The parameters of the distribution.
*/
public: explicit hyperexponential_distribution(param_type const& param)
: dd_(param.probabilities()),
rates_(param.rates())
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a \c hyperexponential_distribution from the <em>phase
* probability vector</em> and <em>rate vector</em> parameters of the
* distribution.
*
* The <em>phase probability vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l1, and the <em>rate vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l2.
*
* \param l1 The initializer list for inizializing the phase probability vector.
* \param l2 The initializer list for inizializing the rate vector.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: hyperexponential_distribution(std::initializer_list<RealT> const& l1, std::initializer_list<RealT> const& l2)
: dd_(l1.begin(), l1.end()),
rates_(l2.begin(), l2.end())
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
/**
* Constructs a \c hyperexponential_distribution from the <em>rate
* vector</em> parameter of the distribution and with equal phase
* probabilities.
*
* The <em>rate vector</em> parameter is given by the
* <em>brace-init-list</em> (ISO,2014,sec. 8.5.4 [dcl.init.list])
* defined by \a l1, and the <em>phase probability vector</em> parameter is
* set to the equal phase probabilities (i.e., to a vector of the same
* length \f$k\f$ of the <em>rate vector</em> and with each element set
* to \f$1.0/k\f$).
*
* \param l1 The initializer list for inizializing the rate vector.
*
* References:
* -# ISO, <em>ISO/IEC 14882-2014: Information technology - Programming languages - C++</em>, 2014
* .
*/
public: hyperexponential_distribution(std::initializer_list<RealT> const& l1)
: dd_(std::vector<RealT>(std::distance(l1.begin(), l1.end()), 1)),
rates_(l1.begin(), l1.end())
{
assert( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
}
#endif
/**
* Gets a random variate distributed according to the
* hyperexponential distribution.
*
* \tparam URNG Must meet the requirements of \uniform_random_number_generator.
*
* \param urng A uniform random number generator object.
*
* \return A random variate distributed according to the hyperexponential distribution.
*/
public: template<class URNG>\
RealT operator()(URNG& urng) const
{
const int i = dd_(urng);
return boost::random::exponential_distribution<RealT>(rates_[i])(urng);
}
/**
* Gets a random variate distributed according to the hyperexponential
* distribution with parameters specified by \c param.
*
* \tparam URNG Must meet the requirements of \uniform_random_number_generator.
*
* \param urng A uniform random number generator object.
* \param param A distribution parameter object.
*
* \return A random variate distributed according to the hyperexponential distribution.
* distribution with parameters specified by \c param.
*/
public: template<class URNG>
RealT operator()(URNG& urng, const param_type& param) const
{
return hyperexponential_distribution(param)(urng);
}
/** Returns the number of phases of the distribution. */
public: std::size_t num_phases() const
{
return rates_.size();
}
/** Returns the <em>phase probability vector</em> parameter of the distribution. */
public: std::vector<RealT> probabilities() const
{
return dd_.probabilities();
}
/** Returns the <em>rate vector</em> parameter of the distribution. */
public: std::vector<RealT> rates() const
{
return rates_;
}
/** Returns the smallest value that the distribution can produce. */
public: RealT min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
return 0;
}
/** Returns the largest value that the distribution can produce. */
public: RealT max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
return std::numeric_limits<RealT>::infinity();
}
/** Returns the parameters of the distribution. */
public: param_type param() const
{
std::vector<RealT> probs = dd_.probabilities();
return param_type(probs.begin(), probs.end(), rates_.begin(), rates_.end());
}
/** Sets the parameters of the distribution. */
public: void param(param_type const& param)
{
dd_.param(typename boost::random::discrete_distribution<int,RealT>::param_type(param.probabilities()));
rates_ = param.rates();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
public: void reset()
{
// empty
}
/** Writes an @c hyperexponential_distribution to a @c std::ostream. */
public: BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, hyperexponential_distribution, hd)
{
os << hd.param();
return os;
}
/** Reads an @c hyperexponential_distribution from a @c std::istream. */
public: BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, hyperexponential_distribution, hd)
{
param_type param;
if(is >> param)
{
hd.param(param);
}
return is;
}
/**
* Returns true if the two instances of @c hyperexponential_distribution will
* return identical sequences of values given equal generators.
*/
public: BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(hyperexponential_distribution, lhs, rhs)
{
return lhs.dd_ == rhs.dd_
&& lhs.rates_ == rhs.rates_;
}
/**
* Returns true if the two instances of @c hyperexponential_distribution will
* return different sequences of values given equal generators.
*/
public: BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(hyperexponential_distribution)
private: boost::random::discrete_distribution<int,RealT> dd_; ///< The \c discrete_distribution used to sample the phase probability and choose the rate
private: std::vector<RealT> rates_; ///< The <em>rate vector</em> parameter of the distribution
}; // hyperexponential_distribution
}} // namespace boost::random
#endif // BOOST_RANDOM_HYPEREXPONENTIAL_DISTRIBUTION_HPP

View File

@ -1,271 +0,0 @@
/* boost random/independent_bits.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_INDEPENDENT_BITS_HPP
#define BOOST_RANDOM_INDEPENDENT_BITS_HPP
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/random/traits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/integer_log2.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
namespace boost {
namespace random {
/**
* An instantiation of class template @c independent_bits_engine
* model a \pseudo_random_number_generator. It generates random
* numbers distributed between [0, 2^w) by combining one or
* more invocations of the base engine.
*
* Requires: 0 < w <= std::numeric_limits<UIntType>::digits
*/
template<class Engine, std::size_t w, class UIntType>
class independent_bits_engine
{
public:
typedef Engine base_type;
typedef UIntType result_type;
typedef typename Engine::result_type base_result_type;
// Required by old Boost.Random concept
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0; }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return max_imp(boost::is_integral<UIntType>()); }
/**
* Constructs an @c independent_bits_engine using the
* default constructor of the base generator.
*/
independent_bits_engine() { }
/**
* Constructs an @c independent_bits_engine, using seed as
* the constructor argument for both base generators.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(independent_bits_engine,
base_result_type, seed_arg)
{
_base.seed(seed_arg);
}
/**
* Constructs an @c independent_bits_engine, using seq as
* the constructor argument for the base generator.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(independent_bits_engine,
SeedSeq, seq)
{ _base.seed(seq); }
/** Constructs an @c independent_bits_engine by copying @c base. */
independent_bits_engine(const base_type& base_arg) : _base(base_arg) {}
/**
* Contructs an @c independent_bits_engine with
* values from the range defined by the input iterators first
* and last. first will be modified to point to the element
* after the last one used.
*
* Throws: @c std::invalid_argument if the input range is too small.
*
* Exception Safety: Basic
*/
template<class It>
independent_bits_engine(It& first, It last) : _base(first, last) { }
/**
* Seeds an @c independent_bits_engine using the default
* seed of the base generator.
*/
void seed() { _base.seed(); }
/**
* Seeds an @c independent_bits_engine, using @c seed as the
* seed for the base generator.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(independent_bits_engine,
base_result_type, seed_arg)
{ _base.seed(seed_arg); }
/**
* Seeds an @c independent_bits_engine, using @c seq to
* seed the base generator.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(independent_bits_engine,
SeedSeq, seq)
{ _base.seed(seq); }
/**
* Seeds an @c independent_bits_engine with
* values from the range defined by the input iterators first
* and last. first will be modified to point to the element
* after the last one used.
*
* Throws: @c std::invalid_argument if the input range is too small.
*
* Exception Safety: Basic
*/
template<class It> void seed(It& first, It last)
{ _base.seed(first, last); }
/** Returns the next value of the generator. */
result_type operator()()
{
// While it may seem wasteful to recalculate this
// every time, both msvc and gcc can propagate
// constants, resolving this at compile time.
base_unsigned range =
detail::subtract<base_result_type>()((_base.max)(), (_base.min)());
std::size_t m =
(range == (std::numeric_limits<base_unsigned>::max)()) ?
std::numeric_limits<base_unsigned>::digits :
detail::integer_log2(range + 1);
std::size_t n = (w + m - 1) / m;
std::size_t w0, n0;
base_unsigned y0, y1;
base_unsigned y0_mask, y1_mask;
calc_params(n, range, w0, n0, y0, y1, y0_mask, y1_mask);
if(base_unsigned(range - y0 + 1) > y0 / n) {
// increment n and try again.
++n;
calc_params(n, range, w0, n0, y0, y1, y0_mask, y1_mask);
}
BOOST_ASSERT(n0*w0 + (n - n0)*(w0 + 1) == w);
result_type S = 0;
for(std::size_t k = 0; k < n0; ++k) {
base_unsigned u;
do {
u = detail::subtract<base_result_type>()(_base(), (_base.min)());
} while(u > base_unsigned(y0 - 1));
S = (S << w0) + (u & y0_mask);
}
for(std::size_t k = 0; k < (n - n0); ++k) {
base_unsigned u;
do {
u = detail::subtract<base_result_type>()(_base(), (_base.min)());
} while(u > base_unsigned(y1 - 1));
S = (S << (w0 + 1)) + (u & y1_mask);
}
return S;
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t i = 0; i < z; ++i) {
(*this)();
}
}
const base_type& base() const { return _base; }
/**
* Writes the textual representation if the generator to a @c std::ostream.
* The textual representation of the engine is the textual representation
* of the base engine.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, independent_bits_engine, r)
{
os << r._base;
return os;
}
/**
* Reads the state of an @c independent_bits_engine from a
* @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, independent_bits_engine, r)
{
is >> r._base;
return is;
}
/**
* Returns: true iff the two @c independent_bits_engines will
* produce the same sequence of values.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(independent_bits_engine, x, y)
{ return x._base == y._base; }
/**
* Returns: true iff the two @c independent_bits_engines will
* produce different sequences of values.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(independent_bits_engine)
private:
/// \cond show_private
typedef typename boost::random::traits::make_unsigned<base_result_type>::type base_unsigned;
static UIntType max_imp(const boost::true_type&)
{
return boost::low_bits_mask_t<w>::sig_bits;
}
static UIntType max_imp(const boost::false_type&)
{
// We have a multiprecision integer type:
BOOST_STATIC_ASSERT(std::numeric_limits<UIntType>::is_specialized);
return w < std::numeric_limits<UIntType>::digits ? UIntType((UIntType(1) << w) - 1) : UIntType((((UIntType(1) << (w - 1)) - 1) << 1) | 1u);
}
void calc_params(
std::size_t n, base_unsigned range,
std::size_t& w0, std::size_t& n0,
base_unsigned& y0, base_unsigned& y1,
base_unsigned& y0_mask, base_unsigned& y1_mask)
{
BOOST_ASSERT(w >= n);
w0 = w/n;
n0 = n - w % n;
y0_mask = (base_unsigned(2) << (w0 - 1)) - 1;
y1_mask = (y0_mask << 1) | 1;
y0 = (range + 1) & ~y0_mask;
y1 = (range + 1) & ~y1_mask;
BOOST_ASSERT(y0 != 0 || base_unsigned(range + 1) == 0);
}
/// \endcond
Engine _base;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
template<class Engine, std::size_t w, class UIntType>
const bool independent_bits_engine<Engine, w, UIntType>::has_fixed_range;
#endif
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_INDEPENDENT_BITS_HPP

View File

@ -1,267 +0,0 @@
/* boost random/inversive_congruential.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
#define BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
#include <iosfwd>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/const_mod.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
// Eichenauer and Lehn 1986
/**
* Instantiations of class template @c inversive_congruential_engine model a
* \pseudo_random_number_generator. It uses the inversive congruential
* algorithm (ICG) described in
*
* @blockquote
* "Inversive pseudorandom number generators: concepts, results and links",
* Peter Hellekalek, In: "Proceedings of the 1995 Winter Simulation
* Conference", C. Alexopoulos, K. Kang, W.R. Lilegdon, and D. Goldsman
* (editors), 1995, pp. 255-262. ftp://random.mat.sbg.ac.at/pub/data/wsc95.ps
* @endblockquote
*
* The output sequence is defined by x(n+1) = (a*inv(x(n)) - b) (mod p),
* where x(0), a, b, and the prime number p are parameters of the generator.
* The expression inv(k) denotes the multiplicative inverse of k in the
* field of integer numbers modulo p, with inv(0) := 0.
*
* The template parameter IntType shall denote a signed integral type large
* enough to hold p; a, b, and p are the parameters of the generators. The
* template parameter val is the validation value checked by validation.
*
* @xmlnote
* The implementation currently uses the Euclidian Algorithm to compute
* the multiplicative inverse. Therefore, the inversive generators are about
* 10-20 times slower than the others (see section"performance"). However,
* the paper talks of only 3x slowdown, so the Euclidian Algorithm is probably
* not optimal for calculating the multiplicative inverse.
* @endxmlnote
*/
template<class IntType, IntType a, IntType b, IntType p>
class inversive_congruential_engine
{
public:
typedef IntType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(result_type, multiplier = a);
BOOST_STATIC_CONSTANT(result_type, increment = b);
BOOST_STATIC_CONSTANT(result_type, modulus = p);
BOOST_STATIC_CONSTANT(IntType, default_seed = 1);
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return b == 0 ? 1 : 0; }
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return p-1; }
/**
* Constructs an @c inversive_congruential_engine, seeding it with
* the default seed.
*/
inversive_congruential_engine() { seed(); }
/**
* Constructs an @c inversive_congruential_engine, seeding it with @c x0.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(inversive_congruential_engine,
IntType, x0)
{ seed(x0); }
/**
* Constructs an @c inversive_congruential_engine, seeding it with values
* produced by a call to @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(inversive_congruential_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Constructs an @c inversive_congruential_engine, seeds it
* with values taken from the itrator range [first, last),
* and adjusts first to point to the element after the last one
* used. If there are not enough elements, throws @c std::invalid_argument.
*
* first and last must be input iterators.
*/
template<class It> inversive_congruential_engine(It& first, It last)
{ seed(first, last); }
/**
* Calls seed(default_seed)
*/
void seed() { seed(default_seed); }
/**
* If c mod m is zero and x0 mod m is zero, changes the current value of
* the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
* distinct seeds in the range [1,m) will leave the generator in distinct
* states. If c is not zero, the range is [0,m).
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(inversive_congruential_engine, IntType, x0)
{
// wrap _x if it doesn't fit in the destination
if(modulus == 0) {
_value = x0;
} else {
_value = x0 % modulus;
}
// handle negative seeds
if(_value <= 0 && _value != 0) {
_value += modulus;
}
// adjust to the correct range
if(increment == 0 && _value == 0) {
_value = 1;
}
BOOST_ASSERT(_value >= (min)());
BOOST_ASSERT(_value <= (max)());
}
/**
* Seeds an @c inversive_congruential_engine using values from a SeedSeq.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(inversive_congruential_engine, SeedSeq, seq)
{ seed(detail::seed_one_int<IntType, modulus>(seq)); }
/**
* seeds an @c inversive_congruential_engine with values taken
* from the itrator range [first, last) and adjusts @c first to
* point to the element after the last one used. If there are
* not enough elements, throws @c std::invalid_argument.
*
* @c first and @c last must be input iterators.
*/
template<class It> void seed(It& first, It last)
{ seed(detail::get_one_int<IntType, modulus>(first, last)); }
/** Returns the next output of the generator. */
IntType operator()()
{
typedef const_mod<IntType, p> do_mod;
_value = do_mod::mult_add(a, do_mod::invert(_value), b);
return _value;
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
/**
* Writes the textual representation of the generator to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, inversive_congruential_engine, x)
{
os << x._value;
return os;
}
/**
* Reads the textual representation of the generator from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, inversive_congruential_engine, x)
{
is >> x._value;
return is;
}
/**
* Returns true if the two generators will produce identical
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(inversive_congruential_engine, x, y)
{ return x._value == y._value; }
/**
* Returns true if the two generators will produce different
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(inversive_congruential_engine)
private:
IntType _value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, IntType a, IntType b, IntType p>
const bool inversive_congruential_engine<IntType, a, b, p>::has_fixed_range;
template<class IntType, IntType a, IntType b, IntType p>
const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::multiplier;
template<class IntType, IntType a, IntType b, IntType p>
const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::increment;
template<class IntType, IntType a, IntType b, IntType p>
const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::modulus;
template<class IntType, IntType a, IntType b, IntType p>
const typename inversive_congruential_engine<IntType, a, b, p>::result_type inversive_congruential_engine<IntType, a, b, p>::default_seed;
#endif
/// \cond show_deprecated
// provided for backwards compatibility
template<class IntType, IntType a, IntType b, IntType p, IntType val = 0>
class inversive_congruential : public inversive_congruential_engine<IntType, a, b, p>
{
typedef inversive_congruential_engine<IntType, a, b, p> base_type;
public:
inversive_congruential(IntType x0 = 1) : base_type(x0) {}
template<class It>
inversive_congruential(It& first, It last) : base_type(first, last) {}
};
/// \endcond
/**
* The specialization hellekalek1995 was suggested in
*
* @blockquote
* "Inversive pseudorandom number generators: concepts, results and links",
* Peter Hellekalek, In: "Proceedings of the 1995 Winter Simulation
* Conference", C. Alexopoulos, K. Kang, W.R. Lilegdon, and D. Goldsman
* (editors), 1995, pp. 255-262. ftp://random.mat.sbg.ac.at/pub/data/wsc95.ps
* @endblockquote
*/
typedef inversive_congruential_engine<uint32_t, 9102, 2147483647-36884165,
2147483647> hellekalek1995;
} // namespace random
using random::hellekalek1995;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP

View File

@ -1,537 +0,0 @@
/* boost random/lagged_fibonacci.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2013-10-14 fixed some warnings with Wshadow (mgaunard)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LAGGED_FIBONACCI_HPP
#define BOOST_RANDOM_LAGGED_FIBONACCI_HPP
#include <istream>
#include <iosfwd>
#include <algorithm> // std::max
#include <iterator>
#include <boost/config/no_tr1/cmath.hpp> // std::pow
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/generator_seed_seq.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template \lagged_fibonacci_engine model a
* \pseudo_random_number_generator. It uses a lagged Fibonacci
* algorithm with two lags @c p and @c q:
* x(i) = x(i-p) + x(i-q) (mod 2<sup>w</sup>) with p > q.
*/
template<class UIntType, int w, unsigned int p, unsigned int q>
class lagged_fibonacci_engine
{
public:
typedef UIntType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
BOOST_STATIC_CONSTANT(UIntType, default_seed = 331u);
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return low_bits_mask_t<w>::sig_bits; }
/** Creates a new @c lagged_fibonacci_engine and calls @c seed(). */
lagged_fibonacci_engine() { seed(); }
/** Creates a new @c lagged_fibonacci_engine and calls @c seed(value). */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_engine,
UIntType, value)
{ seed(value); }
/** Creates a new @c lagged_fibonacci_engine and calls @c seed(seq). */
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Creates a new @c lagged_fibonacci_engine and calls @c seed(first, last).
*/
template<class It> lagged_fibonacci_engine(It& first, It last)
{ seed(first, last); }
// compiler-generated copy ctor and assignment operator are fine
/** Calls @c seed(default_seed). */
void seed() { seed(default_seed); }
/**
* Sets the state of the generator to values produced by
* a \minstd_rand0 generator.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_engine,
UIntType, value)
{
minstd_rand0 intgen(static_cast<boost::uint32_t>(value));
detail::generator_seed_seq<minstd_rand0> gen(intgen);
seed(gen);
}
/**
* Sets the state of the generator using values produced by seq.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_engine, SeedSeq, seq)
{
detail::seed_array_int<w>(seq, x);
i = long_lag;
}
/**
* Sets the state of the generator to values from the iterator
* range [first, last). If there are not enough elements in the
* range [first, last) throws @c std::invalid_argument.
*/
template<class It>
void seed(It& first, It last)
{
detail::fill_array_int<w>(first, last, x);
i = long_lag;
}
/** Returns the next value of the generator. */
result_type operator()()
{
if(i >= long_lag)
fill();
return x[i++];
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
/**
* Writes the textual representation of the generator to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_engine, f)
{
os << f.i;
for(unsigned int j = 0; j < f.long_lag; ++j)
os << ' ' << f.x[j];
return os;
}
/**
* Reads the textual representation of the generator from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_engine, f)
{
is >> f.i >> std::ws;
for(unsigned int j = 0; j < f.long_lag; ++j)
is >> f.x[j] >> std::ws;
return is;
}
/**
* Returns true if the two generators will produce identical
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_engine, x_, y_)
{ return x_.i == y_.i && std::equal(x_.x, x_.x+long_lag, y_.x); }
/**
* Returns true if the two generators will produce different
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_engine)
private:
/// \cond show_private
void fill();
/// \endcond
unsigned int i;
UIntType x[long_lag];
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UIntType, int w, unsigned int p, unsigned int q>
const bool lagged_fibonacci_engine<UIntType, w, p, q>::has_fixed_range;
template<class UIntType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::long_lag;
template<class UIntType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_engine<UIntType, w, p, q>::short_lag;
template<class UIntType, int w, unsigned int p, unsigned int q>
const UIntType lagged_fibonacci_engine<UIntType, w, p, q>::default_seed;
#endif
/// \cond show_private
template<class UIntType, int w, unsigned int p, unsigned int q>
void lagged_fibonacci_engine<UIntType, w, p, q>::fill()
{
// two loops to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(unsigned int j = 0; j < short_lag; ++j)
x[j] = (x[j] + x[j+(long_lag-short_lag)]) & low_bits_mask_t<w>::sig_bits;
}
for(unsigned int j = short_lag; j < long_lag; ++j)
x[j] = (x[j] + x[j-short_lag]) & low_bits_mask_t<w>::sig_bits;
i = 0;
}
/// \endcond
/// \cond show_deprecated
// provided for backwards compatibility
template<class UIntType, int w, unsigned int p, unsigned int q, UIntType v = 0>
class lagged_fibonacci : public lagged_fibonacci_engine<UIntType, w, p, q>
{
typedef lagged_fibonacci_engine<UIntType, w, p, q> base_type;
public:
lagged_fibonacci() {}
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci, UIntType, val)
{ this->seed(val); }
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci, SeedSeq, seq)
{ this->seed(seq); }
template<class It>
lagged_fibonacci(It& first, It last) : base_type(first, last) {}
};
/// \endcond
// lagged Fibonacci generator for the range [0..1)
// contributed by Matthias Troyer
// for p=55, q=24 originally by G. J. Mitchell and D. P. Moore 1958
/**
* Instantiations of class template @c lagged_fibonacci_01 model a
* \pseudo_random_number_generator. It uses a lagged Fibonacci
* algorithm with two lags @c p and @c q, evaluated in floating-point
* arithmetic: x(i) = x(i-p) + x(i-q) (mod 1) with p > q. See
*
* @blockquote
* "Uniform random number generators for supercomputers", Richard Brent,
* Proc. of Fifth Australian Supercomputer Conference, Melbourne,
* Dec. 1992, pp. 704-706.
* @endblockquote
*
* @xmlnote
* The quality of the generator crucially depends on the choice
* of the parameters. User code should employ one of the sensibly
* parameterized generators such as \lagged_fibonacci607 instead.
* @endxmlnote
*
* The generator requires considerable amounts of memory for the storage
* of its state array. For example, \lagged_fibonacci607 requires about
* 4856 bytes and \lagged_fibonacci44497 requires about 350 KBytes.
*/
template<class RealType, int w, unsigned int p, unsigned int q>
class lagged_fibonacci_01_engine
{
public:
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 331u);
/** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(). */
lagged_fibonacci_01_engine() { seed(); }
/** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(value). */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01_engine, uint32_t, value)
{ seed(value); }
/** Constructs a @c lagged_fibonacci_01 generator and calls @c seed(gen). */
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01_engine, SeedSeq, seq)
{ seed(seq); }
template<class It> lagged_fibonacci_01_engine(It& first, It last)
{ seed(first, last); }
// compiler-generated copy ctor and assignment operator are fine
/** Calls seed(default_seed). */
void seed() { seed(default_seed); }
/**
* Constructs a \minstd_rand0 generator with the constructor parameter
* value and calls seed with it. Distinct seeds in the range
* [1, 2147483647) will produce generators with different states. Other
* seeds will be equivalent to some seed within this range. See
* \linear_congruential_engine for details.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(lagged_fibonacci_01_engine, boost::uint32_t, value)
{
minstd_rand0 intgen(value);
detail::generator_seed_seq<minstd_rand0> gen(intgen);
seed(gen);
}
/**
* Seeds this @c lagged_fibonacci_01_engine using values produced by
* @c seq.generate.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(lagged_fibonacci_01_engine, SeedSeq, seq)
{
detail::seed_array_real<w>(seq, x);
i = long_lag;
}
/**
* Seeds this @c lagged_fibonacci_01_engine using values from the
* iterator range [first, last). If there are not enough elements
* in the range, throws @c std::invalid_argument.
*/
template<class It>
void seed(It& first, It last)
{
detail::fill_array_real<w>(first, last, x);
i = long_lag;
}
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(0); }
/** Returns the upper bound of the generators outputs. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return result_type(1); }
/** Returns the next value of the generator. */
result_type operator()()
{
if(i >= long_lag)
fill();
return x[i++];
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ return detail::generate_from_real(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
/**
* Writes the textual representation of the generator to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lagged_fibonacci_01_engine, f)
{
// allow for Koenig lookup
using std::pow;
os << f.i;
std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
for(unsigned int j = 0; j < f.long_lag; ++j)
os << ' ' << f.x[j] * f.modulus();
os.flags(oldflags);
return os;
}
/**
* Reads the textual representation of the generator from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lagged_fibonacci_01_engine, f)
{
is >> f.i;
for(unsigned int j = 0; j < f.long_lag; ++j) {
typename lagged_fibonacci_01_engine::result_type value;
is >> std::ws >> value;
f.x[j] = value / f.modulus();
}
return is;
}
/**
* Returns true if the two generators will produce identical
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lagged_fibonacci_01_engine, x_, y_)
{ return x_.i == y_.i && std::equal(x_.x, x_.x+long_lag, y_.x); }
/**
* Returns true if the two generators will produce different
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lagged_fibonacci_01_engine)
private:
/// \cond show_private
void fill();
static RealType modulus()
{
using std::pow;
return pow(RealType(2), word_size);
}
/// \endcond
unsigned int i;
RealType x[long_lag];
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class RealType, int w, unsigned int p, unsigned int q>
const bool lagged_fibonacci_01_engine<RealType, w, p, q>::has_fixed_range;
template<class RealType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::long_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_01_engine<RealType, w, p, q>::short_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
const int lagged_fibonacci_01_engine<RealType,w,p,q>::word_size;
template<class RealType, int w, unsigned int p, unsigned int q>
const boost::uint32_t lagged_fibonacci_01_engine<RealType,w,p,q>::default_seed;
#endif
/// \cond show_private
template<class RealType, int w, unsigned int p, unsigned int q>
void lagged_fibonacci_01_engine<RealType, w, p, q>::fill()
{
// two loops to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(unsigned int j = 0; j < short_lag; ++j) {
RealType t = x[j] + x[j+(long_lag-short_lag)];
if(t >= RealType(1))
t -= RealType(1);
x[j] = t;
}
}
for(unsigned int j = short_lag; j < long_lag; ++j) {
RealType t = x[j] + x[j-short_lag];
if(t >= RealType(1))
t -= RealType(1);
x[j] = t;
}
i = 0;
}
/// \endcond
/// \cond show_deprecated
// provided for backwards compatibility
template<class RealType, int w, unsigned int p, unsigned int q>
class lagged_fibonacci_01 : public lagged_fibonacci_01_engine<RealType, w, p, q>
{
typedef lagged_fibonacci_01_engine<RealType, w, p, q> base_type;
public:
lagged_fibonacci_01() {}
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(lagged_fibonacci_01, boost::uint32_t, val)
{ this->seed(val); }
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(lagged_fibonacci_01, SeedSeq, seq)
{ this->seed(seq); }
template<class It>
lagged_fibonacci_01(It& first, It last) : base_type(first, last) {}
};
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class RealType, int w, unsigned int p, unsigned int q>
struct generator_bits<lagged_fibonacci_01_engine<RealType, w, p, q> >
{
static std::size_t value() { return w; }
};
template<class RealType, int w, unsigned int p, unsigned int q>
struct generator_bits<lagged_fibonacci_01<RealType, w, p, q> >
{
static std::size_t value() { return w; }
};
}
#ifdef BOOST_RANDOM_DOXYGEN
namespace detail {
/**
* The specializations lagged_fibonacci607 ... lagged_fibonacci44497
* use well tested lags.
*
* See
*
* @blockquote
* "On the Periods of Generalized Fibonacci Recurrences", Richard P. Brent
* Computer Sciences Laboratory Australian National University, December 1992
* @endblockquote
*
* The lags used here can be found in
*
* @blockquote
* "Uniform random number generators for supercomputers", Richard Brent,
* Proc. of Fifth Australian Supercomputer Conference, Melbourne,
* Dec. 1992, pp. 704-706.
* @endblockquote
*/
struct lagged_fibonacci_doc {};
}
#endif
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 607, 273> lagged_fibonacci607;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 1279, 418> lagged_fibonacci1279;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 2281, 1252> lagged_fibonacci2281;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 3217, 576> lagged_fibonacci3217;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 4423, 2098> lagged_fibonacci4423;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 9689, 5502> lagged_fibonacci9689;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 19937, 9842> lagged_fibonacci19937;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 23209, 13470> lagged_fibonacci23209;
/** @copydoc boost::random::detail::lagged_fibonacci_doc */
typedef lagged_fibonacci_01_engine<double, 48, 44497, 21034> lagged_fibonacci44497;
} // namespace random
using random::lagged_fibonacci607;
using random::lagged_fibonacci1279;
using random::lagged_fibonacci2281;
using random::lagged_fibonacci3217;
using random::lagged_fibonacci4423;
using random::lagged_fibonacci9689;
using random::lagged_fibonacci19937;
using random::lagged_fibonacci23209;
using random::lagged_fibonacci44497;
} // namespace boost
#endif // BOOST_RANDOM_LAGGED_FIBONACCI_HPP

View File

@ -1,175 +0,0 @@
/* boost random/laplace_distribution.hpp header file
*
* Copyright Steven Watanabe 2014
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP
#define BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP
#include <cassert>
#include <istream>
#include <iosfwd>
#include <boost/random/detail/operators.hpp>
#include <boost/random/exponential_distribution.hpp>
namespace boost {
namespace random {
/**
* The laplace distribution is a real-valued distribution with
* two parameters, mean and beta.
*
* It has \f$\displaystyle p(x) = \frac{e^-{\frac{|x-\mu|}{\beta}}}{2\beta}\f$.
*/
template<class RealType = double>
class laplace_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef laplace_distribution distribution_type;
/**
* Constructs a @c param_type from the "mean" and "beta" parameters
* of the distribution.
*/
explicit param_type(RealType mean_arg = RealType(0.0),
RealType beta_arg = RealType(1.0))
: _mean(mean_arg), _beta(beta_arg)
{}
/** Returns the "mean" parameter of the distribtuion. */
RealType mean() const { return _mean; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._mean << ' ' << parm._beta; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._mean >> std::ws >> parm._beta; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._mean == rhs._mean && lhs._beta == rhs._beta; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _mean;
RealType _beta;
};
/**
* Constructs an @c laplace_distribution from its "mean" and "beta" parameters.
*/
explicit laplace_distribution(RealType mean_arg = RealType(0.0),
RealType beta_arg = RealType(1.0))
: _mean(mean_arg), _beta(beta_arg)
{}
/** Constructs an @c laplace_distribution from its parameters. */
explicit laplace_distribution(const param_type& parm)
: _mean(parm.mean()), _beta(parm.beta())
{}
/**
* Returns a random variate distributed according to the
* laplace distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
RealType exponential = exponential_distribution<RealType>()(urng);
if(uniform_01<RealType>()(urng) < 0.5)
exponential = -exponential;
return _mean + _beta * exponential;
}
/**
* Returns a random variate distributed accordint to the laplace
* distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return laplace_distribution(parm)(urng);
}
/** Returns the "mean" parameter of the distribution. */
RealType mean() const { return _mean; }
/** Returns the "beta" parameter of the distribution. */
RealType beta() const { return _beta; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(-std::numeric_limits<RealType>::infinity()); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(std::numeric_limits<RealType>::infinity()); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_mean, _beta); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_mean = parm.mean();
_beta = parm.beta();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Writes an @c laplace_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, laplace_distribution, wd)
{
os << wd.param();
return os;
}
/** Reads an @c laplace_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, laplace_distribution, wd)
{
param_type parm;
if(is >> parm) {
wd.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c laplace_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(laplace_distribution, lhs, rhs)
{ return lhs._mean == rhs._mean && lhs._beta == rhs._beta; }
/**
* Returns true if the two instances of @c laplace_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(laplace_distribution)
private:
RealType _mean;
RealType _beta;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_LAPLACE_DISTRIBUTION_HPP

View File

@ -1,466 +0,0 @@
/* boost random/linear_congruential.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
#include <iostream>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/const_mod.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template linear_congruential_engine model a
* \pseudo_random_number_generator. Linear congruential pseudo-random
* number generators are described in:
*
* @blockquote
* "Mathematical methods in large-scale computing units", D. H. Lehmer,
* Proc. 2nd Symposium on Large-Scale Digital Calculating Machines,
* Harvard University Press, 1951, pp. 141-146
* @endblockquote
*
* Let x(n) denote the sequence of numbers returned by some pseudo-random
* number generator. Then for the linear congruential generator,
* x(n+1) := (a * x(n) + c) mod m. Parameters for the generator are
* x(0), a, c, m. The template parameter IntType shall denote an integral
* type. It must be large enough to hold values a, c, and m. The template
* parameters a and c must be smaller than m.
*
* Note: The quality of the generator crucially depends on the choice of
* the parameters. User code should use one of the sensibly parameterized
* generators such as minstd_rand instead.
*/
template<class IntType, IntType a, IntType c, IntType m>
class linear_congruential_engine
{
public:
typedef IntType result_type;
// Required for old Boost.Random concept
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(IntType, multiplier = a);
BOOST_STATIC_CONSTANT(IntType, increment = c);
BOOST_STATIC_CONSTANT(IntType, modulus = m);
BOOST_STATIC_CONSTANT(IntType, default_seed = 1);
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
BOOST_STATIC_ASSERT(m == 0 || a < m);
BOOST_STATIC_ASSERT(m == 0 || c < m);
/**
* Constructs a @c linear_congruential_engine, using the default seed
*/
linear_congruential_engine() { seed(); }
/**
* Constructs a @c linear_congruential_engine, seeding it with @c x0.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_congruential_engine,
IntType, x0)
{ seed(x0); }
/**
* Constructs a @c linear_congruential_engine, seeding it with values
* produced by a call to @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_congruential_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Constructs a @c linear_congruential_engine and seeds it
* with values taken from the itrator range [first, last)
* and adjusts first to point to the element after the last one
* used. If there are not enough elements, throws @c std::invalid_argument.
*
* first and last must be input iterators.
*/
template<class It>
linear_congruential_engine(It& first, It last)
{
seed(first, last);
}
// compiler-generated copy constructor and assignment operator are fine
/**
* Calls seed(default_seed)
*/
void seed() { seed(default_seed); }
/**
* If c mod m is zero and x0 mod m is zero, changes the current value of
* the generator to 1. Otherwise, changes it to x0 mod m. If c is zero,
* distinct seeds in the range [1,m) will leave the generator in distinct
* states. If c is not zero, the range is [0,m).
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_congruential_engine, IntType, x0)
{
// wrap _x if it doesn't fit in the destination
if(modulus == 0) {
_x = x0;
} else {
_x = x0 % modulus;
}
// handle negative seeds
if(_x <= 0 && _x != 0) {
_x += modulus;
}
// adjust to the correct range
if(increment == 0 && _x == 0) {
_x = 1;
}
BOOST_ASSERT(_x >= (min)());
BOOST_ASSERT(_x <= (max)());
}
/**
* Seeds a @c linear_congruential_engine using values from a SeedSeq.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_congruential_engine, SeedSeq, seq)
{ seed(detail::seed_one_int<IntType, m>(seq)); }
/**
* seeds a @c linear_congruential_engine with values taken
* from the itrator range [first, last) and adjusts @c first to
* point to the element after the last one used. If there are
* not enough elements, throws @c std::invalid_argument.
*
* @c first and @c last must be input iterators.
*/
template<class It>
void seed(It& first, It last)
{ seed(detail::get_one_int<IntType, m>(first, last)); }
/**
* Returns the smallest value that the @c linear_congruential_engine
* can produce.
*/
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return c == 0 ? 1 : 0; }
/**
* Returns the largest value that the @c linear_congruential_engine
* can produce.
*/
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return modulus-1; }
/** Returns the next value of the @c linear_congruential_engine. */
IntType operator()()
{
_x = const_mod<IntType, m>::mult_add(a, _x, c);
return _x;
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
typedef const_mod<IntType, m> mod_type;
IntType b_inv = mod_type::invert(a-1);
IntType b_gcd = mod_type::mult(a-1, b_inv);
if(b_gcd == 1) {
IntType a_z = mod_type::pow(a, z);
_x = mod_type::mult_add(a_z, _x,
mod_type::mult(mod_type::mult(c, b_inv), a_z - 1));
} else {
// compute (a^z - 1)*c % (b_gcd * m) / (b / b_gcd) * inv(b / b_gcd)
// we're storing the intermediate result / b_gcd
IntType a_zm1_over_gcd = 0;
IntType a_km1_over_gcd = (a - 1) / b_gcd;
boost::uintmax_t exponent = z;
while(exponent != 0) {
if(exponent % 2 == 1) {
a_zm1_over_gcd =
mod_type::mult_add(
b_gcd,
mod_type::mult(a_zm1_over_gcd, a_km1_over_gcd),
mod_type::add(a_zm1_over_gcd, a_km1_over_gcd));
}
a_km1_over_gcd = mod_type::mult_add(
b_gcd,
mod_type::mult(a_km1_over_gcd, a_km1_over_gcd),
mod_type::add(a_km1_over_gcd, a_km1_over_gcd));
exponent /= 2;
}
IntType a_z = mod_type::mult_add(b_gcd, a_zm1_over_gcd, 1);
IntType num = mod_type::mult(c, a_zm1_over_gcd);
b_inv = mod_type::invert((a-1)/b_gcd);
_x = mod_type::mult_add(a_z, _x, mod_type::mult(b_inv, num));
}
}
friend bool operator==(const linear_congruential_engine& x,
const linear_congruential_engine& y)
{ return x._x == y._x; }
friend bool operator!=(const linear_congruential_engine& x,
const linear_congruential_engine& y)
{ return !(x == y); }
#if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS)
/** Writes a @c linear_congruential_engine to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const linear_congruential_engine& lcg)
{
return os << lcg._x;
}
/** Reads a @c linear_congruential_engine from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
linear_congruential_engine& lcg)
{
lcg.read(is);
return is;
}
#endif
private:
/// \cond show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
IntType x;
if(is >> x) {
if(x >= (min)() && x <= (max)()) {
_x = x;
} else {
is.setstate(std::ios_base::failbit);
}
}
}
/// \endcond
IntType _x;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, IntType a, IntType c, IntType m>
const bool linear_congruential_engine<IntType, a, c, m>::has_fixed_range;
template<class IntType, IntType a, IntType c, IntType m>
const IntType linear_congruential_engine<IntType,a,c,m>::multiplier;
template<class IntType, IntType a, IntType c, IntType m>
const IntType linear_congruential_engine<IntType,a,c,m>::increment;
template<class IntType, IntType a, IntType c, IntType m>
const IntType linear_congruential_engine<IntType,a,c,m>::modulus;
template<class IntType, IntType a, IntType c, IntType m>
const IntType linear_congruential_engine<IntType,a,c,m>::default_seed;
#endif
/// \cond show_deprecated
// provided for backwards compatibility
template<class IntType, IntType a, IntType c, IntType m, IntType val = 0>
class linear_congruential : public linear_congruential_engine<IntType, a, c, m>
{
typedef linear_congruential_engine<IntType, a, c, m> base_type;
public:
linear_congruential(IntType x0 = 1) : base_type(x0) {}
template<class It>
linear_congruential(It& first, It last) : base_type(first, last) {}
};
/// \endcond
/**
* The specialization \minstd_rand0 was originally suggested in
*
* @blockquote
* A pseudo-random number generator for the System/360, P.A. Lewis,
* A.S. Goodman, J.M. Miller, IBM Systems Journal, Vol. 8, No. 2,
* 1969, pp. 136-146
* @endblockquote
*
* It is examined more closely together with \minstd_rand in
*
* @blockquote
* "Random Number Generators: Good ones are hard to find",
* Stephen K. Park and Keith W. Miller, Communications of
* the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201
* @endblockquote
*/
typedef linear_congruential_engine<uint32_t, 16807, 0, 2147483647> minstd_rand0;
/** The specialization \minstd_rand was suggested in
*
* @blockquote
* "Random Number Generators: Good ones are hard to find",
* Stephen K. Park and Keith W. Miller, Communications of
* the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201
* @endblockquote
*/
typedef linear_congruential_engine<uint32_t, 48271, 0, 2147483647> minstd_rand;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
/**
* Class @c rand48 models a \pseudo_random_number_generator. It uses
* the linear congruential algorithm with the parameters a = 0x5DEECE66D,
* c = 0xB, m = 2**48. It delivers identical results to the @c lrand48()
* function available on some systems (assuming lcong48 has not been called).
*
* It is only available on systems where @c uint64_t is provided as an
* integral type, so that for example static in-class constants and/or
* enum definitions with large @c uint64_t numbers work.
*/
class rand48
{
public:
typedef boost::uint32_t result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
/**
* Returns the smallest value that the generator can produce
*/
static uint32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
/**
* Returns the largest value that the generator can produce
*/
static uint32_t max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0x7FFFFFFF; }
/** Seeds the generator with the default seed. */
rand48() : lcf(cnv(static_cast<uint32_t>(1))) {}
/**
* Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0)
{ seed(x0); }
/**
* Seeds the generator with values produced by @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq)
{ seed(seq); }
/**
* Seeds the generator using values from an iterator range,
* and updates first to point one past the last value consumed.
*/
template<class It> rand48(It& first, It last) : lcf(first, last) { }
// compiler-generated copy ctor and assignment operator are fine
/** Seeds the generator with the default seed. */
void seed() { seed(static_cast<uint32_t>(1)); }
/**
* Changes the current value x(n) of the generator to (x0 << 16) | 0x330e.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0)
{ lcf.seed(cnv(x0)); }
/**
* Seeds the generator using values from an iterator range,
* and updates first to point one past the last value consumed.
*/
template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
/**
* Seeds the generator with values produced by @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq)
{ lcf.seed(seq); }
/** Returns the next value of the generator. */
uint32_t operator()() { return static_cast<uint32_t>(lcf() >> 17); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z) { lcf.discard(z); }
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{
for(; first != last; ++first) {
*first = (*this)();
}
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a @c rand48 to a @c std::ostream. */
template<class CharT,class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
{ os << r.lcf; return os; }
/** Reads a @c rand48 from a @c std::istream. */
template<class CharT,class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
{ is >> r.lcf; return is; }
#endif
/**
* Returns true if the two generators will produce identical
* sequences of values.
*/
friend bool operator==(const rand48& x, const rand48& y)
{ return x.lcf == y.lcf; }
/**
* Returns true if the two generators will produce different
* sequences of values.
*/
friend bool operator!=(const rand48& x, const rand48& y)
{ return !(x == y); }
private:
/// \cond show_private
typedef random::linear_congruential_engine<uint64_t,
// xxxxULL is not portable
uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32),
0xB, uint64_t(1)<<48> lcf_t;
lcf_t lcf;
static boost::uint64_t cnv(boost::uint32_t x)
{ return (static_cast<uint64_t>(x) << 16) | 0x330e; }
/// \endcond
};
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
} // namespace random
using random::minstd_rand0;
using random::minstd_rand;
using random::rand48;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP

View File

@ -1,217 +0,0 @@
/* boost random/linear_feedback_shift.hpp header file
*
* Copyright Jens Maurer 2002
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
#define BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
#include <iosfwd>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed_impl.hpp>
namespace boost {
namespace random {
/**
* Instatiations of @c linear_feedback_shift model a
* \pseudo_random_number_generator. It was originally
* proposed in
*
* @blockquote
* "Random numbers generated by linear recurrence modulo two.",
* Tausworthe, R. C.(1965), Mathematics of Computation 19, 201-209.
* @endblockquote
*/
template<class UIntType, int w, int k, int q, int s>
class linear_feedback_shift_engine
{
public:
typedef UIntType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(int, exponent1 = k);
BOOST_STATIC_CONSTANT(int, exponent2 = q);
BOOST_STATIC_CONSTANT(int, step_size = s);
BOOST_STATIC_CONSTANT(UIntType, default_seed = 341);
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return wordmask(); }
BOOST_STATIC_ASSERT(w > 0);
BOOST_STATIC_ASSERT(q > 0);
BOOST_STATIC_ASSERT(k < w);
BOOST_STATIC_ASSERT(0 < 2*q && 2*q < k);
BOOST_STATIC_ASSERT(0 < s && s <= k-q);
/** Constructs a @c linear_feedback_shift_engine, using the default seed. */
linear_feedback_shift_engine() { seed(); }
/** Constructs a @c linear_feedback_shift_engine, seeding it with s0. */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift_engine,
UIntType, s0)
{ seed(s0); }
/** Constructs a @c linear_feedback_shift_engine, seeding it with seq. */
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Constructs a @c linear_feedback_shift_engine, seeding it with
* values from the range [first, last).
*/
template<class It> linear_feedback_shift_engine(It& first, It last)
{ seed(first, last); }
/** Seeds a @c linear_feedback_shift_engine with the default seed. */
void seed() { seed(default_seed); }
/** Seeds a @c linear_feedback_shift_engine with @c s0. */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_feedback_shift_engine,
UIntType, s0)
{
value = s0 & wordmask();
if(value < (1 << (w-k))) {
value += 1 << (w-k);
}
}
/**
* Seeds a @c linear_feedback_shift_engine with values
* produced by @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_feedback_shift_engine,
SeedSeq, seq)
{ seed(detail::seed_one_int<UIntType, (UIntType(2) << (w - 1))>(seq)); }
/**
* Seeds a @c linear_feedback_shift_engine with values
* from the range [first, last).
*/
template<class It> void seed(It& first, It last)
{
seed(detail::get_one_int<UIntType, (UIntType(2) << (w - 1))>(first, last));
}
/** Returns the next value of the generator. */
result_type operator()()
{
const UIntType b = (((value << q) ^ value) & wordmask()) >> (k-s);
const UIntType mask = (wordmask() << (w-k)) & wordmask();
value = ((value & mask) << s) ^ b;
return value;
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
/**
* Writes the textual representation of the generator to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, linear_feedback_shift_engine, x)
{
os << x.value;
return os;
}
/**
* Reads the textual representation of the generator from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, linear_feedback_shift_engine, x)
{
is >> x.value;
return is;
}
/**
* Returns true if the two generators will produce identical
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(linear_feedback_shift_engine, x, y)
{ return x.value == y.value; }
/**
* Returns true if the two generators will produce different
* sequences of outputs.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(linear_feedback_shift_engine)
private:
/// \cond show_private
static UIntType wordmask() { return boost::low_bits_mask_t<w>::sig_bits; }
/// \endcond
UIntType value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UIntType, int w, int k, int q, int s>
const bool linear_feedback_shift_engine<UIntType, w, k, q, s>::has_fixed_range;
template<class UIntType, int w, int k, int q, int s>
const int linear_feedback_shift_engine<UIntType, w, k, q, s>::word_size;
template<class UIntType, int w, int k, int q, int s>
const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent1;
template<class UIntType, int w, int k, int q, int s>
const int linear_feedback_shift_engine<UIntType, w, k, q, s>::exponent2;
template<class UIntType, int w, int k, int q, int s>
const int linear_feedback_shift_engine<UIntType, w, k, q, s>::step_size;
template<class UIntType, int w, int k, int q, int s>
const UIntType linear_feedback_shift_engine<UIntType, w, k, q, s>::default_seed;
#endif
/// \cond show_deprecated
/** Provided for backwards compatibility. */
template<class UIntType, int w, int k, int q, int s, UIntType v = 0>
class linear_feedback_shift :
public linear_feedback_shift_engine<UIntType, w, k, q, s>
{
typedef linear_feedback_shift_engine<UIntType, w, k, q, s> base_type;
public:
linear_feedback_shift() {}
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_feedback_shift,
SeedSeq, seq)
{ seed(seq); }
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_feedback_shift,
UIntType, val)
{ seed(val); }
template<class It>
linear_feedback_shift(It& first, It last) : base_type(first, last) {}
};
/// \endcond
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP

View File

@ -1,254 +0,0 @@
/* boost random/lognormal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp> // std::exp, std::sqrt
#include <cassert>
#include <iosfwd>
#include <istream>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/normal_distribution.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template lognormal_distribution model a
* \random_distribution. Such a distribution produces random numbers
* with \f$\displaystyle p(x) = \frac{1}{x s \sqrt{2\pi}} e^{\frac{-\left(\log(x)-m\right)^2}{2s^2}}\f$
* for x > 0.
*
* @xmlwarning
* This distribution has been updated to match the C++ standard.
* Its behavior has changed from the original
* boost::lognormal_distribution. A backwards compatible
* version is provided in namespace boost.
* @endxmlwarning
*/
template<class RealType = double>
class lognormal_distribution
{
public:
typedef typename normal_distribution<RealType>::input_type input_type;
typedef RealType result_type;
class param_type
{
public:
typedef lognormal_distribution distribution_type;
/** Constructs the parameters of a lognormal_distribution. */
explicit param_type(RealType m_arg = RealType(0.0),
RealType s_arg = RealType(1.0))
: _m(m_arg), _s(s_arg) {}
/** Returns the "m" parameter of the distribution. */
RealType m() const { return _m; }
/** Returns the "s" parameter of the distribution. */
RealType s() const { return _s; }
/** Writes the parameters to a std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._m << " " << parm._s;
return os;
}
/** Reads the parameters from a std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._m >> std::ws >> parm._s;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._m == rhs._m && lhs._s == rhs._s; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _m;
RealType _s;
};
/**
* Constructs a lognormal_distribution. @c m and @c s are the
* parameters of the distribution.
*/
explicit lognormal_distribution(RealType m_arg = RealType(0.0),
RealType s_arg = RealType(1.0))
: _normal(m_arg, s_arg) {}
/**
* Constructs a lognormal_distribution from its parameters.
*/
explicit lognormal_distribution(const param_type& parm)
: _normal(parm.m(), parm.s()) {}
// compiler-generated copy ctor and assignment operator are fine
/** Returns the m parameter of the distribution. */
RealType m() const { return _normal.mean(); }
/** Returns the s parameter of the distribution. */
RealType s() const { return _normal.sigma(); }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return RealType(0); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(m(), s()); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
typedef normal_distribution<RealType> normal_type;
typename normal_type::param_type normal_param(parm.m(), parm.s());
_normal.param(normal_param);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { _normal.reset(); }
/**
* Returns a random variate distributed according to the
* lognormal distribution.
*/
template<class Engine>
result_type operator()(Engine& eng)
{
using std::exp;
return exp(_normal(eng));
}
/**
* Returns a random variate distributed according to the
* lognormal distribution with parameters specified by param.
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm)
{ return lognormal_distribution(parm)(eng); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
{
os << ld._normal;
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
{
is >> ld._normal;
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(lognormal_distribution, lhs, rhs)
{ return lhs._normal == rhs._normal; }
/**
* Returns true if the two distributions may produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(lognormal_distribution)
private:
normal_distribution<result_type> _normal;
};
} // namespace random
/// \cond show_deprecated
/**
* Provided for backwards compatibility. This class is
* deprecated. It provides the old behavior of lognormal_distribution with
* \f$\displaystyle p(x) = \frac{1}{x \sigma_N \sqrt{2\pi}} e^{\frac{-\left(\log(x)-\mu_N\right)^2}{2\sigma_N^2}}\f$
* for x > 0, where \f$\displaystyle \mu_N = \log\left(\frac{\mu^2}{\sqrt{\sigma^2 + \mu^2}}\right)\f$ and
* \f$\displaystyle \sigma_N = \sqrt{\log\left(1 + \frac{\sigma^2}{\mu^2}\right)}\f$.
*/
template<class RealType = double>
class lognormal_distribution
{
public:
typedef typename normal_distribution<RealType>::input_type input_type;
typedef RealType result_type;
lognormal_distribution(RealType mean_arg = RealType(1.0),
RealType sigma_arg = RealType(1.0))
: _mean(mean_arg), _sigma(sigma_arg)
{
init();
}
RealType mean() const { return _mean; }
RealType sigma() const { return _sigma; }
void reset() { _normal.reset(); }
template<class Engine>
RealType operator()(Engine& eng)
{
using std::exp;
return exp(_normal(eng) * _nsigma + _nmean);
}
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, lognormal_distribution, ld)
{
os << ld._normal << " " << ld._mean << " " << ld._sigma;
return os;
}
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, lognormal_distribution, ld)
{
is >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
ld.init();
return is;
}
private:
/// \cond show_private
void init()
{
using std::log;
using std::sqrt;
_nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
_nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
}
RealType _mean;
RealType _sigma;
RealType _nmean;
RealType _nsigma;
normal_distribution<RealType> _normal;
/// \endcond
};
/// \endcond
} // namespace boost
#endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP

View File

@ -1,682 +0,0 @@
/* boost random/mersenne_twister.hpp header file
*
* Copyright Jens Maurer 2000-2001
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2013-10-14 fixed some warnings with Wshadow (mgaunard)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_MERSENNE_TWISTER_HPP
#define BOOST_RANDOM_MERSENNE_TWISTER_HPP
#include <iosfwd>
#include <istream>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/ptr_helper.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/random/detail/generator_seed_seq.hpp>
#include <boost/random/detail/polynomial.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template mersenne_twister_engine model a
* \pseudo_random_number_generator. It uses the algorithm described in
*
* @blockquote
* "Mersenne Twister: A 623-dimensionally equidistributed uniform
* pseudo-random number generator", Makoto Matsumoto and Takuji Nishimura,
* ACM Transactions on Modeling and Computer Simulation: Special Issue on
* Uniform Random Number Generation, Vol. 8, No. 1, January 1998, pp. 3-30.
* @endblockquote
*
* @xmlnote
* The boost variant has been implemented from scratch and does not
* derive from or use mt19937.c provided on the above WWW site. However, it
* was verified that both produce identical output.
* @endxmlnote
*
* The seeding from an integer was changed in April 2005 to address a
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html">weakness</a>.
*
* The quality of the generator crucially depends on the choice of the
* parameters. User code should employ one of the sensibly parameterized
* generators such as \mt19937 instead.
*
* The generator requires considerable amounts of memory for the storage of
* its state array. For example, \mt11213b requires about 1408 bytes and
* \mt19937 requires about 2496 bytes.
*/
template<class UIntType,
std::size_t w, std::size_t n, std::size_t m, std::size_t r,
UIntType a, std::size_t u, UIntType d, std::size_t s,
UIntType b, std::size_t t,
UIntType c, std::size_t l, UIntType f>
class mersenne_twister_engine
{
public:
typedef UIntType result_type;
BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
BOOST_STATIC_CONSTANT(std::size_t, state_size = n);
BOOST_STATIC_CONSTANT(std::size_t, shift_size = m);
BOOST_STATIC_CONSTANT(std::size_t, mask_bits = r);
BOOST_STATIC_CONSTANT(UIntType, xor_mask = a);
BOOST_STATIC_CONSTANT(std::size_t, tempering_u = u);
BOOST_STATIC_CONSTANT(UIntType, tempering_d = d);
BOOST_STATIC_CONSTANT(std::size_t, tempering_s = s);
BOOST_STATIC_CONSTANT(UIntType, tempering_b = b);
BOOST_STATIC_CONSTANT(std::size_t, tempering_t = t);
BOOST_STATIC_CONSTANT(UIntType, tempering_c = c);
BOOST_STATIC_CONSTANT(std::size_t, tempering_l = l);
BOOST_STATIC_CONSTANT(UIntType, initialization_multiplier = f);
BOOST_STATIC_CONSTANT(UIntType, default_seed = 5489u);
// backwards compatibility
BOOST_STATIC_CONSTANT(UIntType, parameter_a = a);
BOOST_STATIC_CONSTANT(std::size_t, output_u = u);
BOOST_STATIC_CONSTANT(std::size_t, output_s = s);
BOOST_STATIC_CONSTANT(UIntType, output_b = b);
BOOST_STATIC_CONSTANT(std::size_t, output_t = t);
BOOST_STATIC_CONSTANT(UIntType, output_c = c);
BOOST_STATIC_CONSTANT(std::size_t, output_l = l);
// old Boost.Random concept requirements
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
/**
* Constructs a @c mersenne_twister_engine and calls @c seed().
*/
mersenne_twister_engine() { seed(); }
/**
* Constructs a @c mersenne_twister_engine and calls @c seed(value).
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(mersenne_twister_engine,
UIntType, value)
{ seed(value); }
template<class It> mersenne_twister_engine(It& first, It last)
{ seed(first,last); }
/**
* Constructs a mersenne_twister_engine and calls @c seed(gen).
*
* @xmlnote
* The copy constructor will always be preferred over
* the templated constructor.
* @endxmlnote
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(mersenne_twister_engine,
SeedSeq, seq)
{ seed(seq); }
// compiler-generated copy ctor and assignment operator are fine
/** Calls @c seed(default_seed). */
void seed() { seed(default_seed); }
/**
* Sets the state x(0) to v mod 2w. Then, iteratively,
* sets x(i) to
* (i + f * (x(i-1) xor (x(i-1) rshift w-2))) mod 2<sup>w</sup>
* for i = 1 .. n-1. x(n) is the first value to be returned by operator().
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister_engine, UIntType, value)
{
// New seeding algorithm from
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
// In the previous versions, MSBs of the seed affected only MSBs of the
// state x[].
const UIntType mask = (max)();
x[0] = value & mask;
for (i = 1; i < n; i++) {
// See Knuth "The Art of Computer Programming"
// Vol. 2, 3rd ed., page 106
x[i] = (f * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
}
normalize_state();
}
/**
* Seeds a mersenne_twister_engine using values produced by seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(mersenne_twister_engine, SeeqSeq, seq)
{
detail::seed_array_int<w>(seq, x);
i = n;
normalize_state();
}
/** Sets the state of the generator using values from an iterator range. */
template<class It>
void seed(It& first, It last)
{
detail::fill_array_int<w>(first, last, x);
i = n;
normalize_state();
}
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0; }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return boost::low_bits_mask_t<w>::sig_bits; }
/** Produces the next value of the generator. */
result_type operator()();
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/**
* Advances the state of the generator by @c z steps. Equivalent to
*
* @code
* for(unsigned long long i = 0; i < z; ++i) {
* gen();
* }
* @endcode
*/
void discard(boost::uintmax_t z)
{
#ifndef BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD
#define BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD 10000000
#endif
if(z > BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD) {
discard_many(z);
} else {
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes a mersenne_twister_engine to a @c std::ostream */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const mersenne_twister_engine& mt)
{
mt.print(os);
return os;
}
/** Reads a mersenne_twister_engine from a @c std::istream */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
mersenne_twister_engine& mt)
{
for(std::size_t j = 0; j < mt.state_size; ++j)
is >> mt.x[j] >> std::ws;
// MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template
// value parameter "n" available from the class template scope, so use
// the static constant with the same value
mt.i = mt.state_size;
return is;
}
#endif
/**
* Returns true if the two generators are in the same state,
* and will thus produce identical sequences.
*/
friend bool operator==(const mersenne_twister_engine& x_,
const mersenne_twister_engine& y_)
{
if(x_.i < y_.i) return x_.equal_imp(y_);
else return y_.equal_imp(x_);
}
/**
* Returns true if the two generators are in different states.
*/
friend bool operator!=(const mersenne_twister_engine& x_,
const mersenne_twister_engine& y_)
{ return !(x_ == y_); }
private:
/// \cond show_private
void twist();
/**
* Does the work of operator==. This is in a member function
* for portability. Some compilers, such as msvc 7.1 and
* Sun CC 5.10 can't access template parameters or static
* members of the class from inline friend functions.
*
* requires i <= other.i
*/
bool equal_imp(const mersenne_twister_engine& other) const
{
UIntType back[n];
std::size_t offset = other.i - i;
for(std::size_t j = 0; j + offset < n; ++j)
if(x[j] != other.x[j+offset])
return false;
rewind(&back[n-1], offset);
for(std::size_t j = 0; j < offset; ++j)
if(back[j + n - offset] != other.x[j])
return false;
return true;
}
/**
* Does the work of operator<<. This is in a member function
* for portability.
*/
template<class CharT, class Traits>
void print(std::basic_ostream<CharT, Traits>& os) const
{
UIntType data[n];
for(std::size_t j = 0; j < i; ++j) {
data[j + n - i] = x[j];
}
if(i != n) {
rewind(&data[n - i - 1], n - i);
}
os << data[0];
for(std::size_t j = 1; j < n; ++j) {
os << ' ' << data[j];
}
}
/**
* Copies z elements of the state preceding x[0] into
* the array whose last element is last.
*/
void rewind(UIntType* last, std::size_t z) const
{
const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
const UIntType lower_mask = ~upper_mask;
UIntType y0 = x[m-1] ^ x[n-1];
if(y0 & (static_cast<UIntType>(1) << (w-1))) {
y0 = ((y0 ^ a) << 1) | 1;
} else {
y0 = y0 << 1;
}
for(std::size_t sz = 0; sz < z; ++sz) {
UIntType y1 =
rewind_find(last, sz, m-1) ^ rewind_find(last, sz, n-1);
if(y1 & (static_cast<UIntType>(1) << (w-1))) {
y1 = ((y1 ^ a) << 1) | 1;
} else {
y1 = y1 << 1;
}
*(last - sz) = (y0 & upper_mask) | (y1 & lower_mask);
y0 = y1;
}
}
/**
* Converts an arbitrary array into a valid generator state.
* First we normalize x[0], so that it contains the same
* value we would get by running the generator forwards
* and then in reverse. (The low order r bits are redundant).
* Then, if the state consists of all zeros, we set the
* high order bit of x[0] to 1. This function only needs to
* be called by seed, since the state transform preserves
* this relationship.
*/
void normalize_state()
{
const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
const UIntType lower_mask = ~upper_mask;
UIntType y0 = x[m-1] ^ x[n-1];
if(y0 & (static_cast<UIntType>(1) << (w-1))) {
y0 = ((y0 ^ a) << 1) | 1;
} else {
y0 = y0 << 1;
}
x[0] = (x[0] & upper_mask) | (y0 & lower_mask);
// fix up the state if it's all zeroes.
for(std::size_t j = 0; j < n; ++j) {
if(x[j] != 0) return;
}
x[0] = static_cast<UIntType>(1) << (w-1);
}
/**
* Given a pointer to the last element of the rewind array,
* and the current size of the rewind array, finds an element
* relative to the next available slot in the rewind array.
*/
UIntType
rewind_find(UIntType* last, std::size_t size, std::size_t j) const
{
std::size_t index = (j + n - size + n - 1) % n;
if(index < n - size) {
return x[index];
} else {
return *(last - (n - 1 - index));
}
}
/**
* Optimized algorithm for large jumps.
*
* Hiroshi Haramoto, Makoto Matsumoto, and Pierre L'Ecuyer. 2008.
* A Fast Jump Ahead Algorithm for Linear Recurrences in a Polynomial
* Space. In Proceedings of the 5th international conference on
* Sequences and Their Applications (SETA '08).
* DOI=10.1007/978-3-540-85912-3_26
*/
void discard_many(boost::uintmax_t z)
{
// Compute the minimal polynomial, phi(t)
// This depends only on the transition function,
// which is constant. The characteristic
// polynomial is the same as the minimal
// polynomial for a maximum period generator
// (which should be all specializations of
// mersenne_twister.) Even if it weren't,
// the characteristic polynomial is guaranteed
// to be a multiple of the minimal polynomial,
// which is good enough.
detail::polynomial phi = get_characteristic_polynomial();
// calculate g(t) = t^z % phi(t)
detail::polynomial g = mod_pow_x(z, phi);
// h(s_0, t) = \sum_{i=0}^{2k-1}o(s_i)t^{2k-i-1}
detail::polynomial h;
const std::size_t num_bits = w*n - r;
for(std::size_t j = 0; j < num_bits * 2; ++j) {
// Yes, we're advancing the generator state
// here, but it doesn't matter because
// we're going to overwrite it completely
// in reconstruct_state.
if(i >= n) twist();
h[2*num_bits - j - 1] = x[i++] & UIntType(1);
}
// g(t)h(s_0, t)
detail::polynomial gh = g * h;
detail::polynomial result;
for(std::size_t j = 0; j <= num_bits; ++j) {
result[j] = gh[2*num_bits - j - 1];
}
reconstruct_state(result);
}
static detail::polynomial get_characteristic_polynomial()
{
const std::size_t num_bits = w*n - r;
detail::polynomial helper;
helper[num_bits - 1] = 1;
mersenne_twister_engine tmp;
tmp.reconstruct_state(helper);
// Skip the first num_bits elements, since we
// already know what they are.
for(std::size_t j = 0; j < num_bits; ++j) {
if(tmp.i >= n) tmp.twist();
if(j == num_bits - 1)
assert((tmp.x[tmp.i] & 1) == 1);
else
assert((tmp.x[tmp.i] & 1) == 0);
++tmp.i;
}
detail::polynomial phi;
phi[num_bits] = 1;
detail::polynomial next_bits = tmp.as_polynomial(num_bits);
for(std::size_t j = 0; j < num_bits; ++j) {
int val = next_bits[j] ^ phi[num_bits-j-1];
phi[num_bits-j-1] = val;
if(val) {
for(std::size_t k = j + 1; k < num_bits; ++k) {
phi[num_bits-k-1] ^= next_bits[k-j-1];
}
}
}
return phi;
}
detail::polynomial as_polynomial(std::size_t size) {
detail::polynomial result;
for(std::size_t j = 0; j < size; ++j) {
if(i >= n) twist();
result[j] = x[i++] & UIntType(1);
}
return result;
}
void reconstruct_state(const detail::polynomial& p)
{
const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
const UIntType lower_mask = ~upper_mask;
const std::size_t num_bits = w*n - r;
for(std::size_t j = num_bits - n + 1; j <= num_bits; ++j)
x[j % n] = p[j];
UIntType y0 = 0;
for(std::size_t j = num_bits + 1; j >= n - 1; --j) {
UIntType y1 = x[j % n] ^ x[(j + m) % n];
if(p[j - n + 1])
y1 = (y1 ^ a) << UIntType(1) | UIntType(1);
else
y1 = y1 << UIntType(1);
x[(j + 1) % n] = (y0 & upper_mask) | (y1 & lower_mask);
y0 = y1;
}
i = 0;
}
/// \endcond
// state representation: next output is o(x(i))
// x[0] ... x[k] x[k+1] ... x[n-1] represents
// x(i-k) ... x(i) x(i+1) ... x(i-k+n-1)
UIntType x[n];
std::size_t i;
};
/// \cond show_private
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
#define BOOST_RANDOM_MT_DEFINE_CONSTANT(type, name) \
template<class UIntType, std::size_t w, std::size_t n, std::size_t m, \
std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, \
UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> \
const type mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::name
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, word_size);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, state_size);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, shift_size);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, mask_bits);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, xor_mask);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_u);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_d);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_s);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_b);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_t);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, tempering_c);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, tempering_l);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, initialization_multiplier);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, default_seed);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, parameter_a);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_u );
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_s);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, output_b);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_t);
BOOST_RANDOM_MT_DEFINE_CONSTANT(UIntType, output_c);
BOOST_RANDOM_MT_DEFINE_CONSTANT(std::size_t, output_l);
BOOST_RANDOM_MT_DEFINE_CONSTANT(bool, has_fixed_range);
#undef BOOST_RANDOM_MT_DEFINE_CONSTANT
#endif
template<class UIntType,
std::size_t w, std::size_t n, std::size_t m, std::size_t r,
UIntType a, std::size_t u, UIntType d, std::size_t s,
UIntType b, std::size_t t,
UIntType c, std::size_t l, UIntType f>
void
mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::twist()
{
const UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
const UIntType lower_mask = ~upper_mask;
const std::size_t unroll_factor = 6;
const std::size_t unroll_extra1 = (n-m) % unroll_factor;
const std::size_t unroll_extra2 = (m-1) % unroll_factor;
// split loop to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(std::size_t j = 0; j < n-m-unroll_extra1; j++) {
UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
x[j] = x[j+m] ^ (y >> 1) ^ ((x[j+1]&1) * a);
}
}
{
for(std::size_t j = n-m-unroll_extra1; j < n-m; j++) {
UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
x[j] = x[j+m] ^ (y >> 1) ^ ((x[j+1]&1) * a);
}
}
{
for(std::size_t j = n-m; j < n-1-unroll_extra2; j++) {
UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ ((x[j+1]&1) * a);
}
}
{
for(std::size_t j = n-1-unroll_extra2; j < n-1; j++) {
UIntType y = (x[j] & upper_mask) | (x[j+1] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ ((x[j+1]&1) * a);
}
}
// last iteration
UIntType y = (x[n-1] & upper_mask) | (x[0] & lower_mask);
x[n-1] = x[m-1] ^ (y >> 1) ^ ((x[0]&1) * a);
i = 0;
}
/// \endcond
template<class UIntType,
std::size_t w, std::size_t n, std::size_t m, std::size_t r,
UIntType a, std::size_t u, UIntType d, std::size_t s,
UIntType b, std::size_t t,
UIntType c, std::size_t l, UIntType f>
inline typename
mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::result_type
mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>::operator()()
{
if(i == n)
twist();
// Step 4
UIntType z = x[i];
++i;
z ^= ((z >> u) & d);
z ^= ((z << s) & b);
z ^= ((z << t) & c);
z ^= (z >> l);
return z;
}
/**
* The specializations \mt11213b and \mt19937 are from
*
* @blockquote
* "Mersenne Twister: A 623-dimensionally equidistributed
* uniform pseudo-random number generator", Makoto Matsumoto
* and Takuji Nishimura, ACM Transactions on Modeling and
* Computer Simulation: Special Issue on Uniform Random Number
* Generation, Vol. 8, No. 1, January 1998, pp. 3-30.
* @endblockquote
*/
typedef mersenne_twister_engine<uint32_t,32,351,175,19,0xccab8ee7,
11,0xffffffff,7,0x31b6ab00,15,0xffe50000,17,1812433253> mt11213b;
/**
* The specializations \mt11213b and \mt19937 are from
*
* @blockquote
* "Mersenne Twister: A 623-dimensionally equidistributed
* uniform pseudo-random number generator", Makoto Matsumoto
* and Takuji Nishimura, ACM Transactions on Modeling and
* Computer Simulation: Special Issue on Uniform Random Number
* Generation, Vol. 8, No. 1, January 1998, pp. 3-30.
* @endblockquote
*/
typedef mersenne_twister_engine<uint32_t,32,624,397,31,0x9908b0df,
11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
typedef mersenne_twister_engine<uint64_t,64,312,156,31,
UINT64_C(0xb5026f5aa96619e9),29,UINT64_C(0x5555555555555555),17,
UINT64_C(0x71d67fffeda60000),37,UINT64_C(0xfff7eee000000000),43,
UINT64_C(6364136223846793005)> mt19937_64;
#endif
/// \cond show_deprecated
template<class UIntType,
int w, int n, int m, int r,
UIntType a, int u, std::size_t s,
UIntType b, int t,
UIntType c, int l, UIntType v>
class mersenne_twister :
public mersenne_twister_engine<UIntType,
w, n, m, r, a, u, ~(UIntType)0, s, b, t, c, l, 1812433253>
{
typedef mersenne_twister_engine<UIntType,
w, n, m, r, a, u, ~(UIntType)0, s, b, t, c, l, 1812433253> base_type;
public:
mersenne_twister() {}
BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(mersenne_twister, Gen, gen)
{ seed(gen); }
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(mersenne_twister, UIntType, val)
{ seed(val); }
template<class It>
mersenne_twister(It& first, It last) : base_type(first, last) {}
void seed() { base_type::seed(); }
BOOST_RANDOM_DETAIL_GENERATOR_SEED(mersenne_twister, Gen, gen)
{
detail::generator_seed_seq<Gen> seq(gen);
base_type::seed(seq);
}
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(mersenne_twister, UIntType, val)
{ base_type::seed(val); }
template<class It>
void seed(It& first, It last) { base_type::seed(first, last); }
};
/// \endcond
} // namespace random
using random::mt11213b;
using random::mt19937;
using random::mt19937_64;
} // namespace boost
BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt11213b)
BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937)
BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937_64)
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP

View File

@ -1,220 +0,0 @@
/* boost random/negative_binomial_distribution.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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_HPP_INCLUDED
#include <iosfwd>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
namespace boost {
namespace random {
/**
* The negative binomial distribution is an integer valued
* distribution with two parameters, @c k and @c p. The
* distribution produces non-negative values.
*
* The distribution function is
* \f$\displaystyle P(i) = {k+i-1\choose i}p^k(1-p)^i\f$.
*
* This implementation uses a gamma-poisson mixture.
*/
template<class IntType = int, class RealType = double>
class negative_binomial_distribution {
public:
typedef IntType result_type;
typedef RealType input_type;
class param_type {
public:
typedef negative_binomial_distribution distribution_type;
/**
* Construct a param_type object. @c k and @c p
* are the parameters of the distribution.
*
* Requires: k >=0 && 0 <= p <= 1
*/
explicit param_type(IntType k_arg = 1, RealType p_arg = RealType (0.5))
: _k(k_arg), _p(p_arg)
{}
/** Returns the @c k parameter of the distribution. */
IntType k() const { return _k; }
/** Returns the @c p parameter of the distribution. */
RealType p() const { return _p; }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const param_type& parm)
{
os << parm._p << " " << parm._k;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, param_type& parm)
{
is >> parm._p >> std::ws >> parm._k;
return is;
}
#endif
/** Returns true if the parameters have the same values. */
friend bool operator==(const param_type& lhs, const param_type& rhs)
{
return lhs._k == rhs._k && lhs._p == rhs._p;
}
/** Returns true if the parameters have different values. */
friend bool operator!=(const param_type& lhs, const param_type& rhs)
{
return !(lhs == rhs);
}
private:
IntType _k;
RealType _p;
};
/**
* Construct a @c negative_binomial_distribution object. @c k and @c p
* are the parameters of the distribution.
*
* Requires: k >=0 && 0 <= p <= 1
*/
explicit negative_binomial_distribution(IntType k_arg = 1,
RealType p_arg = RealType(0.5))
: _k(k_arg), _p(p_arg)
{}
/**
* Construct an @c negative_binomial_distribution object from the
* parameters.
*/
explicit negative_binomial_distribution(const param_type& parm)
: _k(parm.k()), _p(parm.p())
{}
/**
* Returns a random variate distributed according to the
* negative binomial distribution.
*/
template<class URNG>
IntType operator()(URNG& urng) const
{
gamma_distribution<RealType> gamma(_k, (1-_p)/_p);
poisson_distribution<IntType, RealType> poisson(gamma(urng));
return poisson(urng);
}
/**
* Returns a random variate distributed according to the negative
* binomial distribution with parameters specified by @c param.
*/
template<class URNG>
IntType operator()(URNG& urng, const param_type& parm) const
{
return negative_binomial_distribution(parm)(urng);
}
/** Returns the @c k parameter of the distribution. */
IntType k() const { return _k; }
/** Returns the @c p parameter of the distribution. */
RealType p() const { return _p; }
/** Returns the smallest value that the distribution can produce. */
IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
/** Returns the largest value that the distribution can produce. */
IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return (std::numeric_limits<IntType>::max)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_k, _p); }
/** Sets parameters of the distribution. */
void param(const param_type& parm)
{
_k = parm.k();
_p = parm.p();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const negative_binomial_distribution& bd)
{
os << bd.param();
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
negative_binomial_distribution& bd)
{
bd.read(is);
return is;
}
#endif
/** Returns true if the two distributions will produce the same
sequence of values, given equal generators. */
friend bool operator==(const negative_binomial_distribution& lhs,
const negative_binomial_distribution& rhs)
{
return lhs._k == rhs._k && lhs._p == rhs._p;
}
/** Returns true if the two distributions could produce different
sequences of values, given equal generators. */
friend bool operator!=(const negative_binomial_distribution& lhs,
const negative_binomial_distribution& rhs)
{
return !(lhs == rhs);
}
private:
/// @cond \show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
param_type parm;
if(is >> parm) {
param(parm);
}
}
// parameters
IntType _k;
RealType _p;
/// @endcond
};
}
}
#endif

View File

@ -1,221 +0,0 @@
/* boost random/non_central_chi_squared_distribution.hpp header file
*
* Copyright Thijs van den Berg 2014
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
#define BOOST_RANDOM_NON_CENTRAL_CHI_SQUARED_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <istream>
#include <boost/limits.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/chi_squared_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
namespace boost {
namespace random {
/**
* The noncentral chi-squared distribution is a real valued distribution with
* two parameter, @c k and @c lambda. The distribution produces values > 0.
*
* This is the distribution of the sum of squares of k Normal distributed
* variates each with variance one and \f$\lambda\f$ the sum of squares of the
* normal means.
*
* The distribution function is
* \f$\displaystyle P(x) = \frac{1}{2} e^{-(x+\lambda)/2} \left( \frac{x}{\lambda} \right)^{k/4-1/2} I_{k/2-1}( \sqrt{\lambda x} )\f$.
* where \f$\displaystyle I_\nu(z)\f$ is a modified Bessel function of the
* first kind.
*
* The algorithm is taken from
*
* @blockquote
* "Monte Carlo Methods in Financial Engineering", Paul Glasserman,
* 2003, XIII, 596 p, Stochastic Modelling and Applied Probability, Vol. 53,
* ISBN 978-0-387-21617-1, p 124, Fig. 3.5.
* @endblockquote
*/
template <typename RealType = double>
class non_central_chi_squared_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef non_central_chi_squared_distribution distribution_type;
/**
* Constructs the parameters of a non_central_chi_squared_distribution.
* @c k and @c lambda are the parameter of the distribution.
*
* Requires: k > 0 && lambda > 0
*/
explicit
param_type(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
: _k(k_arg), _lambda(lambda_arg)
{
BOOST_ASSERT(k_arg > RealType(0));
BOOST_ASSERT(lambda_arg > RealType(0));
}
/** Returns the @c k parameter of the distribution */
RealType k() const { return _k; }
/** Returns the @c lambda parameter of the distribution */
RealType lambda() const { return _lambda; }
/** Writes the parameters of the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._k << ' ' << parm._lambda;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._k >> std::ws >> parm._lambda;
return is;
}
/** Returns true if the parameters have the same values. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._k == rhs._k && lhs._lambda == rhs._lambda; }
/** Returns true if the parameters have different values. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _k;
RealType _lambda;
};
/**
* Construct a @c non_central_chi_squared_distribution object. @c k and
* @c lambda are the parameter of the distribution.
*
* Requires: k > 0 && lambda > 0
*/
explicit
non_central_chi_squared_distribution(RealType k_arg = RealType(1), RealType lambda_arg = RealType(1))
: _param(k_arg, lambda_arg)
{
BOOST_ASSERT(k_arg > RealType(0));
BOOST_ASSERT(lambda_arg > RealType(0));
}
/**
* Construct a @c non_central_chi_squared_distribution object from the parameter.
*/
explicit
non_central_chi_squared_distribution(const param_type& parm)
: _param( parm )
{ }
/**
* Returns a random variate distributed according to the
* non central chi squared distribution specified by @c param.
*/
template<typename URNG>
RealType operator()(URNG& eng, const param_type& parm) const
{ return non_central_chi_squared_distribution(parm)(eng); }
/**
* Returns a random variate distributed according to the
* non central chi squared distribution.
*/
template<typename URNG>
RealType operator()(URNG& eng)
{
using std::sqrt;
if (_param.k() > 1) {
boost::random::normal_distribution<RealType> n_dist;
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() - RealType(1));
RealType _z = n_dist(eng);
RealType _x = c_dist(eng);
RealType term1 = _z + sqrt(_param.lambda());
return term1*term1 + _x;
}
else {
boost::random::poisson_distribution<> p_dist(_param.lambda()/RealType(2));
boost::random::poisson_distribution<>::result_type _p = p_dist(eng);
boost::random::chi_squared_distribution<RealType> c_dist(_param.k() + RealType(2)*_p);
return c_dist(eng);
}
}
/** Returns the @c k parameter of the distribution. */
RealType k() const { return _param.k(); }
/** Returns the @c lambda parameter of the distribution. */
RealType lambda() const { return _param.lambda(); }
/** Returns the parameters of the distribution. */
param_type param() const { return _param; }
/** Sets parameters of the distribution. */
void param(const param_type& parm) { _param = parm; }
/** Resets the distribution, so that subsequent uses does not depend on values already produced by it.*/
void reset() {}
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return RealType(0); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return (std::numeric_limits<RealType>::infinity)(); }
/** Writes the parameters of the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, non_central_chi_squared_distribution, dist)
{
os << dist.param();
return os;
}
/** reads the parameters of the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, non_central_chi_squared_distribution, dist)
{
param_type parm;
if(is >> parm) {
dist.param(parm);
}
return is;
}
/** Returns true if two distributions have the same parameters and produce
the same sequence of random numbers given equal generators.*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(non_central_chi_squared_distribution, lhs, rhs)
{ return lhs.param() == rhs.param(); }
/** Returns true if two distributions have different parameters and/or can produce
different sequences of random numbers given equal generators.*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(non_central_chi_squared_distribution)
private:
/// @cond show_private
param_type _param;
/// @endcond
};
} // namespace random
} // namespace boost
#endif

View File

@ -1,374 +0,0 @@
/* boost random/normal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/int_float_pair.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/exponential_distribution.hpp>
namespace boost {
namespace random {
namespace detail {
// tables for the ziggurat algorithm
template<class RealType>
struct normal_table {
static const RealType table_x[129];
static const RealType table_y[129];
};
template<class RealType>
const RealType normal_table<RealType>::table_x[129] = {
3.7130862467403632609, 3.4426198558966521214, 3.2230849845786185446, 3.0832288582142137009,
2.9786962526450169606, 2.8943440070186706210, 2.8231253505459664379, 2.7611693723841538514,
2.7061135731187223371, 2.6564064112581924999, 2.6109722484286132035, 2.5690336259216391328,
2.5300096723854666170, 2.4934545220919507609, 2.4590181774083500943, 2.4264206455302115930,
2.3954342780074673425, 2.3658713701139875435, 2.3375752413355307354, 2.3104136836950021558,
2.2842740596736568056, 2.2590595738653295251, 2.2346863955870569803, 2.2110814088747278106,
2.1881804320720206093, 2.1659267937448407377, 2.1442701823562613518, 2.1231657086697899595,
2.1025731351849988838, 2.0824562379877246441, 2.0627822745039633575, 2.0435215366506694976,
2.0246469733729338782, 2.0061338699589668403, 1.9879595741230607243, 1.9701032608497132242,
1.9525457295488889058, 1.9352692282919002011, 1.9182573008597320303, 1.9014946531003176140,
1.8849670357028692380, 1.8686611409895420085, 1.8525645117230870617, 1.8366654602533840447,
1.8209529965910050740, 1.8054167642140487420, 1.7900469825946189862, 1.7748343955807692457,
1.7597702248942318749, 1.7448461281083765085, 1.7300541605582435350, 1.7153867407081165482,
1.7008366185643009437, 1.6863968467734863258, 1.6720607540918522072, 1.6578219209482075462,
1.6436741568569826489, 1.6296114794646783962, 1.6156280950371329644, 1.6017183802152770587,
1.5878768648844007019, 1.5740982160167497219, 1.5603772223598406870, 1.5467087798535034608,
1.5330878776675560787, 1.5195095847593707806, 1.5059690368565502602, 1.4924614237746154081,
1.4789819769830978546, 1.4655259573357946276, 1.4520886428822164926, 1.4386653166774613138,
1.4252512545068615734, 1.4118417124397602509, 1.3984319141236063517, 1.3850170377251486449,
1.3715922024197322698, 1.3581524543224228739, 1.3446927517457130432, 1.3312079496576765017,
1.3176927832013429910, 1.3041418501204215390, 1.2905495919178731508, 1.2769102735516997175,
1.2632179614460282310, 1.2494664995643337480, 1.2356494832544811749, 1.2217602305309625678,
1.2077917504067576028, 1.1937367078237721994, 1.1795873846544607035, 1.1653356361550469083,
1.1509728421389760651, 1.1364898520030755352, 1.1218769225722540661, 1.1071236475235353980,
1.0922188768965537614, 1.0771506248819376573, 1.0619059636836193998, 1.0464709007525802629,
1.0308302360564555907, 1.0149673952392994716, 0.99886423348064351303, 0.98250080350276038481,
0.96585507938813059489, 0.94890262549791195381, 0.93161619660135381056, 0.91396525100880177644,
0.89591535256623852894, 0.87742742909771569142, 0.85845684317805086354, 0.83895221428120745572,
0.81885390668331772331, 0.79809206062627480454, 0.77658398787614838598, 0.75423066443451007146,
0.73091191062188128150, 0.70647961131360803456, 0.68074791864590421664, 0.65347863871504238702,
0.62435859730908822111, 0.59296294244197797913, 0.55869217837551797140, 0.52065603872514491759,
0.47743783725378787681, 0.42654798630330512490, 0.36287143102841830424, 0.27232086470466385065,
0
};
template<class RealType>
const RealType normal_table<RealType>::table_y[129] = {
0, 0.0026696290839025035092, 0.0055489952208164705392, 0.0086244844129304709682,
0.011839478657982313715, 0.015167298010672042468, 0.018592102737165812650, 0.022103304616111592615,
0.025693291936149616572, 0.029356317440253829618, 0.033087886146505155566, 0.036884388786968774128,
0.040742868074790604632, 0.044660862200872429800, 0.048636295860284051878, 0.052667401903503169793,
0.056752663481538584188, 0.060890770348566375972, 0.065080585213631873753, 0.069321117394180252601,
0.073611501884754893389, 0.077950982514654714188, 0.082338898242957408243, 0.086774671895542968998,
0.091257800827634710201, 0.09578784912257815216, 0.10036444102954554013, 0.10498725541035453978,
0.10965602101581776100, 0.11437051244988827452, 0.11913054670871858767, 0.12393598020398174246,
0.12878670619710396109, 0.13368265258464764118, 0.13862377998585103702, 0.14361008009193299469,
0.14864157424369696566, 0.15371831220958657066, 0.15884037114093507813, 0.16400785468492774791,
0.16922089223892475176, 0.17447963833240232295, 0.17978427212496211424, 0.18513499701071343216,
0.19053204032091372112, 0.19597565311811041399, 0.20146611007620324118, 0.20700370944187380064,
0.21258877307373610060, 0.21822164655637059599, 0.22390269938713388747, 0.22963232523430270355,
0.23541094226572765600, 0.24123899354775131610, 0.24711694751469673582, 0.25304529850976585934,
0.25902456739871074263, 0.26505530225816194029, 0.27113807914102527343, 0.27727350292189771153,
0.28346220822601251779, 0.28970486044581049771, 0.29600215684985583659, 0.30235482778947976274,
0.30876363800925192282, 0.31522938806815752222, 0.32175291587920862031, 0.32833509837615239609,
0.33497685331697116147, 0.34167914123501368412, 0.34844296754987246935, 0.35526938485154714435,
0.36215949537303321162, 0.36911445366827513952, 0.37613546951445442947, 0.38322381105988364587,
0.39038080824138948916, 0.39760785649804255208, 0.40490642081148835099, 0.41227804010702462062,
0.41972433205403823467, 0.42724699830956239880, 0.43484783025466189638, 0.44252871528024661483,
0.45029164368692696086, 0.45813871627287196483, 0.46607215269457097924, 0.47409430069824960453,
0.48220764633483869062, 0.49041482528932163741, 0.49871863547658432422, 0.50712205108130458951,
0.51562823824987205196, 0.52424057267899279809, 0.53296265938998758838, 0.54179835503172412311,
0.55075179312105527738, 0.55982741271069481791, 0.56902999107472161225, 0.57836468112670231279,
0.58783705444182052571, 0.59745315095181228217, 0.60721953663260488551, 0.61714337082656248870,
0.62723248525781456578, 0.63749547734314487428, 0.64794182111855080873, 0.65858200005865368016,
0.66942766735770616891, 0.68049184100641433355, 0.69178914344603585279, 0.70333609902581741633,
0.71515150742047704368, 0.72725691835450587793, 0.73967724368333814856, 0.75244155918570380145,
0.76558417390923599480, 0.77914608594170316563, 0.79317701178385921053, 0.80773829469612111340,
0.82290721139526200050, 0.83878360531064722379, 0.85550060788506428418, 0.87324304892685358879,
0.89228165080230272301, 0.91304364799203805999, 0.93628268170837107547, 0.96359969315576759960,
1
};
template<class RealType = double>
struct unit_normal_distribution
{
template<class Engine>
RealType operator()(Engine& eng) {
const double * const table_x = normal_table<double>::table_x;
const double * const table_y = normal_table<double>::table_y;
for(;;) {
std::pair<RealType, int> vals = generate_int_float_pair<RealType, 8>(eng);
int i = vals.second;
int sign = (i & 1) * 2 - 1;
i = i >> 1;
RealType x = vals.first * RealType(table_x[i]);
if(x < table_x[i + 1]) return x * sign;
if(i == 0) return generate_tail(eng) * sign;
RealType y01 = uniform_01<RealType>()(eng);
RealType y = RealType(table_y[i]) + y01 * RealType(table_y[i + 1] - table_y[i]);
// These store the value y - bound, or something proportional to that difference:
RealType y_above_ubound, y_above_lbound;
// There are three cases to consider:
// - convex regions (where x[i] > x[j] >= 1)
// - concave regions (where 1 <= x[i] < x[j])
// - region containing the inflection point (where x[i] > 1 > x[j])
// For convex (concave), exp^(-x^2/2) is bounded below (above) by the tangent at
// (x[i],y[i]) and is bounded above (below) by the diagonal line from (x[i+1],y[i+1]) to
// (x[i],y[i]).
//
// *If* the inflection point region satisfies slope(x[i+1]) < slope(diagonal), then we
// can treat the inflection region as a convex region: this condition is necessary and
// sufficient to ensure that the curve lies entirely below the diagonal (that, in turn,
// also implies that it will be above the tangent at x[i]).
//
// For the current table size (128), this is satisfied: slope(x[i+1]) = -0.60653 <
// slope(diag) = -0.60649, and so we have only two cases below instead of three.
if (table_x[i] >= 1) { // convex (incl. inflection)
y_above_ubound = RealType(table_x[i] - table_x[i+1]) * y01 - (RealType(table_x[i]) - x);
y_above_lbound = y - (RealType(table_y[i]) + (RealType(table_x[i]) - x) * RealType(table_y[i]) * RealType(table_x[i]));
}
else { // concave
y_above_lbound = RealType(table_x[i] - table_x[i+1]) * y01 - (RealType(table_x[i]) - x);
y_above_ubound = y - (RealType(table_y[i]) + (RealType(table_x[i]) - x) * RealType(table_y[i]) * RealType(table_x[i]));
}
if (y_above_ubound < 0 // if above the upper bound reject immediately
&&
(
y_above_lbound < 0 // If below the lower bound accept immediately
||
y < f(x) // Otherwise it's between the bounds and we need a full check
)
) {
return x * sign;
}
}
}
static RealType f(RealType x) {
using std::exp;
return exp(-(x*x/2));
}
// Generate from the tail using rejection sampling from the exponential(x_1) distribution,
// shifted by x_1. This looks a little different from the usual rejection sampling because it
// transforms the condition by taking the log of both sides, thus avoiding the costly exp() call
// on the RHS, then takes advantage of the fact that -log(unif01) is simply generating an
// exponential (by inverse cdf sampling) by replacing the log(unif01) on the LHS with a
// exponential(1) draw, y.
template<class Engine>
RealType generate_tail(Engine& eng) {
const RealType tail_start = RealType(normal_table<double>::table_x[1]);
boost::random::exponential_distribution<RealType> exp_x(tail_start);
boost::random::exponential_distribution<RealType> exp_y;
for(;;) {
RealType x = exp_x(eng);
RealType y = exp_y(eng);
// If we were doing non-transformed rejection sampling, this condition would be:
// if (unif01 < exp(-.5*x*x)) return x + tail_start;
if(2*y > x*x) return x + tail_start;
}
}
};
} // namespace detail
/**
* Instantiations of class template normal_distribution model a
* \random_distribution. Such a distribution produces random numbers
* @c x distributed with probability density function
* \f$\displaystyle p(x) =
* \frac{1}{\sqrt{2\pi}\sigma} e^{-\frac{(x-\mu)^2}{2\sigma^2}}
* \f$,
* where mean and sigma are the parameters of the distribution.
*
* The implementation uses the "ziggurat" algorithm, as described in
*
* @blockquote
* "The Ziggurat Method for Generating Random Variables",
* George Marsaglia and Wai Wan Tsang, Journal of Statistical Software,
* Volume 5, Number 8 (2000), 1-7.
* @endblockquote
*/
template<class RealType = double>
class normal_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type {
public:
typedef normal_distribution distribution_type;
/**
* Constructs a @c param_type with a given mean and
* standard deviation.
*
* Requires: sigma >= 0
*/
explicit param_type(RealType mean_arg = RealType(0.0),
RealType sigma_arg = RealType(1.0))
: _mean(mean_arg),
_sigma(sigma_arg)
{}
/** Returns the mean of the distribution. */
RealType mean() const { return _mean; }
/** Returns the standand deviation of the distribution. */
RealType sigma() const { return _sigma; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._mean << " " << parm._sigma ; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._mean >> std::ws >> parm._sigma; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _mean;
RealType _sigma;
};
/**
* Constructs a @c normal_distribution object. @c mean and @c sigma are
* the parameters for the distribution.
*
* Requires: sigma >= 0
*/
explicit normal_distribution(const RealType& mean_arg = RealType(0.0),
const RealType& sigma_arg = RealType(1.0))
: _mean(mean_arg), _sigma(sigma_arg)
{
BOOST_ASSERT(_sigma >= RealType(0));
}
/**
* Constructs a @c normal_distribution object from its parameters.
*/
explicit normal_distribution(const param_type& parm)
: _mean(parm.mean()), _sigma(parm.sigma())
{}
/** Returns the mean of the distribution. */
RealType mean() const { return _mean; }
/** Returns the standard deviation of the distribution. */
RealType sigma() const { return _sigma; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -std::numeric_limits<RealType>::infinity(); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_mean, _sigma); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_mean = parm.mean();
_sigma = parm.sigma();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Returns a normal variate. */
template<class Engine>
result_type operator()(Engine& eng)
{
detail::unit_normal_distribution<RealType> impl;
return impl(eng) * _sigma + _mean;
}
/** Returns a normal variate with parameters specified by @c param. */
template<class URNG>
result_type operator()(URNG& urng, const param_type& parm)
{
return normal_distribution(parm)(urng);
}
/** Writes a @c normal_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, normal_distribution, nd)
{
os << nd._mean << " " << nd._sigma;
return os;
}
/** Reads a @c normal_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, normal_distribution, nd)
{
is >> std::ws >> nd._mean >> std::ws >> nd._sigma;
return is;
}
/**
* Returns true if the two instances of @c normal_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(normal_distribution, lhs, rhs)
{
return lhs._mean == rhs._mean && lhs._sigma == rhs._sigma;
}
/**
* Returns true if the two instances of @c normal_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(normal_distribution)
private:
RealType _mean, _sigma;
};
} // namespace random
using random::normal_distribution;
} // namespace boost
#endif // BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP

View File

@ -1,466 +0,0 @@
/* boost random/piecewise_constant_distribution.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_HPP_INCLUDED
#include <vector>
#include <numeric>
#include <boost/assert.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/vector_io.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost {
namespace random {
/**
* The class @c piecewise_constant_distribution models a \random_distribution.
*/
template<class RealType = double, class WeightType = double>
class piecewise_constant_distribution {
public:
typedef std::size_t input_type;
typedef RealType result_type;
class param_type {
public:
typedef piecewise_constant_distribution distribution_type;
/**
* Constructs a @c param_type object, representing a distribution
* that produces values uniformly distributed in the range [0, 1).
*/
param_type()
{
_weights.push_back(WeightType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
/**
* Constructs a @c param_type object from two iterator ranges
* containing the interval boundaries and the interval weights.
* If there are less than two boundaries, then this is equivalent to
* the default constructor and creates a single interval, [0, 1).
*
* The values of the interval boundaries must be strictly
* increasing, and the number of weights must be one less than
* the number of interval boundaries. If there are extra
* weights, they are ignored.
*/
template<class IntervalIter, class WeightIter>
param_type(IntervalIter intervals_first, IntervalIter intervals_last,
WeightIter weight_first)
: _intervals(intervals_first, intervals_last)
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
_weights.push_back(WeightType(1));
} else {
_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
_weights.push_back(*weight_first++);
}
}
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a @c param_type object from an
* initializer_list containing the interval boundaries
* and a unary function specifying the weights. Each
* weight is determined by calling the function at the
* midpoint of the corresponding interval.
*
* If the initializer_list contains less than two elements,
* this is equivalent to the default constructor and the
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
template<class T, class F>
param_type(const std::initializer_list<T>& il, F f)
: _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
_weights.push_back(WeightType(1));
} else {
_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType midpoint = (_intervals[i] + _intervals[i + 1]) / 2;
_weights.push_back(f(midpoint));
}
}
}
#endif
/**
* Constructs a @c param_type object from Boost.Range
* ranges holding the interval boundaries and the weights. If
* there are less than two interval boundaries, this is equivalent
* to the default constructor and the distribution will produce
* values uniformly distributed in the range [0, 1). The
* number of weights must be one less than the number of
* interval boundaries.
*/
template<class IntervalRange, class WeightRange>
param_type(const IntervalRange& intervals_arg,
const WeightRange& weights_arg)
: _intervals(boost::begin(intervals_arg), boost::end(intervals_arg)),
_weights(boost::begin(weights_arg), boost::end(weights_arg))
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
_weights.push_back(WeightType(1));
}
}
/**
* Constructs the parameters for a distribution that approximates a
* function. The range of the distribution is [xmin, xmax). This
* range is divided into nw equally sized intervals and the weights
* are found by calling the unary function f on the midpoints of the
* intervals.
*/
template<class F>
param_type(std::size_t nw, RealType xmin, RealType xmax, F f)
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_weights.push_back(f(xmin + k*delta + delta/2));
_intervals.push_back(xmin + k*delta);
}
_intervals.push_back(xmax);
}
/** Returns a vector containing the interval boundaries. */
std::vector<RealType> intervals() const { return _intervals; }
/**
* Returns a vector containing the probability densities
* over all the intervals of the distribution.
*/
std::vector<RealType> densities() const
{
RealType sum = std::accumulate(_weights.begin(), _weights.end(),
static_cast<RealType>(0));
std::vector<RealType> result;
result.reserve(_weights.size());
for(std::size_t i = 0; i < _weights.size(); ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
result.push_back(_weights[i] / (sum * width));
}
return result;
}
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
detail::print_vector(os, parm._intervals);
detail::print_vector(os, parm._weights);
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
std::vector<RealType> new_intervals;
std::vector<WeightType> new_weights;
detail::read_vector(is, new_intervals);
detail::read_vector(is, new_weights);
if(is) {
parm._intervals.swap(new_intervals);
parm._weights.swap(new_weights);
}
return is;
}
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{
return lhs._intervals == rhs._intervals
&& lhs._weights == rhs._weights;
}
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
friend class piecewise_constant_distribution;
std::vector<RealType> _intervals;
std::vector<WeightType> _weights;
};
/**
* Creates a new @c piecewise_constant_distribution with
* a single interval, [0, 1).
*/
piecewise_constant_distribution()
{
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
/**
* Constructs a piecewise_constant_distribution from two iterator ranges
* containing the interval boundaries and the interval weights.
* If there are less than two boundaries, then this is equivalent to
* the default constructor and creates a single interval, [0, 1).
*
* The values of the interval boundaries must be strictly
* increasing, and the number of weights must be one less than
* the number of interval boundaries. If there are extra
* weights, they are ignored.
*
* For example,
*
* @code
* double intervals[] = { 0.0, 1.0, 4.0 };
* double weights[] = { 1.0, 1.0 };
* piecewise_constant_distribution<> dist(
* &intervals[0], &intervals[0] + 3, &weights[0]);
* @endcode
*
* The distribution has a 50% chance of producing a
* value between 0 and 1 and a 50% chance of producing
* a value between 1 and 4.
*/
template<class IntervalIter, class WeightIter>
piecewise_constant_distribution(IntervalIter first_interval,
IntervalIter last_interval,
WeightIter first_weight)
: _intervals(first_interval, last_interval)
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
std::vector<WeightType> actual_weights;
actual_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
actual_weights.push_back(*first_weight++);
}
typedef discrete_distribution<std::size_t, WeightType> bins_type;
typename bins_type::param_type bins_param(actual_weights);
_bins.param(bins_param);
}
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a piecewise_constant_distribution from an
* initializer_list containing the interval boundaries
* and a unary function specifying the weights. Each
* weight is determined by calling the function at the
* midpoint of the corresponding interval.
*
* If the initializer_list contains less than two elements,
* this is equivalent to the default constructor and the
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
template<class T, class F>
piecewise_constant_distribution(std::initializer_list<T> il, F f)
: _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
std::vector<WeightType> actual_weights;
actual_weights.reserve(_intervals.size() - 1);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType midpoint = (_intervals[i] + _intervals[i + 1]) / 2;
actual_weights.push_back(f(midpoint));
}
typedef discrete_distribution<std::size_t, WeightType> bins_type;
typename bins_type::param_type bins_param(actual_weights);
_bins.param(bins_param);
}
}
#endif
/**
* Constructs a piecewise_constant_distribution from Boost.Range
* ranges holding the interval boundaries and the weights. If
* there are less than two interval boundaries, this is equivalent
* to the default constructor and the distribution will produce
* values uniformly distributed in the range [0, 1). The
* number of weights must be one less than the number of
* interval boundaries.
*/
template<class IntervalsRange, class WeightsRange>
piecewise_constant_distribution(const IntervalsRange& intervals_arg,
const WeightsRange& weights_arg)
: _bins(weights_arg),
_intervals(boost::begin(intervals_arg), boost::end(intervals_arg))
{
if(_intervals.size() < 2) {
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
}
/**
* Constructs a piecewise_constant_distribution that approximates a
* function. The range of the distribution is [xmin, xmax). This
* range is divided into nw equally sized intervals and the weights
* are found by calling the unary function f on the midpoints of the
* intervals.
*/
template<class F>
piecewise_constant_distribution(std::size_t nw,
RealType xmin,
RealType xmax,
F f)
: _bins(nw, xmin, xmax, f)
{
if(nw == 0) { nw = 1; }
RealType delta = (xmax - xmin) / nw;
_intervals.reserve(nw + 1);
for(std::size_t i = 0; i < nw; ++i) {
_intervals.push_back(xmin + i * delta);
}
_intervals.push_back(xmax);
}
/**
* Constructs a piecewise_constant_distribution from its parameters.
*/
explicit piecewise_constant_distribution(const param_type& parm)
: _bins(parm._weights),
_intervals(parm._intervals)
{
}
/**
* Returns a value distributed according to the parameters of the
* piecewist_constant_distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
std::size_t i = _bins(urng);
return uniform_real<RealType>(_intervals[i], _intervals[i+1])(urng);
}
/**
* Returns a value distributed according to the parameters
* specified by param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return piecewise_constant_distribution(parm)(urng);
}
/** Returns the smallest value that the distribution can produce. */
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return _intervals.front(); }
/** Returns the largest value that the distribution can produce. */
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return _intervals.back(); }
/**
* Returns a vector containing the probability density
* over each interval.
*/
std::vector<RealType> densities() const
{
std::vector<RealType> result(_bins.probabilities());
for(std::size_t i = 0; i < result.size(); ++i) {
result[i] /= (_intervals[i+1] - _intervals[i]);
}
return(result);
}
/** Returns a vector containing the interval boundaries. */
std::vector<RealType> intervals() const { return _intervals; }
/** Returns the parameters of the distribution. */
param_type param() const
{
return param_type(_intervals, _bins.probabilities());
}
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
std::vector<RealType> new_intervals(parm._intervals);
typedef discrete_distribution<std::size_t, WeightType> bins_type;
typename bins_type::param_type bins_param(parm._weights);
_bins.param(bins_param);
_intervals.swap(new_intervals);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { _bins.reset(); }
/** Writes a distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(
os, piecewise_constant_distribution, pcd)
{
os << pcd.param();
return os;
}
/** Reads a distribution from a @c std::istream */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(
is, piecewise_constant_distribution, pcd)
{
param_type parm;
if(is >> parm) {
pcd.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will return the
* same sequence of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(
piecewise_constant_distribution, lhs, rhs)
{
return lhs._bins == rhs._bins && lhs._intervals == rhs._intervals;
}
/**
* Returns true if the two distributions may return different
* sequences of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(piecewise_constant_distribution)
private:
discrete_distribution<std::size_t, WeightType> _bins;
std::vector<RealType> _intervals;
};
}
}
#endif

View File

@ -1,531 +0,0 @@
/* boost random/piecewise_linear_distribution.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_HPP_INCLUDED
#define BOOST_RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_HPP_INCLUDED
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <boost/assert.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/vector_io.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost {
namespace random {
/**
* The class @c piecewise_linear_distribution models a \random_distribution.
*/
template<class RealType = double>
class piecewise_linear_distribution {
public:
typedef std::size_t input_type;
typedef RealType result_type;
class param_type {
public:
typedef piecewise_linear_distribution distribution_type;
/**
* Constructs a @c param_type object, representing a distribution
* that produces values uniformly distributed in the range [0, 1).
*/
param_type()
{
_weights.push_back(RealType(1));
_weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
/**
* Constructs a @c param_type object from two iterator ranges
* containing the interval boundaries and weights at the boundaries.
* If there are fewer than two boundaries, then this is equivalent to
* the default constructor and the distribution will produce values
* uniformly distributed in the range [0, 1).
*
* The values of the interval boundaries must be strictly
* increasing, and the number of weights must be the same as
* the number of interval boundaries. If there are extra
* weights, they are ignored.
*/
template<class IntervalIter, class WeightIter>
param_type(IntervalIter intervals_first, IntervalIter intervals_last,
WeightIter weight_first)
: _intervals(intervals_first, intervals_last)
{
if(_intervals.size() < 2) {
_intervals.clear();
_weights.push_back(RealType(1));
_weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
_weights.reserve(_intervals.size());
for(std::size_t i = 0; i < _intervals.size(); ++i) {
_weights.push_back(*weight_first++);
}
}
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a @c param_type object from an initializer_list
* containing the interval boundaries and a unary function
* specifying the weights at the boundaries. Each weight is
* determined by calling the function at the corresponding point.
*
* If the initializer_list contains fewer than two elements,
* this is equivalent to the default constructor and the
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
template<class T, class F>
param_type(const std::initializer_list<T>& il, F f)
: _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
_intervals.clear();
_weights.push_back(RealType(1));
_weights.push_back(RealType(1));
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
} else {
_weights.reserve(_intervals.size());
for(typename std::vector<RealType>::const_iterator
iter = _intervals.begin(), end = _intervals.end();
iter != end; ++iter)
{
_weights.push_back(f(*iter));
}
}
}
#endif
/**
* Constructs a @c param_type object from Boost.Range ranges holding
* the interval boundaries and the weights at the boundaries. If
* there are fewer than two interval boundaries, this is equivalent
* to the default constructor and the distribution will produce
* values uniformly distributed in the range [0, 1). The
* number of weights must be equal to the number of
* interval boundaries.
*/
template<class IntervalRange, class WeightRange>
param_type(const IntervalRange& intervals_arg,
const WeightRange& weights_arg)
: _intervals(boost::begin(intervals_arg), boost::end(intervals_arg)),
_weights(boost::begin(weights_arg), boost::end(weights_arg))
{
if(_intervals.size() < 2) {
_weights.clear();
_weights.push_back(RealType(1));
_weights.push_back(RealType(1));
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
}
}
/**
* Constructs the parameters for a distribution that approximates a
* function. The range of the distribution is [xmin, xmax). This
* range is divided into nw equally sized intervals and the weights
* are found by calling the unary function f on the boundaries of the
* intervals.
*/
template<class F>
param_type(std::size_t nw, RealType xmin, RealType xmax, F f)
{
std::size_t n = (nw == 0) ? 1 : nw;
double delta = (xmax - xmin) / n;
BOOST_ASSERT(delta > 0);
for(std::size_t k = 0; k < n; ++k) {
_weights.push_back(f(xmin + k*delta));
_intervals.push_back(xmin + k*delta);
}
_weights.push_back(f(xmax));
_intervals.push_back(xmax);
}
/** Returns a vector containing the interval boundaries. */
std::vector<RealType> intervals() const { return _intervals; }
/**
* Returns a vector containing the probability densities
* at all the interval boundaries.
*/
std::vector<RealType> densities() const
{
RealType sum = static_cast<RealType>(0);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
sum += (_weights[i] + _weights[i + 1]) * width / 2;
}
std::vector<RealType> result;
result.reserve(_weights.size());
for(typename std::vector<RealType>::const_iterator
iter = _weights.begin(), end = _weights.end();
iter != end; ++iter)
{
result.push_back(*iter / sum);
}
return result;
}
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
detail::print_vector(os, parm._intervals);
detail::print_vector(os, parm._weights);
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
std::vector<RealType> new_intervals;
std::vector<RealType> new_weights;
detail::read_vector(is, new_intervals);
detail::read_vector(is, new_weights);
if(is) {
parm._intervals.swap(new_intervals);
parm._weights.swap(new_weights);
}
return is;
}
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{
return lhs._intervals == rhs._intervals
&& lhs._weights == rhs._weights;
}
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
friend class piecewise_linear_distribution;
std::vector<RealType> _intervals;
std::vector<RealType> _weights;
};
/**
* Creates a new @c piecewise_linear_distribution that
* produces values uniformly distributed in the range [0, 1).
*/
piecewise_linear_distribution()
{
default_init();
}
/**
* Constructs a piecewise_linear_distribution from two iterator ranges
* containing the interval boundaries and the weights at the boundaries.
* If there are fewer than two boundaries, then this is equivalent to
* the default constructor and creates a distribution that
* produces values uniformly distributed in the range [0, 1).
*
* The values of the interval boundaries must be strictly
* increasing, and the number of weights must be equal to
* the number of interval boundaries. If there are extra
* weights, they are ignored.
*
* For example,
*
* @code
* double intervals[] = { 0.0, 1.0, 2.0 };
* double weights[] = { 0.0, 1.0, 0.0 };
* piecewise_constant_distribution<> dist(
* &intervals[0], &intervals[0] + 3, &weights[0]);
* @endcode
*
* produces a triangle distribution.
*/
template<class IntervalIter, class WeightIter>
piecewise_linear_distribution(IntervalIter first_interval,
IntervalIter last_interval,
WeightIter first_weight)
: _intervals(first_interval, last_interval)
{
if(_intervals.size() < 2) {
default_init();
} else {
_weights.reserve(_intervals.size());
for(std::size_t i = 0; i < _intervals.size(); ++i) {
_weights.push_back(*first_weight++);
}
init();
}
}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/**
* Constructs a piecewise_linear_distribution from an
* initializer_list containing the interval boundaries
* and a unary function specifying the weights. Each
* weight is determined by calling the function at the
* corresponding interval boundary.
*
* If the initializer_list contains fewer than two elements,
* this is equivalent to the default constructor and the
* distribution will produce values uniformly distributed
* in the range [0, 1).
*/
template<class T, class F>
piecewise_linear_distribution(std::initializer_list<T> il, F f)
: _intervals(il.begin(), il.end())
{
if(_intervals.size() < 2) {
default_init();
} else {
_weights.reserve(_intervals.size());
for(typename std::vector<RealType>::const_iterator
iter = _intervals.begin(), end = _intervals.end();
iter != end; ++iter)
{
_weights.push_back(f(*iter));
}
init();
}
}
#endif
/**
* Constructs a piecewise_linear_distribution from Boost.Range
* ranges holding the interval boundaries and the weights. If
* there are fewer than two interval boundaries, this is equivalent
* to the default constructor and the distribution will produce
* values uniformly distributed in the range [0, 1). The
* number of weights must be equal to the number of
* interval boundaries.
*/
template<class IntervalsRange, class WeightsRange>
piecewise_linear_distribution(const IntervalsRange& intervals_arg,
const WeightsRange& weights_arg)
: _intervals(boost::begin(intervals_arg), boost::end(intervals_arg)),
_weights(boost::begin(weights_arg), boost::end(weights_arg))
{
if(_intervals.size() < 2) {
default_init();
} else {
init();
}
}
/**
* Constructs a piecewise_linear_distribution that approximates a
* function. The range of the distribution is [xmin, xmax). This
* range is divided into nw equally sized intervals and the weights
* are found by calling the unary function f on the interval boundaries.
*/
template<class F>
piecewise_linear_distribution(std::size_t nw,
RealType xmin,
RealType xmax,
F f)
{
if(nw == 0) { nw = 1; }
RealType delta = (xmax - xmin) / nw;
_intervals.reserve(nw + 1);
for(std::size_t i = 0; i < nw; ++i) {
RealType x = xmin + i * delta;
_intervals.push_back(x);
_weights.push_back(f(x));
}
_intervals.push_back(xmax);
_weights.push_back(f(xmax));
init();
}
/**
* Constructs a piecewise_linear_distribution from its parameters.
*/
explicit piecewise_linear_distribution(const param_type& parm)
: _intervals(parm._intervals),
_weights(parm._weights)
{
init();
}
/**
* Returns a value distributed according to the parameters of the
* piecewise_linear_distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
std::size_t i = _bins(urng);
bool is_in_rectangle = (i % 2 == 0);
i = i / 2;
uniform_real<RealType> dist(_intervals[i], _intervals[i+1]);
if(is_in_rectangle) {
return dist(urng);
} else if(_weights[i] < _weights[i+1]) {
return (std::max)(dist(urng), dist(urng));
} else {
return (std::min)(dist(urng), dist(urng));
}
}
/**
* Returns a value distributed according to the parameters
* specified by param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return piecewise_linear_distribution(parm)(urng);
}
/** Returns the smallest value that the distribution can produce. */
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return _intervals.front(); }
/** Returns the largest value that the distribution can produce. */
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return _intervals.back(); }
/**
* Returns a vector containing the probability densities
* at the interval boundaries.
*/
std::vector<RealType> densities() const
{
RealType sum = static_cast<RealType>(0);
for(std::size_t i = 0; i < _intervals.size() - 1; ++i) {
RealType width = _intervals[i + 1] - _intervals[i];
sum += (_weights[i] + _weights[i + 1]) * width / 2;
}
std::vector<RealType> result;
result.reserve(_weights.size());
for(typename std::vector<RealType>::const_iterator
iter = _weights.begin(), end = _weights.end();
iter != end; ++iter)
{
result.push_back(*iter / sum);
}
return result;
}
/** Returns a vector containing the interval boundaries. */
std::vector<RealType> intervals() const { return _intervals; }
/** Returns the parameters of the distribution. */
param_type param() const
{
return param_type(_intervals, _weights);
}
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
std::vector<RealType> new_intervals(parm._intervals);
std::vector<RealType> new_weights(parm._weights);
init(new_intervals, new_weights);
_intervals.swap(new_intervals);
_weights.swap(new_weights);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { _bins.reset(); }
/** Writes a distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(
os, piecewise_linear_distribution, pld)
{
os << pld.param();
return os;
}
/** Reads a distribution from a @c std::istream */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(
is, piecewise_linear_distribution, pld)
{
param_type parm;
if(is >> parm) {
pld.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will return the
* same sequence of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(
piecewise_linear_distribution, lhs, rhs)
{
return lhs._intervals == rhs._intervals && lhs._weights == rhs._weights;
}
/**
* Returns true if the two distributions may return different
* sequences of values, when passed equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(piecewise_linear_distribution)
private:
/// @cond \show_private
void init(const std::vector<RealType>& intervals_arg,
const std::vector<RealType>& weights_arg)
{
using std::abs;
std::vector<RealType> bin_weights;
bin_weights.reserve((intervals_arg.size() - 1) * 2);
for(std::size_t i = 0; i < intervals_arg.size() - 1; ++i) {
RealType width = intervals_arg[i + 1] - intervals_arg[i];
RealType w1 = weights_arg[i];
RealType w2 = weights_arg[i + 1];
bin_weights.push_back((std::min)(w1, w2) * width);
bin_weights.push_back(abs(w1 - w2) * width / 2);
}
typedef discrete_distribution<std::size_t, RealType> bins_type;
typename bins_type::param_type bins_param(bin_weights);
_bins.param(bins_param);
}
void init()
{
init(_intervals, _weights);
}
void default_init()
{
_intervals.clear();
_intervals.push_back(RealType(0));
_intervals.push_back(RealType(1));
_weights.clear();
_weights.push_back(RealType(1));
_weights.push_back(RealType(1));
init();
}
discrete_distribution<std::size_t, RealType> _bins;
std::vector<RealType> _intervals;
std::vector<RealType> _weights;
/// @endcond
};
}
}
#endif

View File

@ -1,360 +0,0 @@
/* boost random/poisson_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
#define BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <cstdlib>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
namespace detail {
template<class RealType>
struct poisson_table {
static RealType value[10];
};
template<class RealType>
RealType poisson_table<RealType>::value[10] = {
0.0,
0.0,
0.69314718055994529,
1.7917594692280550,
3.1780538303479458,
4.7874917427820458,
6.5792512120101012,
8.5251613610654147,
10.604602902745251,
12.801827480081469
};
}
/**
* An instantiation of the class template @c poisson_distribution is a
* model of \random_distribution. The poisson distribution has
* \f$p(i) = \frac{e^{-\lambda}\lambda^i}{i!}\f$
*
* This implementation is based on the PTRD algorithm described
*
* @blockquote
* "The transformed rejection method for generating Poisson random variables",
* Wolfgang Hormann, Insurance: Mathematics and Economics
* Volume 12, Issue 1, February 1993, Pages 39-45
* @endblockquote
*/
template<class IntType = int, class RealType = double>
class poisson_distribution {
public:
typedef IntType result_type;
typedef RealType input_type;
class param_type {
public:
typedef poisson_distribution distribution_type;
/**
* Construct a param_type object with the parameter "mean"
*
* Requires: mean > 0
*/
explicit param_type(RealType mean_arg = RealType(1))
: _mean(mean_arg)
{
BOOST_ASSERT(_mean > 0);
}
/* Returns the "mean" parameter of the distribution. */
RealType mean() const { return _mean; }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const param_type& parm)
{
os << parm._mean;
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, param_type& parm)
{
is >> parm._mean;
return is;
}
#endif
/** Returns true if the parameters have the same values. */
friend bool operator==(const param_type& lhs, const param_type& rhs)
{
return lhs._mean == rhs._mean;
}
/** Returns true if the parameters have different values. */
friend bool operator!=(const param_type& lhs, const param_type& rhs)
{
return !(lhs == rhs);
}
private:
RealType _mean;
};
/**
* Constructs a @c poisson_distribution with the parameter @c mean.
*
* Requires: mean > 0
*/
explicit poisson_distribution(RealType mean_arg = RealType(1))
: _mean(mean_arg)
{
BOOST_ASSERT(_mean > 0);
init();
}
/**
* Construct an @c poisson_distribution object from the
* parameters.
*/
explicit poisson_distribution(const param_type& parm)
: _mean(parm.mean())
{
init();
}
/**
* Returns a random variate distributed according to the
* poisson distribution.
*/
template<class URNG>
IntType operator()(URNG& urng) const
{
if(use_inversion()) {
return invert(urng);
} else {
return generate(urng);
}
}
/**
* Returns a random variate distributed according to the
* poisson distribution with parameters specified by param.
*/
template<class URNG>
IntType operator()(URNG& urng, const param_type& parm) const
{
return poisson_distribution(parm)(urng);
}
/** Returns the "mean" parameter of the distribution. */
RealType mean() const { return _mean; }
/** Returns the smallest value that the distribution can produce. */
IntType min BOOST_PREVENT_MACRO_SUBSTITUTION() const { return 0; }
/** Returns the largest value that the distribution can produce. */
IntType max BOOST_PREVENT_MACRO_SUBSTITUTION() const
{ return (std::numeric_limits<IntType>::max)(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_mean); }
/** Sets parameters of the distribution. */
void param(const param_type& parm)
{
_mean = parm.mean();
init();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
/** Writes the parameters of the distribution to a @c std::ostream. */
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const poisson_distribution& pd)
{
os << pd.param();
return os;
}
/** Reads the parameters of the distribution from a @c std::istream. */
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, poisson_distribution& pd)
{
pd.read(is);
return is;
}
#endif
/** Returns true if the two distributions will produce the same
sequence of values, given equal generators. */
friend bool operator==(const poisson_distribution& lhs,
const poisson_distribution& rhs)
{
return lhs._mean == rhs._mean;
}
/** Returns true if the two distributions could produce different
sequences of values, given equal generators. */
friend bool operator!=(const poisson_distribution& lhs,
const poisson_distribution& rhs)
{
return !(lhs == rhs);
}
private:
/// @cond show_private
template<class CharT, class Traits>
void read(std::basic_istream<CharT, Traits>& is) {
param_type parm;
if(is >> parm) {
param(parm);
}
}
bool use_inversion() const
{
return _mean < 10;
}
static RealType log_factorial(IntType k)
{
BOOST_ASSERT(k >= 0);
BOOST_ASSERT(k < 10);
return detail::poisson_table<RealType>::value[k];
}
void init()
{
using std::sqrt;
using std::exp;
if(use_inversion()) {
_exp_mean = exp(-_mean);
} else {
_ptrd.smu = sqrt(_mean);
_ptrd.b = 0.931 + 2.53 * _ptrd.smu;
_ptrd.a = -0.059 + 0.02483 * _ptrd.b;
_ptrd.inv_alpha = 1.1239 + 1.1328 / (_ptrd.b - 3.4);
_ptrd.v_r = 0.9277 - 3.6224 / (_ptrd.b - 2);
}
}
template<class URNG>
IntType generate(URNG& urng) const
{
using std::floor;
using std::abs;
using std::log;
while(true) {
RealType u;
RealType v = uniform_01<RealType>()(urng);
if(v <= 0.86 * _ptrd.v_r) {
u = v / _ptrd.v_r - 0.43;
return static_cast<IntType>(floor(
(2*_ptrd.a/(0.5-abs(u)) + _ptrd.b)*u + _mean + 0.445));
}
if(v >= _ptrd.v_r) {
u = uniform_01<RealType>()(urng) - 0.5;
} else {
u = v/_ptrd.v_r - 0.93;
u = ((u < 0)? -0.5 : 0.5) - u;
v = uniform_01<RealType>()(urng) * _ptrd.v_r;
}
RealType us = 0.5 - abs(u);
if(us < 0.013 && v > us) {
continue;
}
RealType k = floor((2*_ptrd.a/us + _ptrd.b)*u+_mean+0.445);
v = v*_ptrd.inv_alpha/(_ptrd.a/(us*us) + _ptrd.b);
RealType log_sqrt_2pi = 0.91893853320467267;
if(k >= 10) {
if(log(v*_ptrd.smu) <= (k + 0.5)*log(_mean/k)
- _mean
- log_sqrt_2pi
+ k
- (1/12. - (1/360. - 1/(1260.*k*k))/(k*k))/k) {
return static_cast<IntType>(k);
}
} else if(k >= 0) {
if(log(v) <= k*log(_mean)
- _mean
- log_factorial(static_cast<IntType>(k))) {
return static_cast<IntType>(k);
}
}
}
}
template<class URNG>
IntType invert(URNG& urng) const
{
RealType p = _exp_mean;
IntType x = 0;
RealType u = uniform_01<RealType>()(urng);
while(u > p) {
u = u - p;
++x;
p = _mean * p / x;
}
return x;
}
RealType _mean;
union {
// for ptrd
struct {
RealType v_r;
RealType a;
RealType b;
RealType smu;
RealType inv_alpha;
} _ptrd;
// for inversion
RealType _exp_mean;
};
/// @endcond
};
} // namespace random
using random::poisson_distribution;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_POISSON_DISTRIBUTION_HPP

View File

@ -1,143 +0,0 @@
/* boost random/random_device.hpp header file
*
* Copyright Jens Maurer 2000
* Copyright Steven Watanabe 2010-2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* $Id$
*
* Revision history
* 2000-02-18 Portability fixes (thanks to Beman Dawes)
*/
// See http://www.boost.org/libs/random for documentation.
#ifndef BOOST_RANDOM_RANDOM_DEVICE_HPP
#define BOOST_RANDOM_RANDOM_DEVICE_HPP
#include <string>
#include <boost/config.hpp>
#include <boost/noncopyable.hpp>
#include <boost/random/detail/auto_link.hpp>
#include <boost/system/config.hpp> // force autolink to find Boost.System
namespace boost {
namespace random {
/**
* Class \random_device models a \nondeterministic_random_number_generator.
* It uses one or more implementation-defined stochastic processes to
* generate a sequence of uniformly distributed non-deterministic random
* numbers. For those environments where a non-deterministic random number
* generator is not available, class random_device must not be implemented. See
*
* @blockquote
* "Randomness Recommendations for Security", D. Eastlake, S. Crocker,
* J. Schiller, Network Working Group, RFC 1750, December 1994
* @endblockquote
*
* for further discussions.
*
* @xmlnote
* Some operating systems abstract the computer hardware enough
* to make it difficult to non-intrusively monitor stochastic processes.
* However, several do provide a special device for exactly this purpose.
* It seems to be impossible to emulate the functionality using Standard
* C++ only, so users should be aware that this class may not be available
* on all platforms.
* @endxmlnote
*
* <b>Implementation Note for Linux</b>
*
* On the Linux operating system, token is interpreted as a filesystem
* path. It is assumed that this path denotes an operating system
* pseudo-device which generates a stream of non-deterministic random
* numbers. The pseudo-device should never signal an error or end-of-file.
* Otherwise, @c std::ios_base::failure is thrown. By default,
* \random_device uses the /dev/urandom pseudo-device to retrieve
* the random numbers. Another option would be to specify the /dev/random
* pseudo-device, which blocks on reads if the entropy pool has no more
* random bits available.
*
* <b>Implementation 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/performance/nondet_random_speed.cpp">
* nondet_random_speed.cpp</a> measures the execution times of the
* random_device.hpp implementation of the above algorithms in a tight
* loop. The performance has been evaluated on an
* Intel(R) Core(TM) i7 CPU Q 840 \@ 1.87GHz, 1867 Mhz with
* Visual C++ 2010, Microsoft Windows 7 Professional and with gcc 4.4.5,
* Ubuntu Linux 2.6.35-25-generic.
*
* <table cols="2">
* <tr><th>Platform</th><th>time per invocation [microseconds]</th></tr>
* <tr><td> Windows </td><td>2.9</td></tr>
* <tr><td> Linux </td><td>1.7</td></tr>
* </table>
*
* The measurement error is estimated at +/- 1 usec.
*/
class random_device : private noncopyable
{
public:
typedef unsigned int result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
/** Returns the smallest value that the \random_device can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }
/** Returns the largest value that the \random_device can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return ~0u; }
/** Constructs a @c random_device, optionally using the default device. */
BOOST_RANDOM_DECL random_device();
/**
* Constructs a @c random_device, optionally using the given token as an
* access specification (for example, a URL) to some implementation-defined
* service for monitoring a stochastic process.
*/
BOOST_RANDOM_DECL explicit random_device(const std::string& token);
BOOST_RANDOM_DECL ~random_device();
/**
* Returns: An entropy estimate for the random numbers returned by
* operator(), in the range min() to log2( max()+1). A deterministic
* random number generator (e.g. a pseudo-random number engine)
* has entropy 0.
*
* Throws: Nothing.
*/
BOOST_RANDOM_DECL double entropy() const;
/** Returns a random value in the range [min, max]. */
BOOST_RANDOM_DECL unsigned int operator()();
/** Fills a range with random 32-bit values. */
template<class Iter>
void generate(Iter begin, Iter end)
{
for(; begin != end; ++begin) {
*begin = (*this)();
}
}
private:
class impl;
impl * pimpl;
};
} // namespace random
using random::random_device;
} // namespace boost
#endif /* BOOST_RANDOM_RANDOM_DEVICE_HPP */

View File

@ -1,73 +0,0 @@
/* boost random/random_number_generator.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
#include <boost/assert.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template random_number_generator model a
* RandomNumberGenerator (std:25.2.11 [lib.alg.random.shuffle]). On
* each invocation, it returns a uniformly distributed integer in
* the range [0..n).
*
* The template parameter IntType shall denote some integer-like value type.
*/
template<class URNG, class IntType = long>
class random_number_generator
{
public:
typedef URNG base_type;
typedef IntType argument_type;
typedef IntType result_type;
/**
* Constructs a random_number_generator functor with the given
* \uniform_random_number_generator as the underlying source of
* random numbers.
*/
random_number_generator(base_type& rng) : _rng(rng) {}
// compiler-generated copy ctor is fine
// assignment is disallowed because there is a reference member
/**
* Returns a value in the range [0, n)
*/
result_type operator()(argument_type n)
{
BOOST_ASSERT(n > 0);
return uniform_int_distribution<IntType>(0, n-1)(_rng);
}
private:
base_type& _rng;
};
} // namespace random
using random::random_number_generator;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP

View File

@ -1,99 +0,0 @@
/* boost random/ranlux.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 created
*/
#ifndef BOOST_RANDOM_RANLUX_HPP
#define BOOST_RANDOM_RANLUX_HPP
#include <boost/config.hpp>
#include <boost/random/subtract_with_carry.hpp>
#include <boost/random/discard_block.hpp>
namespace boost {
namespace random {
namespace detail {
/**
* The ranlux family of generators are described in
*
* @blockquote
* "A portable high-quality random number generator for lattice field theory
* calculations", M. Luescher, Computer Physics Communications, 79 (1994)
* pp 100-110.
* @endblockquote
*
* The levels are given in
*
* @blockquote
* "RANLUX: A Fortran implementation of the high-quality
* pseudorandom number generator of Luescher", F. James,
* Computer Physics Communications 79 (1994) 111-114
* @endblockquote
*/
class ranlux_documentation {};
}
typedef subtract_with_carry_engine<uint32_t, 24, 10, 24> ranlux_base;
typedef subtract_with_carry_01_engine<float, 24, 10, 24> ranlux_base_01;
typedef subtract_with_carry_01_engine<double, 48, 10, 24> ranlux64_base_01;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux_base, 223, 24> ranlux3;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux_base, 389, 24> ranlux4;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux_base_01, 223, 24> ranlux3_01;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux_base_01, 389, 24> ranlux4_01;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux64_base_01, 223, 24> ranlux64_3_01;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux64_base_01, 389, 24> ranlux64_4_01;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
typedef subtract_with_carry_engine<uint64_t, 48, 10, 24> ranlux64_base;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux64_base, 223, 24> ranlux64_3;
/** @copydoc boost::random::detail::ranlux_documentation */
typedef discard_block_engine<ranlux64_base, 389, 24> ranlux64_4;
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
typedef subtract_with_carry_engine<uint32_t, 24, 10, 24> ranlux24_base;
typedef subtract_with_carry_engine<uint64_t, 48, 5, 12> ranlux48_base;
typedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
typedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
#endif
}
using random::ranlux3;
using random::ranlux4;
using random::ranlux3_01;
using random::ranlux4_01;
using random::ranlux64_3_01;
using random::ranlux64_4_01;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
using random::ranlux64_3;
using random::ranlux64_4;
#endif
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP

View File

@ -1,118 +0,0 @@
/* boost random/seed_seq.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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_SEED_SEQ_HPP
#define BOOST_RANDOM_SEED_SEQ_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <cstddef>
#include <vector>
#include <algorithm>
#include <iterator>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif
namespace boost {
namespace random {
/**
* The class @c seed_seq stores a sequence of 32-bit words
* for seeding a \pseudo_random_number_generator. These
* words will be combined to fill the entire state of the
* generator.
*/
class seed_seq {
public:
typedef boost::uint_least32_t result_type;
/** Initializes a seed_seq to hold an empty sequence. */
seed_seq() {}
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
/** Initializes the sequence from an initializer_list. */
template<class T>
seed_seq(const std::initializer_list<T>& il) : v(il.begin(), il.end()) {}
#endif
/** Initializes the sequence from an iterator range. */
template<class Iter>
seed_seq(Iter first, Iter last) : v(first, last) {}
/** Initializes the sequence from Boost.Range range. */
template<class Range>
explicit seed_seq(const Range& range)
: v(boost::begin(range), boost::end(range)) {}
/**
* Fills a range with 32-bit values based on the stored sequence.
*
* Requires: Iter must be a Random Access Iterator whose value type
* is an unsigned integral type at least 32 bits wide.
*/
template<class Iter>
void generate(Iter first, Iter last) const
{
typedef typename std::iterator_traits<Iter>::value_type value_type;
std::fill(first, last, static_cast<value_type>(0x8b8b8b8bu));
std::size_t s = v.size();
std::size_t n = last - first;
std::size_t t =
(n >= 623) ? 11 :
(n >= 68) ? 7 :
(n >= 39) ? 5 :
(n >= 7) ? 3 :
(n - 1)/2;
std::size_t p = (n - t) / 2;
std::size_t q = p + t;
std::size_t m = (std::max)(s+1, n);
value_type mask = 0xffffffffu;
for(std::size_t k = 0; k < m; ++k) {
value_type r1 = static_cast<value_type>
(*(first + k%n) ^ *(first + (k+p)%n) ^ *(first + (k+n-1)%n));
r1 = r1 ^ (r1 >> 27);
r1 = (r1 * 1664525u) & mask;
value_type r2 = static_cast<value_type>(r1 +
((k == 0) ? s :
(k <= s) ? k % n + v[k - 1] :
(k % n)));
*(first + (k+p)%n) = (*(first + (k+p)%n) + r1) & mask;
*(first + (k+q)%n) = (*(first + (k+q)%n) + r2) & mask;
*(first + k%n) = r2;
}
for(std::size_t k = m; k < m + n; ++k) {
value_type r3 = static_cast<value_type>
((*(first + k%n) + *(first + (k+p)%n) + *(first + (k+n-1)%n))
& mask);
r3 = r3 ^ (r3 >> 27);
r3 = (r3 * 1566083941u) & mask;
value_type r4 = static_cast<value_type>(r3 - k%m);
*(first + (k+p)%n) ^= r3;
*(first + (k+q)%n) ^= r4;
*(first + k%n) = r4;
}
}
/** Returns the size of the sequence. */
std::size_t size() const { return v.size(); }
/** Writes the stored sequence to iter. */
template<class Iter>
void param(Iter out) { std::copy(v.begin(), v.end(), out); }
private:
std::vector<result_type> v;
};
}
}
#endif

View File

@ -1,269 +0,0 @@
/* boost random/shuffle_order.hpp header file
*
* Copyright Jens Maurer 2000-2001
* 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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_SHUFFLE_ORDER_HPP
#define BOOST_RANDOM_SHUFFLE_ORDER_HPP
#include <iostream>
#include <algorithm> // std::copy
#include <cassert>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
/**
* Instatiations of class template @c shuffle_order_engine model a
* \pseudo_random_number_generator. It mixes the output
* of some (usually \linear_congruential_engine)
* \uniform_random_number_generator to get better statistical properties.
* The algorithm is described in
*
* @blockquote
* "Improving a poor random number generator", Carter Bays
* and S.D. Durham, ACM Transactions on Mathematical Software,
* Vol 2, No. 1, March 1976, pp. 59-64.
* http://doi.acm.org/10.1145/355666.355670
* @endblockquote
*
* The output of the base generator is buffered in an array of
* length k. Every output X(n) has a second role: It gives an
* index into the array where X(n+1) will be retrieved. Used
* array elements are replaced with fresh output from the base
* generator.
*
* Template parameters are the base generator and the array
* length k, which should be around 100.
*/
template<class UniformRandomNumberGenerator, std::size_t k>
class shuffle_order_engine
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef typename base_type::result_type result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(std::size_t, buffer_size = k);
BOOST_STATIC_CONSTANT(std::size_t, table_size = k);
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
BOOST_STATIC_ASSERT(k > 0);
/**
* Constructs a @c shuffle_order_engine by invoking the
* default constructor of the base generator.
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
shuffle_order_engine() : _rng() { init(); }
/**
* Constructs a @c shuffle_output_engine by invoking the one-argument
* constructor of the base generator with the parameter seed.
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(shuffle_order_engine,
result_type, s)
{ _rng.seed(s); init(); }
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(shuffle_order_engine, SeedSeq, seq)
{ _rng.seed(seq); init(); }
/**
* Constructs a @c shuffle_output_engine by using a copy
* of the provided generator.
*
* Precondition: The template argument UniformRandomNumberGenerator
* shall denote a CopyConstructible type.
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
explicit shuffle_order_engine(const base_type & rng) : _rng(rng) { init(); }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
explicit shuffle_order_engine(base_type&& rng) : _rng(rng) { init(); }
#endif
template<class It> shuffle_order_engine(It& first, It last)
: _rng(first, last) { init(); }
void seed() { _rng.seed(); init(); }
/**
* Invokes the one-argument seed method of the base generator
* with the parameter seed and re-initializes the internal buffer array.
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(shuffle_order_engine,
result_type, seed_arg)
{ _rng.seed(seed_arg); init(); }
/**
* Invokes the one-argument seed method of the base generator
* with the parameter seq and re-initializes the internal buffer array.
*
* Complexity: Exactly k+1 invocations of the base generator.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(shuffle_order_engine, SeedSeq, seq)
{ _rng.seed(seq); init(); }
template<class It> void seed(It& first, It last)
{ _rng.seed(first, last); init(); }
const base_type& base() const { return _rng; }
result_type operator()() {
// calculating the range every time may seem wasteful. However, this
// makes the information locally available for the optimizer.
typedef typename boost::random::traits::make_unsigned<result_type>::type base_unsigned;
const base_unsigned brange =
detail::subtract<result_type>()((max)(), (min)());
const base_unsigned off =
detail::subtract<result_type>()(y, (min)());
base_unsigned j;
if(k == 1) {
j = 0;
} else if(brange < (std::numeric_limits<base_unsigned>::max)() / k) {
// try to do it in the native type if we know that it won't
// overflow
j = k * off / (brange + 1);
} else if(brange < (std::numeric_limits<uintmax_t>::max)() / k) {
// Otherwise try to use uint64_t
j = static_cast<base_unsigned>(
static_cast<uintmax_t>(off) * k /
(static_cast<uintmax_t>(brange) + 1));
} else {
boost::uintmax_t divisor =
static_cast<boost::uintmax_t>(brange) + 1;
j = static_cast<base_unsigned>(detail::muldiv(off, k, divisor));
}
// assert(0 <= j && j < k);
y = v[j];
v[j] = _rng();
return y;
}
/** Advances the generator by z steps. */
void discard(boost::uintmax_t z)
{
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
/** Fills a range with pseudo-random values. */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (base_type::min)(); }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (base_type::max)(); }
/** Writes a @c shuffle_order_engine to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, shuffle_order_engine, s)
{
os << s._rng;
for(std::size_t i = 0; i < k; ++i)
os << ' ' << s.v[i];
os << ' ' << s.y;
return os;
}
/** Reads a @c shuffle_order_engine from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, shuffle_order_engine, s)
{
is >> s._rng;
for(std::size_t i = 0; i < k; ++i)
is >> std::ws >> s.v[i];
is >> std::ws >> s.y;
return is;
}
/** Returns true if the two generators will produce identical sequences. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(shuffle_order_engine, x, y)
{ return x._rng == y._rng && x.y == y.y && std::equal(x.v, x.v+k, y.v); }
/** Returns true if the two generators will produce different sequences. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(shuffle_order_engine)
private:
/// \cond show_private
void init()
{
// we cannot use std::generate, because it uses pass-by-value for _rng
for(result_type * p = v; p != v+k; ++p)
*p = _rng();
y = _rng();
}
/// \endcond
base_type _rng;
result_type v[k];
result_type y;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class URNG, std::size_t k>
const bool shuffle_order_engine<URNG, k>::has_fixed_range;
template<class URNG, std::size_t k>
const std::size_t shuffle_order_engine<URNG, k>::table_size;
template<class URNG, std::size_t k>
const std::size_t shuffle_order_engine<URNG, k>::buffer_size;
#endif
/**
* According to Harry Erwin (private e-mail), the specialization
* @c kreutzer1986 was suggested in:
*
* @blockquote
* "System Simulation: Programming Styles and Languages (International
* Computer Science Series)", Wolfgang Kreutzer, Addison-Wesley, December 1986.
* @endblockquote
*/
typedef shuffle_order_engine<
linear_congruential_engine<uint32_t, 1366, 150889, 714025>,
97> kreutzer1986;
/**
* The specialization @c knuth_b is specified by the C++ standard.
* It is described in
*
* @blockquote
* "The Art of Computer Programming, Second Edition, Volume 2,
* Seminumerical Algorithms", Donald Knuth, Addison-Wesley, 1981.
* @endblockquote
*/
typedef shuffle_order_engine<minstd_rand0, 256> knuth_b;
} // namespace random
using random::kreutzer1986;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP

View File

@ -1,51 +0,0 @@
/* boost random/shuffle_output.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
#define BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
#include <boost/random/shuffle_order.hpp>
namespace boost {
namespace random {
/// \cond
template<typename URNG, int k,
typename URNG::result_type val = 0>
class shuffle_output : public shuffle_order_engine<URNG, k>
{
typedef shuffle_order_engine<URNG, k> base_t;
public:
typedef typename base_t::result_type result_type;
shuffle_output() {}
template<class T>
explicit shuffle_output(T& arg) : base_t(arg) {}
template<class T>
explicit shuffle_output(const T& arg) : base_t(arg) {}
template<class It>
shuffle_output(It& first, It last) : base_t(first, last) {}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (this->base().min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return (this->base().max)(); }
};
/// \endcond
}
}
#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP

View File

@ -1,180 +0,0 @@
/* boost random/student_t_distribution.hpp header file
*
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_STUDENT_T_DISTRIBUTION_HPP
#define BOOST_RANDOM_STUDENT_T_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/chi_squared_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
namespace boost {
namespace random {
/**
* The Student t distribution is a real valued distribution with one
* parameter n, the number of degrees of freedom.
*
* It has \f$\displaystyle p(x) =
* \frac{1}{\sqrt{n\pi}}
* \frac{\Gamma((n+1)/2)}{\Gamma(n/2)}
* \left(1+\frac{x^2}{n}\right)^{-(n+1)/2}
* \f$.
*/
template<class RealType = double>
class student_t_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef student_t_distribution distribution_type;
/**
* Constructs a @c param_type with "n" degrees of freedom.
*
* Requires: n > 0
*/
explicit param_type(RealType n_arg = RealType(1.0))
: _n(n_arg)
{}
/** Returns the number of degrees of freedom of the distribution. */
RealType n() const { return _n; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._n; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._n; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._n == rhs._n; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _n;
};
/**
* Constructs an @c student_t_distribution with "n" degrees of freedom.
*
* Requires: n > 0
*/
explicit student_t_distribution(RealType n_arg = RealType(1.0))
: _normal(), _chi_squared(n_arg)
{}
/** Constructs an @c student_t_distribution from its parameters. */
explicit student_t_distribution(const param_type& parm)
: _normal(), _chi_squared(parm.n())
{}
/**
* Returns a random variate distributed according to the
* Student t distribution.
*/
template<class URNG>
RealType operator()(URNG& urng)
{
using std::sqrt;
return _normal(urng) / sqrt(_chi_squared(urng) / n());
}
/**
* Returns a random variate distributed accordint to the Student
* t distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return student_t_distribution(parm)(urng);
}
/** Returns the number of degrees of freedom. */
RealType n() const { return _chi_squared.n(); }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return -std::numeric_limits<RealType>::infinity(); }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(n()); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
typedef chi_squared_distribution<RealType> chi_squared_type;
typename chi_squared_type::param_type chi_squared_param(parm.n());
_chi_squared.param(chi_squared_param);
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset()
{
_normal.reset();
_chi_squared.reset();
}
/** Writes a @c student_t_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, student_t_distribution, td)
{
os << td.param();
return os;
}
/** Reads a @c student_t_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, student_t_distribution, td)
{
param_type parm;
if(is >> parm) {
td.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c student_t_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(student_t_distribution, lhs, rhs)
{ return lhs._normal == rhs._normal && lhs._chi_squared == rhs._chi_squared; }
/**
* Returns true if the two instances of @c student_t_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(student_t_distribution)
private:
normal_distribution<RealType> _normal;
chi_squared_distribution<RealType> _chi_squared;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_STUDENT_T_DISTRIBUTION_HPP

View File

@ -1,613 +0,0 @@
/* boost random/subtract_with_carry.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2002-03-02 created
*/
#ifndef BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
#define BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
#include <boost/config/no_tr1/cmath.hpp> // std::pow
#include <iostream>
#include <algorithm> // std::equal
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/integer/integer_mask.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/random/detail/generator_seed_seq.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
namespace detail {
struct subtract_with_carry_discard
{
template<class Engine>
static void apply(Engine& eng, boost::uintmax_t z)
{
typedef typename Engine::result_type IntType;
const std::size_t short_lag = Engine::short_lag;
const std::size_t long_lag = Engine::long_lag;
std::size_t k = eng.k;
IntType carry = eng.carry;
if(k != 0) {
// increment k until it becomes 0.
if(k < short_lag) {
std::size_t limit = (short_lag - k) < z?
short_lag : (k + static_cast<std::size_t>(z));
for(std::size_t j = k; j < limit; ++j) {
carry = eng.do_update(j, j + long_lag - short_lag, carry);
}
}
std::size_t limit = (long_lag - k) < z?
long_lag : (k + static_cast<std::size_t>(z));
std::size_t start = (k < short_lag ? short_lag : k);
for(std::size_t j = start; j < limit; ++j) {
carry = eng.do_update(j, j - short_lag, carry);
}
}
k = ((z % long_lag) + k) % long_lag;
if(k < z) {
// main loop: update full blocks from k = 0 to long_lag
for(std::size_t i = 0; i < (z - k) / long_lag; ++i) {
for(std::size_t j = 0; j < short_lag; ++j) {
carry = eng.do_update(j, j + long_lag - short_lag, carry);
}
for(std::size_t j = short_lag; j < long_lag; ++j) {
carry = eng.do_update(j, j - short_lag, carry);
}
}
// Update the last partial block
std::size_t limit = short_lag < k? short_lag : k;
for(std::size_t j = 0; j < limit; ++j) {
carry = eng.do_update(j, j + long_lag - short_lag, carry);
}
for(std::size_t j = short_lag; j < k; ++j) {
carry = eng.do_update(j, j - short_lag, carry);
}
}
eng.carry = carry;
eng.k = k;
}
};
}
/**
* Instantiations of @c subtract_with_carry_engine model a
* \pseudo_random_number_generator. The algorithm is
* described in
*
* @blockquote
* "A New Class of Random Number Generators", George
* Marsaglia and Arif Zaman, Annals of Applied Probability,
* Volume 1, Number 3 (1991), 462-480.
* @endblockquote
*/
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
class subtract_with_carry_engine
{
public:
typedef IntType result_type;
BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
BOOST_STATIC_CONSTANT(std::size_t, long_lag = r);
BOOST_STATIC_CONSTANT(std::size_t, short_lag = s);
BOOST_STATIC_CONSTANT(uint32_t, default_seed = 19780503u);
// Required by the old Boost.Random concepts
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
// Backwards compatibility
BOOST_STATIC_CONSTANT(result_type, modulus = (result_type(1) << w));
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
/**
* Constructs a new @c subtract_with_carry_engine and seeds
* it with the default seed.
*/
subtract_with_carry_engine() { seed(); }
/**
* Constructs a new @c subtract_with_carry_engine and seeds
* it with @c value.
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_engine,
IntType, value)
{ seed(value); }
/**
* Constructs a new @c subtract_with_carry_engine and seeds
* it with values produced by @c seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(subtract_with_carry_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Constructs a new @c subtract_with_carry_engine and seeds
* it with values from a range. first is updated to point
* one past the last value consumed. If there are not
* enough elements in the range to fill the entire state of
* the generator, throws @c std::invalid_argument.
*/
template<class It> subtract_with_carry_engine(It& first, It last)
{ seed(first,last); }
// compiler-generated copy ctor and assignment operator are fine
/** Seeds the generator with the default seed. */
void seed() { seed(default_seed); }
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_engine,
IntType, value)
{
typedef linear_congruential_engine<uint32_t,40014,0,2147483563> gen_t;
gen_t intgen(static_cast<boost::uint32_t>(value == 0 ? default_seed : value));
detail::generator_seed_seq<gen_t> gen(intgen);
seed(gen);
}
/** Seeds the generator with values produced by @c seq.generate(). */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(subtract_with_carry, SeedSeq, seq)
{
detail::seed_array_int<w>(seq, x);
carry = (x[long_lag-1] == 0);
k = 0;
}
/**
* Seeds the generator with values from a range. Updates @c first to
* point one past the last consumed value. If the range does not
* contain enough elements to fill the entire state of the generator,
* throws @c std::invalid_argument.
*/
template<class It>
void seed(It& first, It last)
{
detail::fill_array_int<w>(first, last, x);
carry = (x[long_lag-1] == 0);
k = 0;
}
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return 0; }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return boost::low_bits_mask_t<w>::sig_bits; }
/** Returns the next value of the generator. */
result_type operator()()
{
std::size_t short_index =
(k < short_lag)?
(k + long_lag - short_lag) :
(k - short_lag);
carry = do_update(k, short_index, carry);
IntType result = x[k];
++k;
if(k >= long_lag)
k = 0;
return result;
}
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
detail::subtract_with_carry_discard::apply(*this, z);
}
/** Fills a range with random values. */
template<class It>
void generate(It first, It last)
{ detail::generate_from_int(*this, first, last); }
/** Writes a @c subtract_with_carry_engine to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, subtract_with_carry_engine, f)
{
for(unsigned int j = 0; j < f.long_lag; ++j)
os << f.compute(j) << ' ';
os << f.carry;
return os;
}
/** Reads a @c subtract_with_carry_engine from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, subtract_with_carry_engine, f)
{
for(unsigned int j = 0; j < f.long_lag; ++j)
is >> f.x[j] >> std::ws;
is >> f.carry;
f.k = 0;
return is;
}
/**
* Returns true if the two generators will produce identical
* sequences of values.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(subtract_with_carry_engine, x, y)
{
for(unsigned int j = 0; j < r; ++j)
if(x.compute(j) != y.compute(j))
return false;
return true;
}
/**
* Returns true if the two generators will produce different
* sequences of values.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(subtract_with_carry_engine)
private:
/// \cond show_private
// returns x(i-r+index), where index is in 0..r-1
IntType compute(unsigned int index) const
{
return x[(k+index) % long_lag];
}
friend struct detail::subtract_with_carry_discard;
IntType do_update(std::size_t current, std::size_t short_index, IntType carry)
{
IntType delta;
IntType temp = x[current] + carry;
if (x[short_index] >= temp) {
// x(n) >= 0
delta = x[short_index] - temp;
carry = 0;
} else {
// x(n) < 0
delta = modulus - temp + x[short_index];
carry = 1;
}
x[current] = delta;
return carry;
}
/// \endcond
// state representation; next output (state) is x(i)
// x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
// x(i-k) ... x(i) x(i+1) ... x(i-k+long_lag-1)
// speed: base: 20-25 nsec
// ranlux_4: 230 nsec, ranlux_7: 430 nsec, ranlux_14: 810 nsec
// This state representation makes operator== and save/restore more
// difficult, because we've already computed "too much" and thus
// have to undo some steps to get at x(i-r) etc.
// state representation: next output (state) is x(i)
// x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
// x(i-k) ... x(i) x(i-long_lag+1) ... x(i-k-1)
// speed: base 28 nsec
// ranlux_4: 370 nsec, ranlux_7: 688 nsec, ranlux_14: 1343 nsec
IntType x[long_lag];
std::size_t k;
IntType carry;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const bool subtract_with_carry_engine<IntType, w, s, r>::has_fixed_range;
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const IntType subtract_with_carry_engine<IntType, w, s, r>::modulus;
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_engine<IntType, w, s, r>::word_size;
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_engine<IntType, w, s, r>::long_lag;
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_engine<IntType, w, s, r>::short_lag;
template<class IntType, std::size_t w, std::size_t s, std::size_t r>
const uint32_t subtract_with_carry_engine<IntType, w, s, r>::default_seed;
#endif
// use a floating-point representation to produce values in [0..1)
/**
* Instantiations of \subtract_with_carry_01_engine model a
* \pseudo_random_number_generator. The algorithm is
* described in
*
* @blockquote
* "A New Class of Random Number Generators", George
* Marsaglia and Arif Zaman, Annals of Applied Probability,
* Volume 1, Number 3 (1991), 462-480.
* @endblockquote
*/
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
class subtract_with_carry_01_engine
{
public:
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(std::size_t, word_size = w);
BOOST_STATIC_CONSTANT(std::size_t, long_lag = r);
BOOST_STATIC_CONSTANT(std::size_t, short_lag = s);
BOOST_STATIC_CONSTANT(boost::uint32_t, default_seed = 19780503u);
BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_integer);
/** Creates a new \subtract_with_carry_01_engine using the default seed. */
subtract_with_carry_01_engine() { init_modulus(); seed(); }
/** Creates a new subtract_with_carry_01_engine and seeds it with value. */
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_01_engine,
boost::uint32_t, value)
{ init_modulus(); seed(value); }
/**
* Creates a new \subtract_with_carry_01_engine and seeds with values
* produced by seq.generate().
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(subtract_with_carry_01_engine,
SeedSeq, seq)
{ init_modulus(); seed(seq); }
/**
* Creates a new \subtract_with_carry_01_engine and seeds it with values
* from a range. Advances first to point one past the last consumed
* value. If the range does not contain enough elements to fill the
* entire state, throws @c std::invalid_argument.
*/
template<class It> subtract_with_carry_01_engine(It& first, It last)
{ init_modulus(); seed(first,last); }
private:
/// \cond show_private
void init_modulus()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::pow;
#endif
_modulus = pow(RealType(2), RealType(word_size));
}
/// \endcond
public:
// compiler-generated copy ctor and assignment operator are fine
/** Seeds the generator with the default seed. */
void seed() { seed(default_seed); }
/** Seeds the generator with @c value. */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_01_engine,
boost::uint32_t, value)
{
typedef linear_congruential_engine<uint32_t, 40014, 0, 2147483563> gen_t;
gen_t intgen(value == 0 ? default_seed : value);
detail::generator_seed_seq<gen_t> gen(intgen);
seed(gen);
}
/** Seeds the generator with values produced by @c seq.generate(). */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(subtract_with_carry_01_engine,
SeedSeq, seq)
{
detail::seed_array_real<w>(seq, x);
carry = (x[long_lag-1] ? result_type(0) : result_type(1 / _modulus));
k = 0;
}
/**
* Seeds the generator with values from a range. Updates first to
* point one past the last consumed element. If there are not
* enough elements in the range to fill the entire state, throws
* @c std::invalid_argument.
*/
template<class It>
void seed(It& first, It last)
{
detail::fill_array_real<w>(first, last, x);
carry = (x[long_lag-1] ? result_type(0) : result_type(1 / _modulus));
k = 0;
}
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return result_type(0); }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
{ return result_type(1); }
/** Returns the next value of the generator. */
result_type operator()()
{
std::size_t short_index =
(k < short_lag) ?
(k + long_lag - short_lag) :
(k - short_lag);
carry = do_update(k, short_index, carry);
RealType result = x[k];
++k;
if(k >= long_lag)
k = 0;
return result;
}
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{ detail::subtract_with_carry_discard::apply(*this, z); }
/** Fills a range with random values. */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_real(*this, first, last); }
/** Writes a \subtract_with_carry_01_engine to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, subtract_with_carry_01_engine, f)
{
std::ios_base::fmtflags oldflags =
os.flags(os.dec | os.fixed | os.left);
for(unsigned int j = 0; j < f.long_lag; ++j)
os << (f.compute(j) * f._modulus) << ' ';
os << (f.carry * f._modulus);
os.flags(oldflags);
return os;
}
/** Reads a \subtract_with_carry_01_engine from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, subtract_with_carry_01_engine, f)
{
RealType value;
for(unsigned int j = 0; j < long_lag; ++j) {
is >> value >> std::ws;
f.x[j] = value / f._modulus;
}
is >> value;
f.carry = value / f._modulus;
f.k = 0;
return is;
}
/** Returns true if the two generators will produce identical sequences. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(subtract_with_carry_01_engine, x, y)
{
for(unsigned int j = 0; j < r; ++j)
if(x.compute(j) != y.compute(j))
return false;
return true;
}
/** Returns true if the two generators will produce different sequences. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(subtract_with_carry_01_engine)
private:
/// \cond show_private
RealType compute(unsigned int index) const
{
return x[(k+index) % long_lag];
}
friend struct detail::subtract_with_carry_discard;
RealType do_update(std::size_t current, std::size_t short_index, RealType carry)
{
RealType delta = x[short_index] - x[current] - carry;
if(delta < 0) {
delta += RealType(1);
carry = RealType(1)/_modulus;
} else {
carry = 0;
}
x[current] = delta;
return carry;
}
/// \endcond
std::size_t k;
RealType carry;
RealType x[long_lag];
RealType _modulus;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
const bool subtract_with_carry_01_engine<RealType, w, s, r>::has_fixed_range;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::word_size;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::long_lag;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
const std::size_t subtract_with_carry_01_engine<RealType, w, s, r>::short_lag;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
const uint32_t subtract_with_carry_01_engine<RealType, w, s, r>::default_seed;
#endif
/// \cond show_deprecated
template<class IntType, IntType m, unsigned s, unsigned r, IntType v>
class subtract_with_carry :
public subtract_with_carry_engine<IntType,
boost::static_log2<m>::value, s, r>
{
typedef subtract_with_carry_engine<IntType,
boost::static_log2<m>::value, s, r> base_type;
public:
subtract_with_carry() {}
BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry, Gen, gen)
{ seed(gen); }
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry,
IntType, val)
{ seed(val); }
template<class It>
subtract_with_carry(It& first, It last) : base_type(first, last) {}
void seed() { base_type::seed(); }
BOOST_RANDOM_DETAIL_GENERATOR_SEED(subtract_with_carry, Gen, gen)
{
detail::generator_seed_seq<Gen> seq(gen);
base_type::seed(seq);
}
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry, IntType, val)
{ base_type::seed(val); }
template<class It>
void seed(It& first, It last) { base_type::seed(first, last); }
};
template<class RealType, int w, unsigned s, unsigned r, int v = 0>
class subtract_with_carry_01 :
public subtract_with_carry_01_engine<RealType, w, s, r>
{
typedef subtract_with_carry_01_engine<RealType, w, s, r> base_type;
public:
subtract_with_carry_01() {}
BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(subtract_with_carry_01, Gen, gen)
{ seed(gen); }
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(subtract_with_carry_01,
uint32_t, val)
{ seed(val); }
template<class It>
subtract_with_carry_01(It& first, It last) : base_type(first, last) {}
void seed() { base_type::seed(); }
BOOST_RANDOM_DETAIL_GENERATOR_SEED(subtract_with_carry_01, Gen, gen)
{
detail::generator_seed_seq<Gen> seq(gen);
base_type::seed(seq);
}
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(subtract_with_carry_01, uint32_t, val)
{ base_type::seed(val); }
template<class It>
void seed(It& first, It last) { base_type::seed(first, last); }
};
/// \endcond
namespace detail {
template<class Engine>
struct generator_bits;
template<class RealType, std::size_t w, std::size_t s, std::size_t r>
struct generator_bits<subtract_with_carry_01_engine<RealType, w, s, r> > {
static std::size_t value() { return w; }
};
template<class RealType, int w, unsigned s, unsigned r, int v>
struct generator_bits<subtract_with_carry_01<RealType, w, s, r, v> > {
static std::size_t value() { return w; }
};
}
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP

View File

@ -1,45 +0,0 @@
/* boost random/taus88.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/random for documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_TAUS88_HPP
#define BOOST_RANDOM_TAUS88_HPP
#include <boost/random/linear_feedback_shift.hpp>
#include <boost/random/xor_combine.hpp>
namespace boost {
namespace random {
/**
* The specialization taus88 was suggested in
*
* @blockquote
* "Maximally Equidistributed Combined Tausworthe Generators",
* Pierre L'Ecuyer, Mathematics of Computation, Volume 65,
* Number 213, January 1996, Pages 203-213
* @endblockquote
*/
typedef xor_combine_engine<
xor_combine_engine<
linear_feedback_shift_engine<uint32_t, 32, 31, 13, 12>, 0,
linear_feedback_shift_engine<uint32_t, 32, 29, 2, 4>, 0>, 0,
linear_feedback_shift_engine<uint32_t, 32, 28, 3, 17>, 0> taus88;
} // namespace random
using random::taus88;
} // namespace boost
#endif // BOOST_RANDOM_TAUS88_HPP

View File

@ -1,107 +0,0 @@
/* boost random/traits.hpp header file
*
* Copyright John Maddock 2015
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* These traits classes serve two purposes: they are designed to mostly
* work out of the box for multiprecision types (ie number types that are
* C++ class types and not integers or floats from type-traits point of view),
* they are also a potential point of specialization for user-defined
* number types.
*
* $Id$
*/
#ifndef BOOST_RANDOM_TRAITS_HPP
#define BOOST_RANDOM_TRAITS_HPP
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/mpl/bool.hpp>
#include <limits>
namespace boost {
namespace random {
namespace traits {
// \cond show_private
template <class T, bool intrinsic>
struct make_unsigned_imp
{
typedef typename boost::make_unsigned<T>::type type;
};
template <class T>
struct make_unsigned_imp<T, false>
{
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_signed == false);
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_integer == true);
typedef T type;
};
// \endcond
/** \brief Converts the argument type T to an unsigned type.
*
* This trait has a single member `type` which is the unsigned type corresponding to T.
* Note that
* if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in
* types this trait defaults to `boost::make_unsigned<T>::type`. For user defined types it simply asserts that
* the argument type T is an unsigned integer (using std::numeric_limits).
* User defined specializations may be provided for other cases.
*/
template <class T>
struct make_unsigned
// \cond show_private
: public make_unsigned_imp < T, boost::is_integral<T>::value >
// \endcond
{};
// \cond show_private
template <class T, bool intrinsic>
struct make_unsigned_or_unbounded_imp
{
typedef typename boost::make_unsigned<T>::type type;
};
template <class T>
struct make_unsigned_or_unbounded_imp<T, false>
{
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
BOOST_STATIC_ASSERT((std::numeric_limits<T>::is_signed == false) || (std::numeric_limits<T>::is_bounded == false));
BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_integer == true);
typedef T type;
};
// \endcond
/** \brief Converts the argument type T to either an unsigned type or an unbounded integer type.
*
* This trait has a single member `type` which is either the unsigned type corresponding to T or an unbounded
* integer type. This trait is used to generate types suitable for the calculation of a range: as a result
* if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in
* types this trait defaults to `boost::make_unsigned<T>::type`. For user defined types it simply asserts that
* the argument type T is either an unbounded integer, or an unsigned one (using std::numeric_limits).
* User defined specializations may be provided for other cases.
*/
template <class T>
struct make_unsigned_or_unbounded
// \cond show_private
: public make_unsigned_or_unbounded_imp < T, boost::is_integral<T>::value >
// \endcond
{};
/** \brief Traits class that indicates whether type T is an integer
*/
template <class T>
struct is_integral
: public mpl::bool_<boost::is_integral<T>::value || (std::numeric_limits<T>::is_integer)>
{};
/** \brief Traits class that indicates whether type T is a signed integer
*/
template <class T> struct is_signed
: public mpl::bool_ < boost::is_signed<T>::value || (std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed)>
{};
}
}
}
#endif

View File

@ -1,232 +0,0 @@
/* boost random/triangle_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
#define BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <ios>
#include <istream>
#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
/**
* Instantiations of @c triangle_distribution model a \random_distribution.
* A @c triangle_distribution has three parameters, @c a, @c b, and @c c,
* which are the smallest, the most probable and the largest values of
* the distribution respectively.
*/
template<class RealType = double>
class triangle_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type
{
public:
typedef triangle_distribution distribution_type;
/** Constructs the parameters of a @c triangle_distribution. */
explicit param_type(RealType a_arg = RealType(0.0),
RealType b_arg = RealType(0.5),
RealType c_arg = RealType(1.0))
: _a(a_arg), _b(b_arg), _c(c_arg)
{
BOOST_ASSERT(_a <= _b && _b <= _c);
}
/** Returns the minimum value of the distribution. */
RealType a() const { return _a; }
/** Returns the mode of the distribution. */
RealType b() const { return _b; }
/** Returns the maximum value of the distribution. */
RealType c() const { return _c; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._a << " " << parm._b << " " << parm._c;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
double a_in, b_in, c_in;
if(is >> a_in >> std::ws >> b_in >> std::ws >> c_in) {
if(a_in <= b_in && b_in <= c_in) {
parm._a = a_in;
parm._b = b_in;
parm._c = c_in;
} else {
is.setstate(std::ios_base::failbit);
}
}
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _a;
RealType _b;
RealType _c;
};
/**
* Constructs a @c triangle_distribution with the parameters
* @c a, @c b, and @c c.
*
* Preconditions: a <= b <= c.
*/
explicit triangle_distribution(RealType a_arg = RealType(0.0),
RealType b_arg = RealType(0.5),
RealType c_arg = RealType(1.0))
: _a(a_arg), _b(b_arg), _c(c_arg)
{
BOOST_ASSERT(_a <= _b && _b <= _c);
init();
}
/** Constructs a @c triangle_distribution from its parameters. */
explicit triangle_distribution(const param_type& parm)
: _a(parm.a()), _b(parm.b()), _c(parm.c())
{
init();
}
// compiler-generated copy ctor and assignment operator are fine
/** Returns the @c a parameter of the distribution */
result_type a() const { return _a; }
/** Returns the @c b parameter of the distribution */
result_type b() const { return _b; }
/** Returns the @c c parameter of the distribution */
result_type c() const { return _c; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _a; }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _c; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_a, _b, _c); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_a = parm.a();
_b = parm.b();
_c = parm.c();
init();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/**
* Returns a random variate distributed according to the
* triangle distribution.
*/
template<class Engine>
result_type operator()(Engine& eng)
{
using std::sqrt;
result_type u = uniform_01<result_type>()(eng);
if( u <= q1 )
return _a + p1*sqrt(u);
else
return _c - d3*sqrt(d2*u-d1);
}
/**
* Returns a random variate distributed according to the
* triangle distribution with parameters specified by param.
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm)
{ return triangle_distribution(parm)(eng); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, triangle_distribution, td)
{
os << td.param();
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, triangle_distribution, td)
{
param_type parm;
if(is >> parm) {
td.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(triangle_distribution, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b && lhs._c == rhs._c; }
/**
* Returns true if the two distributions may produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(triangle_distribution)
private:
/// \cond show_private
void init()
{
using std::sqrt;
d1 = _b - _a;
d2 = _c - _a;
d3 = sqrt(_c - _b);
q1 = d1 / d2;
p1 = sqrt(d1 * d2);
}
/// \endcond
RealType _a, _b, _c;
RealType d1, d2, d3, q1, p1;
};
} // namespace random
using random::triangle_distribution;
} // namespace boost
#endif // BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP

View File

@ -1,257 +0,0 @@
/* boost random/uniform_01.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_01_HPP
#define BOOST_RANDOM_UNIFORM_01_HPP
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/ptr_helper.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
namespace random {
#ifdef BOOST_RANDOM_DOXYGEN
/**
* The distribution function uniform_01 models a \random_distribution.
* On each invocation, it returns a random floating-point value
* uniformly distributed in the range [0..1).
*
* The template parameter RealType shall denote a float-like value type
* with support for binary operators +, -, and /.
*
* Note: The current implementation is buggy, because it may not fill
* all of the mantissa with random bits. I'm unsure how to fill a
* (to-be-invented) @c boost::bigfloat class with random bits efficiently.
* It's probably time for a traits class.
*/
template<class RealType = double>
class uniform_01
{
public:
typedef RealType input_type;
typedef RealType result_type;
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const;
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const;
void reset();
template<class Engine>
result_type operator()(Engine& eng);
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
{
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
{
return is;
}
#endif
};
#else
namespace detail {
template<class RealType>
class new_uniform_01
{
public:
typedef RealType input_type;
typedef RealType result_type;
// compiler-generated copy ctor and copy assignment are fine
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng) {
for (;;) {
typedef typename Engine::result_type base_result;
result_type factor = result_type(1) /
(result_type(base_result((eng.max)()-(eng.min)())) +
result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0));
result_type result = result_type(base_result(eng() - (eng.min)())) * factor;
if (result < result_type(1))
return result;
}
}
#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const new_uniform_01&)
{
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, new_uniform_01&)
{
return is;
}
#endif
};
template<class UniformRandomNumberGenerator, class RealType>
class backward_compatible_uniform_01
{
typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
public:
typedef UniformRandomNumberGenerator base_type;
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit backward_compatible_uniform_01(typename traits::rvalue_type rng)
: _rng(rng),
_factor(result_type(1) /
(result_type((base().max)()-(base().min)()) +
result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
{
}
// compiler-generated copy ctor and copy assignment are fine
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
typename traits::value_type& base() { return traits::ref(_rng); }
const typename traits::value_type& base() const { return traits::ref(_rng); }
void reset() { }
result_type operator()() {
for (;;) {
result_type result = result_type(base()() - (base().min)()) * _factor;
if (result < result_type(1))
return result;
}
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const backward_compatible_uniform_01& u)
{
os << u._rng;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, backward_compatible_uniform_01& u)
{
is >> u._rng;
return is;
}
#endif
private:
typedef typename traits::value_type::result_type base_result;
UniformRandomNumberGenerator _rng;
result_type _factor;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UniformRandomNumberGenerator, class RealType>
const bool backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
#endif
template<class UniformRandomNumberGenerator, bool is_number = std::numeric_limits<UniformRandomNumberGenerator>::is_specialized>
struct select_uniform_01
{
template<class RealType>
struct apply
{
typedef backward_compatible_uniform_01<UniformRandomNumberGenerator, RealType> type;
};
};
template<class Num>
struct select_uniform_01<Num, true>
{
template<class RealType>
struct apply
{
typedef new_uniform_01<Num> type;
};
};
}
// Because it is so commonly used: uniform distribution on the real [0..1)
// range. This allows for specializations to avoid a costly int -> float
// conversion plus float multiplication
template<class UniformRandomNumberGenerator = double, class RealType = double>
class uniform_01
: public detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type
{
typedef typename detail::select_uniform_01<UniformRandomNumberGenerator>::BOOST_NESTED_TEMPLATE apply<RealType>::type impl_type;
typedef boost::random::detail::ptr_helper<UniformRandomNumberGenerator> traits;
public:
uniform_01() {}
explicit uniform_01(typename traits::rvalue_type rng)
: impl_type(rng)
{
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
{
os << static_cast<const impl_type&>(u);
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
{
is >> static_cast<impl_type&>(u);
return is;
}
#endif
};
#endif
} // namespace random
using random::uniform_01;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_UNIFORM_01_HPP

View File

@ -1,99 +0,0 @@
/* boost random/uniform_int.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_INT_HPP
#define BOOST_RANDOM_UNIFORM_INT_HPP
#include <boost/assert.hpp>
#include <boost/random/uniform_int_distribution.hpp>
namespace boost {
/**
* The distribution function uniform_int models a \random_distribution.
* On each invocation, it returns a random integer value uniformly
* distributed in the set of integer numbers {min, min+1, min+2, ..., max}.
*
* The template parameter IntType shall denote an integer-like value type.
*
* This class is deprecated. Please use @c uniform_int_distribution in
* new code.
*/
template<class IntType = int>
class uniform_int : public random::uniform_int_distribution<IntType>
{
typedef random::uniform_int_distribution<IntType> base_type;
public:
class param_type : public base_type::param_type
{
public:
typedef uniform_int distribution_type;
/**
* Constructs the parameters of a uniform_int distribution.
*
* Requires: min <= max
*/
explicit param_type(IntType min_arg = 0, IntType max_arg = 9)
: base_type::param_type(min_arg, max_arg)
{}
};
/**
* Constructs a uniform_int object. @c min and @c max are
* the parameters of the distribution.
*
* Requires: min <= max
*/
explicit uniform_int(IntType min_arg = 0, IntType max_arg = 9)
: base_type(min_arg, max_arg)
{}
/** Constructs a uniform_int distribution from its parameters. */
explicit uniform_int(const param_type& parm)
: base_type(parm)
{}
/** Returns the parameters of the distribution */
param_type param() const { return param_type(this->a(), this->b()); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm) { this->base_type::param(parm); }
// Codergear seems to have trouble with a using declaration here
template<class Engine>
IntType operator()(Engine& eng) const
{
return static_cast<const base_type&>(*this)(eng);
}
template<class Engine>
IntType operator()(Engine& eng, const param_type& parm) const
{
return static_cast<const base_type&>(*this)(eng, parm);
}
template<class Engine>
IntType operator()(Engine& eng, IntType n) const
{
BOOST_ASSERT(n > 0);
return static_cast<const base_type&>(*this)(eng, param_type(0, n - 1));
}
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_INT_HPP

View File

@ -1,419 +0,0 @@
/* boost random/uniform_int_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
#define BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
#include <iosfwd>
#include <ios>
#include <istream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/uniform_int_float.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/traits.hpp>
#include <boost/mpl/bool.hpp>
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
#include <boost/mpl/if.hpp>
#endif
namespace boost {
namespace random {
namespace detail {
#ifdef BOOST_MSVC
#pragma warning(push)
// disable division by zero warning, since we can't
// actually divide by zero.
#pragma warning(disable:4723)
#endif
template<class Engine, class T>
T generate_uniform_int(
Engine& eng, T min_value, T max_value,
boost::mpl::true_ /** is_integral<Engine::result_type> */)
{
typedef T result_type;
typedef typename boost::random::traits::make_unsigned_or_unbounded<T>::type range_type;
typedef typename Engine::result_type base_result;
// ranges are always unsigned or unbounded
typedef typename boost::random::traits::make_unsigned_or_unbounded<base_result>::type base_unsigned;
const range_type range = random::detail::subtract<result_type>()(max_value, min_value);
const base_result bmin = (eng.min)();
const base_unsigned brange =
random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
if(range == 0) {
return min_value;
} else if(brange == range) {
// this will probably never happen in real life
// basically nothing to do; just take care we don't overflow / underflow
base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
return random::detail::add<base_unsigned, result_type>()(v, min_value);
} else if(brange < range) {
// use rejection method to handle things like 0..3 --> 0..4
for(;;) {
// concatenate several invocations of the base RNG
// take extra care to avoid overflows
// limit == floor((range+1)/(brange+1))
// Therefore limit*(brange+1) <= range+1
range_type limit;
if(range == (std::numeric_limits<range_type>::max)()) {
limit = range/(range_type(brange)+1);
if(range % (range_type(brange)+1) == range_type(brange))
++limit;
} else {
limit = (range+1)/(range_type(brange)+1);
}
// We consider "result" as expressed to base (brange+1):
// For every power of (brange+1), we determine a random factor
range_type result = range_type(0);
range_type mult = range_type(1);
// loop invariants:
// result < mult
// mult <= range
while(mult <= limit) {
// Postcondition: result <= range, thus no overflow
//
// limit*(brange+1)<=range+1 def. of limit (1)
// eng()-bmin<=brange eng() post. (2)
// and mult<=limit. loop condition (3)
// Therefore mult*(eng()-bmin+1)<=range+1 by (1),(2),(3) (4)
// Therefore mult*(eng()-bmin)+mult<=range+1 rearranging (4) (5)
// result<mult loop invariant (6)
// Therefore result+mult*(eng()-bmin)<range+1 by (5), (6) (7)
//
// Postcondition: result < mult*(brange+1)
//
// result<mult loop invariant (1)
// eng()-bmin<=brange eng() post. (2)
// Therefore result+mult*(eng()-bmin) <
// mult+mult*(eng()-bmin) by (1) (3)
// Therefore result+(eng()-bmin)*mult <
// mult+mult*brange by (2), (3) (4)
// Therefore result+(eng()-bmin)*mult <
// mult*(brange+1) by (4)
result += static_cast<range_type>(static_cast<range_type>(random::detail::subtract<base_result>()(eng(), bmin)) * mult);
// equivalent to (mult * (brange+1)) == range+1, but avoids overflow.
if(mult * range_type(brange) == range - mult + 1) {
// The destination range is an integer power of
// the generator's range.
return(result);
}
// Postcondition: mult <= range
//
// limit*(brange+1)<=range+1 def. of limit (1)
// mult<=limit loop condition (2)
// Therefore mult*(brange+1)<=range+1 by (1), (2) (3)
// mult*(brange+1)!=range+1 preceding if (4)
// Therefore mult*(brange+1)<range+1 by (3), (4) (5)
//
// Postcondition: result < mult
//
// See the second postcondition on the change to result.
mult *= range_type(brange)+range_type(1);
}
// loop postcondition: range/mult < brange+1
//
// mult > limit loop condition (1)
// Suppose range/mult >= brange+1 Assumption (2)
// range >= mult*(brange+1) by (2) (3)
// range+1 > mult*(brange+1) by (3) (4)
// range+1 > (limit+1)*(brange+1) by (1), (4) (5)
// (range+1)/(brange+1) > limit+1 by (5) (6)
// limit < floor((range+1)/(brange+1)) by (6) (7)
// limit==floor((range+1)/(brange+1)) def. of limit (8)
// not (2) reductio (9)
//
// loop postcondition: (range/mult)*mult+(mult-1) >= range
//
// (range/mult)*mult + range%mult == range identity (1)
// range%mult < mult def. of % (2)
// (range/mult)*mult+mult > range by (1), (2) (3)
// (range/mult)*mult+(mult-1) >= range by (3) (4)
//
// Note that the maximum value of result at this point is (mult-1),
// so after this final step, we generate numbers that can be
// at least as large as range. We have to really careful to avoid
// overflow in this final addition and in the rejection. Anything
// that overflows is larger than range and can thus be rejected.
// range/mult < brange+1 -> no endless loop
range_type result_increment =
generate_uniform_int(
eng,
static_cast<range_type>(0),
static_cast<range_type>(range/mult),
boost::mpl::true_());
if(std::numeric_limits<range_type>::is_bounded && ((std::numeric_limits<range_type>::max)() / mult < result_increment)) {
// The multiplcation would overflow. Reject immediately.
continue;
}
result_increment *= mult;
// unsigned integers are guaranteed to wrap on overflow.
result += result_increment;
if(result < result_increment) {
// The addition overflowed. Reject.
continue;
}
if(result > range) {
// Too big. Reject.
continue;
}
return random::detail::add<range_type, result_type>()(result, min_value);
}
} else { // brange > range
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
typedef typename mpl::if_c<
std::numeric_limits<range_type>::is_specialized && std::numeric_limits<base_unsigned>::is_specialized
&& (std::numeric_limits<range_type>::digits >= std::numeric_limits<base_unsigned>::digits),
range_type, base_unsigned>::type mixed_range_type;
#else
typedef base_unsigned mixed_range_type;
#endif
mixed_range_type bucket_size;
// it's safe to add 1 to range, as long as we cast it first,
// because we know that it is less than brange. However,
// we do need to be careful not to cause overflow by adding 1
// to brange. We use mixed_range_type throughout for mixed
// arithmetic between base_unsigned and range_type - in the case
// that range_type has more bits than base_unsigned it is always
// safe to use range_type for this albeit it may be more effient
// to use base_unsigned. The latter is a narrowing conversion though
// which may be disallowed if range_type is a multiprecision type
// and there are no explicit converison operators.
if(brange == (std::numeric_limits<base_unsigned>::max)()) {
bucket_size = static_cast<mixed_range_type>(brange) / (static_cast<mixed_range_type>(range)+1);
if(static_cast<mixed_range_type>(brange) % (static_cast<mixed_range_type>(range)+1) == static_cast<mixed_range_type>(range)) {
++bucket_size;
}
} else {
bucket_size = static_cast<mixed_range_type>(brange + 1) / (static_cast<mixed_range_type>(range)+1);
}
for(;;) {
mixed_range_type result =
random::detail::subtract<base_result>()(eng(), bmin);
result /= bucket_size;
// result and range are non-negative, and result is possibly larger
// than range, so the cast is safe
if(result <= static_cast<mixed_range_type>(range))
return random::detail::add<mixed_range_type, result_type>()(result, min_value);
}
}
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
template<class Engine, class T>
inline T generate_uniform_int(
Engine& eng, T min_value, T max_value,
boost::mpl::false_ /** is_integral<Engine::result_type> */)
{
uniform_int_float<Engine> wrapper(eng);
return generate_uniform_int(wrapper, min_value, max_value, boost::mpl::true_());
}
template<class Engine, class T>
inline T generate_uniform_int(Engine& eng, T min_value, T max_value)
{
typedef typename Engine::result_type base_result;
return generate_uniform_int(eng, min_value, max_value,
boost::random::traits::is_integral<base_result>());
}
}
/**
* The class template uniform_int_distribution models a \random_distribution.
* On each invocation, it returns a random integer value uniformly
* distributed in the set of integers {min, min+1, min+2, ..., max}.
*
* The template parameter IntType shall denote an integer-like value type.
*/
template<class IntType = int>
class uniform_int_distribution
{
public:
typedef IntType input_type;
typedef IntType result_type;
class param_type
{
public:
typedef uniform_int_distribution distribution_type;
/**
* Constructs the parameters of a uniform_int_distribution.
*
* Requires min <= max
*/
explicit param_type(
IntType min_arg = 0,
IntType max_arg = (std::numeric_limits<IntType>::max)())
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(_min <= _max);
}
/** Returns the minimum value of the distribution. */
IntType a() const { return _min; }
/** Returns the maximum value of the distribution. */
IntType b() const { return _max; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._min << " " << parm._max;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
IntType min_in, max_in;
if(is >> min_in >> std::ws >> max_in) {
if(min_in <= max_in) {
parm._min = min_in;
parm._max = max_in;
} else {
is.setstate(std::ios_base::failbit);
}
}
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
IntType _min;
IntType _max;
};
/**
* Constructs a uniform_int_distribution. @c min and @c max are
* the parameters of the distribution.
*
* Requires: min <= max
*/
explicit uniform_int_distribution(
IntType min_arg = 0,
IntType max_arg = (std::numeric_limits<IntType>::max)())
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(min_arg <= max_arg);
}
/** Constructs a uniform_int_distribution from its parameters. */
explicit uniform_int_distribution(const param_type& parm)
: _min(parm.a()), _max(parm.b()) {}
/** Returns the minimum value of the distribution */
IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
/** Returns the maximum value of the distribution */
IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
/** Returns the minimum value of the distribution */
IntType a() const { return _min; }
/** Returns the maximum value of the distribution */
IntType b() const { return _max; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_min, _max); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_min = parm.a();
_max = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Returns an integer uniformly distributed in the range [min, max]. */
template<class Engine>
result_type operator()(Engine& eng) const
{ return detail::generate_uniform_int(eng, _min, _max); }
/**
* Returns an integer uniformly distributed in the range
* [param.a(), param.b()].
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{ return detail::generate_uniform_int(eng, parm.a(), parm.b()); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_int_distribution, ud)
{
os << ud.param();
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_int_distribution, ud)
{
param_type parm;
if(is >> parm) {
ud.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will produce identical sequences
* of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_int_distribution, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/**
* Returns true if the two distributions may produce different sequences
* of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_int_distribution)
private:
IntType _min;
IntType _max;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_INT_HPP

View File

@ -1,284 +0,0 @@
/* boost random/uniform_on_sphere.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
#define BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
#include <vector>
#include <algorithm> // std::transform
#include <functional> // std::bind2nd, std::divides
#include <boost/assert.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/normal_distribution.hpp>
namespace boost {
namespace random {
/**
* Instantiations of class template uniform_on_sphere model a
* \random_distribution. Such a distribution produces random
* numbers uniformly distributed on the unit sphere of arbitrary
* dimension @c dim. The @c Cont template parameter must be a STL-like
* container type with begin and end operations returning non-const
* ForwardIterators of type @c Cont::iterator.
*/
template<class RealType = double, class Cont = std::vector<RealType> >
class uniform_on_sphere
{
public:
typedef RealType input_type;
typedef Cont result_type;
class param_type
{
public:
typedef uniform_on_sphere distribution_type;
/**
* Constructs the parameters of a uniform_on_sphere
* distribution, given the dimension of the sphere.
*/
explicit param_type(int dim_arg = 2) : _dim(dim_arg)
{
BOOST_ASSERT(_dim >= 0);
}
/** Returns the dimension of the sphere. */
int dim() const { return _dim; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._dim;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._dim;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._dim == rhs._dim; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
int _dim;
};
/**
* Constructs a @c uniform_on_sphere distribution.
* @c dim is the dimension of the sphere.
*
* Requires: dim >= 0
*/
explicit uniform_on_sphere(int dim_arg = 2)
: _container(dim_arg), _dim(dim_arg) { }
/**
* Constructs a @c uniform_on_sphere distribution from its parameters.
*/
explicit uniform_on_sphere(const param_type& parm)
: _container(parm.dim()), _dim(parm.dim()) { }
// compiler-generated copy ctor and assignment operator are fine
/** Returns the dimension of the sphere. */
int dim() const { return _dim; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_dim); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_dim = parm.dim();
_container.resize(_dim);
}
/**
* Returns the smallest value that the distribution can produce.
* Note that this is required to approximate the standard library's
* requirements. The behavior is defined according to lexicographical
* comparison so that for a container type of std::vector,
* dist.min() <= x <= dist.max() where x is any value produced
* by the distribution.
*/
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
result_type result(_dim);
if(_dim != 0) {
result.front() = RealType(-1.0);
}
return result;
}
/**
* Returns the largest value that the distribution can produce.
* Note that this is required to approximate the standard library's
* requirements. The behavior is defined according to lexicographical
* comparison so that for a container type of std::vector,
* dist.min() <= x <= dist.max() where x is any value produced
* by the distribution.
*/
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
result_type result(_dim);
if(_dim != 0) {
result.front() = RealType(1.0);
}
return result;
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() {}
/**
* Returns a point uniformly distributed over the surface of
* a sphere of dimension dim().
*/
template<class Engine>
const result_type & operator()(Engine& eng)
{
using std::sqrt;
switch(_dim)
{
case 0: break;
case 1:
{
if(uniform_01<RealType>()(eng) < 0.5) {
*_container.begin() = -1;
} else {
*_container.begin() = 1;
}
break;
}
case 2:
{
uniform_01<RealType> uniform;
RealType sqsum;
RealType x, y;
do {
x = uniform(eng) * 2 - 1;
y = uniform(eng) * 2 - 1;
sqsum = x*x + y*y;
} while(sqsum == 0 || sqsum > 1);
RealType mult = 1/sqrt(sqsum);
typename Cont::iterator iter = _container.begin();
*iter = x * mult;
iter++;
*iter = y * mult;
break;
}
case 3:
{
uniform_01<RealType> uniform;
RealType sqsum;
RealType x, y;
do {
x = uniform(eng) * 2 - 1;
y = uniform(eng) * 2 - 1;
sqsum = x*x + y*y;
} while(sqsum > 1);
RealType mult = 2 * sqrt(1 - sqsum);
typename Cont::iterator iter = _container.begin();
*iter = x * mult;
++iter;
*iter = y * mult;
++iter;
*iter = 2 * sqsum - 1;
break;
}
default:
{
detail::unit_normal_distribution<RealType> normal;
RealType sqsum;
do {
sqsum = 0;
for(typename Cont::iterator it = _container.begin();
it != _container.end();
++it) {
RealType val = normal(eng);
*it = val;
sqsum += val * val;
}
} while(sqsum == 0);
// for all i: result[i] /= sqrt(sqsum)
std::transform(_container.begin(), _container.end(), _container.begin(),
std::bind2nd(std::multiplies<RealType>(), 1/sqrt(sqsum)));
}
}
return _container;
}
/**
* Returns a point uniformly distributed over the surface of
* a sphere of dimension param.dim().
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{
return uniform_on_sphere(parm)(eng);
}
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_on_sphere, sd)
{
os << sd._dim;
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_on_sphere, sd)
{
is >> sd._dim;
sd._container.resize(sd._dim);
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values, given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_on_sphere, lhs, rhs)
{ return lhs._dim == rhs._dim; }
/**
* Returns true if the two distributions may produce different
* sequences of values, given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_on_sphere)
private:
result_type _container;
int _dim;
};
} // namespace random
using random::uniform_on_sphere;
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP

View File

@ -1,82 +0,0 @@
/* boost random/uniform_real.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_REAL_HPP
#define BOOST_RANDOM_UNIFORM_REAL_HPP
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/uniform_real_distribution.hpp>
namespace boost {
/**
* The distribution function uniform_real models a random distribution.
* On each invocation, it returns a random floating-point value uniformly
* distributed in the range [min..max).
*
* This class is deprecated. Please use @c uniform_real_distribution in
* new code.
*/
template<class RealType = double>
class uniform_real : public random::uniform_real_distribution<RealType>
{
typedef random::uniform_real_distribution<RealType> base_type;
public:
class param_type : public base_type::param_type
{
public:
typedef uniform_real distribution_type;
/**
* Constructs the parameters of a uniform_real distribution.
*
* Requires: min <= max
*/
explicit param_type(RealType min_arg = RealType(0.0),
RealType max_arg = RealType(1.0))
: base_type::param_type(min_arg, max_arg)
{}
};
/**
* Constructs a uniform_real object. @c min and @c max are the
* parameters of the distribution.
*
* Requires: min <= max
*/
explicit uniform_real(RealType min_arg = RealType(0.0),
RealType max_arg = RealType(1.0))
: base_type(min_arg, max_arg)
{
BOOST_ASSERT(min_arg < max_arg);
}
/** Constructs a uniform_real distribution from its parameters. */
explicit uniform_real(const param_type& parm)
: base_type(parm)
{}
/** Returns the parameters of the distribution */
param_type param() const { return param_type(this->a(), this->b()); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm) { this->base_type::param(parm); }
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_REAL_HPP

View File

@ -1,241 +0,0 @@
/* boost random/uniform_real_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
#include <iosfwd>
#include <ios>
#include <istream>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/bool.hpp>
namespace boost {
namespace random {
namespace detail {
template<class Engine, class T>
T generate_uniform_real(
Engine& eng, T min_value, T max_value,
boost::mpl::false_ /** is_integral<Engine::result_type> */)
{
for(;;) {
typedef T result_type;
result_type numerator = static_cast<T>(eng() - (eng.min)());
result_type divisor = static_cast<T>((eng.max)() - (eng.min)());
BOOST_ASSERT(divisor > 0);
BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
T result = numerator / divisor * (max_value - min_value) + min_value;
if(result < max_value) return result;
}
}
template<class Engine, class T>
T generate_uniform_real(
Engine& eng, T min_value, T max_value,
boost::mpl::true_ /** is_integral<Engine::result_type> */)
{
for(;;) {
typedef T result_type;
typedef typename Engine::result_type base_result;
result_type numerator = static_cast<T>(subtract<base_result>()(eng(), (eng.min)()));
result_type divisor = static_cast<T>(subtract<base_result>()((eng.max)(), (eng.min)())) + 1;
BOOST_ASSERT(divisor > 0);
BOOST_ASSERT(numerator >= 0 && numerator <= divisor);
T result = numerator / divisor * (max_value - min_value) + min_value;
if(result < max_value) return result;
}
}
template<class Engine, class T>
inline T generate_uniform_real(Engine& eng, T min_value, T max_value)
{
if(max_value / 2 - min_value / 2 > (std::numeric_limits<T>::max)() / 2)
return 2 * generate_uniform_real(eng, T(min_value / 2), T(max_value / 2));
typedef typename Engine::result_type base_result;
return generate_uniform_real(eng, min_value, max_value,
boost::is_integral<base_result>());
}
}
/**
* The class template uniform_real_distribution models a \random_distribution.
* On each invocation, it returns a random floating-point value uniformly
* distributed in the range [min..max).
*/
template<class RealType = double>
class uniform_real_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
class param_type
{
public:
typedef uniform_real_distribution distribution_type;
/**
* Constructs the parameters of a uniform_real_distribution.
*
* Requires min <= max
*/
explicit param_type(RealType min_arg = RealType(0.0),
RealType max_arg = RealType(1.0))
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(_min < _max);
}
/** Returns the minimum value of the distribution. */
RealType a() const { return _min; }
/** Returns the maximum value of the distribution. */
RealType b() const { return _max; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._min << " " << parm._max;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
RealType min_in, max_in;
if(is >> min_in >> std::ws >> max_in) {
if(min_in <= max_in) {
parm._min = min_in;
parm._max = max_in;
} else {
is.setstate(std::ios_base::failbit);
}
}
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _min;
RealType _max;
};
/**
* Constructs a uniform_real_distribution. @c min and @c max are
* the parameters of the distribution.
*
* Requires: min <= max
*/
explicit uniform_real_distribution(
RealType min_arg = RealType(0.0),
RealType max_arg = RealType(1.0))
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(min_arg < max_arg);
}
/** Constructs a uniform_real_distribution from its parameters. */
explicit uniform_real_distribution(const param_type& parm)
: _min(parm.a()), _max(parm.b()) {}
/** Returns the minimum value of the distribution */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
/** Returns the maximum value of the distribution */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
/** Returns the minimum value of the distribution */
RealType a() const { return _min; }
/** Returns the maximum value of the distribution */
RealType b() const { return _max; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_min, _max); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_min = parm.a();
_max = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Returns a value uniformly distributed in the range [min, max). */
template<class Engine>
result_type operator()(Engine& eng) const
{ return detail::generate_uniform_real(eng, _min, _max); }
/**
* Returns a value uniformly distributed in the range
* [param.a(), param.b()).
*/
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{ return detail::generate_uniform_real(eng, parm.a(), parm.b()); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_real_distribution, ud)
{
os << ud.param();
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_real_distribution, ud)
{
param_type parm;
if(is >> parm) {
ud.param(parm);
}
return is;
}
/**
* Returns true if the two distributions will produce identical sequences
* of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_real_distribution, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/**
* Returns true if the two distributions may produce different sequences
* of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_real_distribution)
private:
RealType _min;
RealType _max;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_INT_HPP

View File

@ -1,307 +0,0 @@
/* boost random/uniform_smallint.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#define BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#include <istream>
#include <iosfwd>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/mpl/bool.hpp>
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
#include <boost/mpl/if.hpp>
#endif
namespace boost {
namespace random {
// uniform integer distribution on a small range [min, max]
/**
* The distribution function uniform_smallint models a \random_distribution.
* On each invocation, it returns a random integer value uniformly distributed
* in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes
* that the desired range (max-min+1) is small compared to the range of the
* underlying source of random numbers and thus makes no attempt to limit
* quantization errors.
*
* Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of
* integer numbers, and
* let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random
* numbers. Then, for the uniform distribution, the theoretical probability
* for any number i in the range \f$r_{\mathtt{out}}\f$ will be
* \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$.
* Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for
* the underlying source of random numbers, i.e.
* \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$.
* Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random
* distribution generated by @c uniform_smallint. Then the sum over all
* i in \f$r_{\mathtt{out}}\f$ of
* \f$\displaystyle
* \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$
* shall not exceed
* \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2}
* (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
* (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$.
*
* The template parameter IntType shall denote an integer-like value type.
*
* @xmlnote
* The property above is the square sum of the relative differences
* in probabilities between the desired uniform distribution
* \f$p_{\mathtt{out}}(i)\f$ and the generated distribution
* \f$p_{\mathtt{out\_s}}(i)\f$.
* The property can be fulfilled with the calculation
* \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows:
* Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$.
* The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the
* range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned
* \f$\displaystyle
* \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$
* numbers of the base distribution, the rest has only \f$\displaystyle
* \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$.
* Therefore,
* \f$\displaystyle p_{\mathtt{out\_s}}(i) =
* \left(\left\lfloor\frac{r_{\mathtt{base}}}
* {r_{\mathtt{out}}}\right\rfloor+1\right) /
* r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) =
* \left\lfloor\frac{r_{\mathtt{base}}}
* {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise.
* Substituting this in the
* above sum formula leads to the desired result.
* @endxmlnote
*
* Note: The upper bound for
* \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})
* (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is
* \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$. Regarding the upper bound
* for the square sum of the relative quantization error of
* \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it
* seems wise to either choose \f$r_{\mathtt{base}}\f$ so that
* \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that
* \f$r_{\mathtt{base}}\f$ is
* divisible by \f$r_{\mathtt{out}}\f$.
*/
template<class IntType = int>
class uniform_smallint
{
public:
typedef IntType input_type;
typedef IntType result_type;
class param_type
{
public:
typedef uniform_smallint distribution_type;
/** constructs the parameters of a @c uniform_smallint distribution. */
param_type(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg)
{
BOOST_ASSERT(_min <= _max);
}
/** Returns the minimum value. */
IntType a() const { return _min; }
/** Returns the maximum value. */
IntType b() const { return _max; }
/** Writes the parameters to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{
os << parm._min << " " << parm._max;
return os;
}
/** Reads the parameters from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{
is >> parm._min >> std::ws >> parm._max;
return is;
}
/** Returns true if the two sets of parameters are equal. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/** Returns true if the two sets of parameters are different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
IntType _min;
IntType _max;
};
/**
* Constructs a @c uniform_smallint. @c min and @c max are the
* lower and upper bounds of the output range, respectively.
*/
explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg) {}
/**
* Constructs a @c uniform_smallint from its parameters.
*/
explicit uniform_smallint(const param_type& parm)
: _min(parm.a()), _max(parm.b()) {}
/** Returns the minimum value of the distribution. */
result_type a() const { return _min; }
/** Returns the maximum value of the distribution. */
result_type b() const { return _max; }
/** Returns the minimum value of the distribution. */
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
/** Returns the maximum value of the distribution. */
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_min, _max); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_min = parm.a();
_max = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Returns a value uniformly distributed in the range [min(), max()]. */
template<class Engine>
result_type operator()(Engine& eng) const
{
typedef typename Engine::result_type base_result;
return generate(eng, boost::random::traits::is_integral<base_result>());
}
/** Returns a value uniformly distributed in the range [param.a(), param.b()]. */
template<class Engine>
result_type operator()(Engine& eng, const param_type& parm) const
{ return uniform_smallint(parm)(eng); }
/** Writes the distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud)
{
os << ud._min << " " << ud._max;
return os;
}
/** Reads the distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud)
{
is >> ud._min >> std::ws >> ud._max;
return is;
}
/**
* Returns true if the two distributions will produce identical
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs)
{ return lhs._min == rhs._min && lhs._max == rhs._max; }
/**
* Returns true if the two distributions may produce different
* sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint)
private:
// \cond show_private
template<class Engine>
result_type generate(Engine& eng, boost::mpl::true_) const
{
// equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min,
// but guarantees no overflow.
typedef typename Engine::result_type base_result;
typedef typename boost::random::traits::make_unsigned<base_result>::type base_unsigned;
typedef typename boost::random::traits::make_unsigned_or_unbounded<result_type>::type range_type;
#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
typedef typename mpl::if_c<
std::numeric_limits<range_type>::is_specialized && std::numeric_limits<base_unsigned>::is_specialized
&& (std::numeric_limits<range_type>::digits >= std::numeric_limits<base_unsigned>::digits),
range_type, base_unsigned>::type mixed_range_type;
#else
typedef base_unsigned mixed_range_type;
#endif
range_type range = random::detail::subtract<result_type>()(_max, _min);
base_unsigned base_range =
random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
base_unsigned val =
random::detail::subtract<base_result>()(eng(), (eng.min)());
if(range >= base_range) {
return boost::random::detail::add<range_type, result_type>()(
static_cast<range_type>(val), _min);
} else {
// This involves mixed arithmetic between the base generators range
// type, and the result_type's range type. mixed_range_type is
// normally the same as base_unsigned which is the most efficient
// option, but requires a narrowing explcit cast if result_type
// is a multiprecision type. If no such casts are available then use
// multiprecision arithmetic throughout instead.
mixed_range_type modulus = static_cast<mixed_range_type>(range)+1;
return boost::random::detail::add<range_type, result_type>()(
static_cast<mixed_range_type>(val) % modulus, _min);
}
}
template<class Engine>
result_type generate(Engine& eng, boost::mpl::false_) const
{
typedef typename Engine::result_type base_result;
typedef typename boost::random::traits::make_unsigned<result_type>::type range_type;
range_type range = random::detail::subtract<result_type>()(_max, _min);
base_result val = boost::uniform_01<base_result>()(eng);
// what is the worst that can possibly happen here?
// base_result may not be able to represent all the values in [0, range]
// exactly. If this happens, it will cause round off error and we
// won't be able to produce all the values in the range. We don't
// care about this because the user has already told us not to by
// using uniform_smallint. However, we do need to be careful
// to clamp the result, or floating point rounding can produce
// an out of range result.
range_type offset = static_cast<range_type>(val * (static_cast<base_result>(range) + 1));
if(offset > range) return _max;
return boost::random::detail::add<range_type, result_type>()(offset , _min);
}
// \endcond
result_type _min;
result_type _max;
};
} // namespace random
using random::uniform_smallint;
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP

View File

@ -1,122 +0,0 @@
/* boost random/variate_generator.hpp header file
*
* Copyright Jens Maurer 2002
* Copyright Steven Watanabe 2011
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_RANDOM_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_GENERATOR_HPP
#include <boost/random/detail/ptr_helper.hpp>
#include <boost/random/detail/disable_warnings.hpp>
namespace boost {
/// \cond hide_private_members
namespace random {
///\endcond
/**
* A random variate generator is used to join a random number
* generator together with a random number distribution.
* Boost.Random provides a vast choice of \generators as well
* as \distributions.
*
* The argument for the template parameter Engine shall be of
* the form U, U&, or U*, where U models a
* \uniform_random_number_generator. Then, the member
* engine_value_type names U (not the pointer or reference to U).
*
* Specializations of @c variate_generator satisfy the
* requirements of CopyConstructible. They also satisfy the
* requirements of Assignable unless the template parameter
* Engine is of the form U&.
*
* The complexity of all functions specified in this section
* is constant. No function described in this section except
* the constructor throws an exception.
*/
template<class Engine, class Distribution>
class variate_generator
{
private:
typedef boost::random::detail::ptr_helper<Engine> helper_type;
public:
typedef typename helper_type::value_type engine_value_type;
typedef Engine engine_type;
typedef Distribution distribution_type;
typedef typename Distribution::result_type result_type;
/**
* Constructs a @c variate_generator object with the associated
* \uniform_random_number_generator eng and the associated
* \random_distribution d.
*
* Throws: If and what the copy constructor of Engine or
* Distribution throws.
*/
variate_generator(Engine e, Distribution d)
: _eng(e), _dist(d) { }
/** Returns: distribution()(engine()) */
result_type operator()() { return _dist(engine()); }
/**
* Returns: distribution()(engine(), value).
*/
template<class T>
result_type operator()(const T& value) { return _dist(engine(), value); }
/**
* Returns: A reference to the associated uniform random number generator.
*/
engine_value_type& engine() { return helper_type::ref(_eng); }
/**
* Returns: A reference to the associated uniform random number generator.
*/
const engine_value_type& engine() const { return helper_type::ref(_eng); }
/** Returns: A reference to the associated \random_distribution. */
distribution_type& distribution() { return _dist; }
/**
* Returns: A reference to the associated random distribution.
*/
const distribution_type& distribution() const { return _dist; }
/**
* Precondition: distribution().min() is well-formed
*
* Returns: distribution().min()
*/
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().min)(); }
/**
* Precondition: distribution().max() is well-formed
*
* Returns: distribution().max()
*/
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().max)(); }
private:
Engine _eng;
distribution_type _dist;
};
} // namespace random
using random::variate_generator;
} // namespace boost
#include <boost/random/detail/enable_warnings.hpp>
#endif // BOOST_RANDOM_RANDOM_GENERATOR_HPP

View File

@ -1,177 +0,0 @@
/* boost random/weibull_distribution.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)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*/
#ifndef BOOST_RANDOM_WEIBULL_DISTRIBUTION_HPP
#define BOOST_RANDOM_WEIBULL_DISTRIBUTION_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <iosfwd>
#include <istream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/random/detail/operators.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
/**
* The Weibull distribution is a real valued distribution with two
* parameters a and b, producing values >= 0.
*
* It has \f$\displaystyle p(x) = \frac{a}{b}\left(\frac{x}{b}\right)^{a-1}e^{-\left(\frac{x}{b}\right)^a}\f$.
*/
template<class RealType = double>
class weibull_distribution {
public:
typedef RealType result_type;
typedef RealType input_type;
class param_type {
public:
typedef weibull_distribution distribution_type;
/**
* Constructs a @c param_type from the "a" and "b" parameters
* of the distribution.
*
* Requires: a > 0 && b > 0
*/
explicit param_type(RealType a_arg = 1.0, RealType b_arg = 1.0)
: _a(a_arg), _b(b_arg)
{}
/** Returns the "a" parameter of the distribtuion. */
RealType a() const { return _a; }
/** Returns the "b" parameter of the distribution. */
RealType b() const { return _b; }
/** Writes a @c param_type to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
{ os << parm._a << ' ' << parm._b; return os; }
/** Reads a @c param_type from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
{ is >> parm._a >> std::ws >> parm._b; return is; }
/** Returns true if the two sets of parameters are the same. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b; }
/** Returns true if the two sets of parameters are the different. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
private:
RealType _a;
RealType _b;
};
/**
* Constructs a @c weibull_distribution from its "a" and "b" parameters.
*
* Requires: a > 0 && b > 0
*/
explicit weibull_distribution(RealType a_arg = 1.0, RealType b_arg = 1.0)
: _a(a_arg), _b(b_arg)
{}
/** Constructs a @c weibull_distribution from its parameters. */
explicit weibull_distribution(const param_type& parm)
: _a(parm.a()), _b(parm.b())
{}
/**
* Returns a random variate distributed according to the
* @c weibull_distribution.
*/
template<class URNG>
RealType operator()(URNG& urng) const
{
using std::pow;
using std::log;
return _b*pow(-log(1 - uniform_01<RealType>()(urng)), 1/_a);
}
/**
* Returns a random variate distributed accordint to the Weibull
* distribution with parameters specified by @c param.
*/
template<class URNG>
RealType operator()(URNG& urng, const param_type& parm) const
{
return weibull_distribution(parm)(urng);
}
/** Returns the "a" parameter of the distribution. */
RealType a() const { return _a; }
/** Returns the "b" parameter of the distribution. */
RealType b() const { return _b; }
/** Returns the smallest value that the distribution can produce. */
RealType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
/** Returns the largest value that the distribution can produce. */
RealType max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{ return std::numeric_limits<RealType>::infinity(); }
/** Returns the parameters of the distribution. */
param_type param() const { return param_type(_a, _b); }
/** Sets the parameters of the distribution. */
void param(const param_type& parm)
{
_a = parm.a();
_b = parm.b();
}
/**
* Effects: Subsequent uses of the distribution do not depend
* on values produced by any engine prior to invoking reset.
*/
void reset() { }
/** Writes a @c weibull_distribution to a @c std::ostream. */
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, weibull_distribution, wd)
{
os << wd.param();
return os;
}
/** Reads a @c weibull_distribution from a @c std::istream. */
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, weibull_distribution, wd)
{
param_type parm;
if(is >> parm) {
wd.param(parm);
}
return is;
}
/**
* Returns true if the two instances of @c weibull_distribution will
* return identical sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(weibull_distribution, lhs, rhs)
{ return lhs._a == rhs._a && lhs._b == rhs._b; }
/**
* Returns true if the two instances of @c weibull_distribution will
* return different sequences of values given equal generators.
*/
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(weibull_distribution)
private:
RealType _a;
RealType _b;
};
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_WEIBULL_DISTRIBUTION_HPP

View File

@ -1,208 +0,0 @@
/* boost random/xor_combine.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id$
*
*/
#ifndef BOOST_RANDOM_XOR_COMBINE_HPP
#define BOOST_RANDOM_XOR_COMBINE_HPP
#include <istream>
#include <iosfwd>
#include <cassert>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp> // uint32_t
#include <boost/random/detail/config.hpp>
#include <boost/random/detail/seed.hpp>
#include <boost/random/detail/seed_impl.hpp>
#include <boost/random/detail/operators.hpp>
namespace boost {
namespace random {
/**
* Instantiations of @c xor_combine_engine model a
* \pseudo_random_number_generator. To produce its output it
* invokes each of the base generators, shifts their results
* and xors them together.
*/
template<class URNG1, int s1, class URNG2, int s2>
class xor_combine_engine
{
public:
typedef URNG1 base1_type;
typedef URNG2 base2_type;
typedef typename base1_type::result_type result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, shift1 = s1);
BOOST_STATIC_CONSTANT(int, shift2 = s2);
/**
* Constructors a @c xor_combine_engine by default constructing
* both base generators.
*/
xor_combine_engine() : _rng1(), _rng2() { }
/** Constructs a @c xor_combine by copying two base generators. */
xor_combine_engine(const base1_type & rng1, const base2_type & rng2)
: _rng1(rng1), _rng2(rng2) { }
/**
* Constructs a @c xor_combine_engine, seeding both base generators
* with @c v.
*
* @xmlwarning
* The exact algorithm used by this function may change in the future.
* @endxmlwarning
*/
BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(xor_combine_engine,
result_type, v)
{ seed(v); }
/**
* Constructs a @c xor_combine_engine, seeding both base generators
* with values produced by @c seq.
*/
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(xor_combine_engine,
SeedSeq, seq)
{ seed(seq); }
/**
* Constructs a @c xor_combine_engine, seeding both base generators
* with values from the iterator range [first, last) and changes
* first to point to the element after the last one used. If there
* are not enough elements in the range to seed both generators,
* throws @c std::invalid_argument.
*/
template<class It> xor_combine_engine(It& first, It last)
: _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
/** Calls @c seed() for both base generators. */
void seed() { _rng1.seed(); _rng2.seed(); }
/** @c seeds both base generators with @c v. */
BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(xor_combine_engine, result_type, v)
{ _rng1.seed(v); _rng2.seed(v); }
/** @c seeds both base generators with values produced by @c seq. */
BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(xor_combine_engine, SeedSeq, seq)
{ _rng1.seed(seq); _rng2.seed(seq); }
/**
* seeds both base generators with values from the iterator
* range [first, last) and changes first to point to the element
* after the last one used. If there are not enough elements in
* the range to seed both generators, throws @c std::invalid_argument.
*/
template<class It> void seed(It& first, It last)
{
_rng1.seed(first, last);
_rng2.seed(first, last);
}
/** Returns the first base generator. */
const base1_type& base1() const { return _rng1; }
/** Returns the second base generator. */
const base2_type& base2() const { return _rng2; }
/** Returns the next value of the generator. */
result_type operator()()
{
return (_rng1() << s1) ^ (_rng2() << s2);
}
/** Fills a range with random values */
template<class Iter>
void generate(Iter first, Iter last)
{ detail::generate_from_int(*this, first, last); }
/** Advances the state of the generator by @c z. */
void discard(boost::uintmax_t z)
{
_rng1.discard(z);
_rng2.discard(z);
}
/** Returns the smallest value that the generator can produce. */
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::min)((URNG1::min)(), (URNG2::min)()); }
/** Returns the largest value that the generator can produce. */
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return (std::max)((URNG1::min)(), (URNG2::max)()); }
/**
* Writes the textual representation of the generator to a @c std::ostream.
*/
BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, xor_combine_engine, s)
{
os << s._rng1 << ' ' << s._rng2;
return os;
}
/**
* Reads the textual representation of the generator from a @c std::istream.
*/
BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, xor_combine_engine, s)
{
is >> s._rng1 >> std::ws >> s._rng2;
return is;
}
/** Returns true if the two generators will produce identical sequences. */
BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(xor_combine_engine, x, y)
{ return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
/** Returns true if the two generators will produce different sequences. */
BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(xor_combine_engine)
private:
base1_type _rng1;
base2_type _rng2;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class URNG1, int s1, class URNG2, int s2>
const bool xor_combine_engine<URNG1, s1, URNG2, s2>::has_fixed_range;
template<class URNG1, int s1, class URNG2, int s2>
const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift1;
template<class URNG1, int s1, class URNG2, int s2>
const int xor_combine_engine<URNG1, s1, URNG2, s2>::shift2;
#endif
/// \cond show_private
/** Provided for backwards compatibility. */
template<class URNG1, int s1, class URNG2, int s2,
typename URNG1::result_type v = 0>
class xor_combine : public xor_combine_engine<URNG1, s1, URNG2, s2>
{
typedef xor_combine_engine<URNG1, s1, URNG2, s2> base_type;
public:
typedef typename base_type::result_type result_type;
xor_combine() {}
xor_combine(result_type val) : base_type(val) {}
template<class It>
xor_combine(It& first, It last) : base_type(first, last) {}
xor_combine(const URNG1 & rng1, const URNG2 & rng2)
: base_type(rng1, rng2) { }
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::min)((this->base1().min)(), (this->base2().min)()); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (std::max)((this->base1().min)(), (this->base2().max)()); }
};
/// \endcond
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_XOR_COMBINE_HPP

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,2 @@
https://github.com/imneme/pcg-cpp
0ca2e8ea6ba212bdfbc6219c2313c45917e34b8d

View File

@ -0,0 +1,52 @@
# PCG Random Number Generation, C++ Edition
[PCG-Random website]: http://www.pcg-random.org
This code provides an implementation of the PCG family of random number
generators, which are fast, statistically excellent, and offer a number of
useful features.
Full details can be found at the [PCG-Random website]. This version
of the code provides many family members -- if you just want one
simple generator, you may prefer the minimal C version of the library.
There are two kinds of generator, normal generators and extended generators.
Extended generators provide *k* dimensional equidistribution and can perform
party tricks, but generally speaking most people only need the normal
generators.
There are two ways to access the generators, using a convenience typedef
or by using the underlying templates directly (similar to C++11's `std::mt19937` typedef vs its `std::mersenne_twister_engine` template). For most users, the convenience typedef is what you want, and probably you're fine with `pcg32` for 32-bit numbers. If you want 64-bit numbers, either use `pcg64` (or, if you're on a 32-bit system, making 64 bits from two calls to `pcg32_k2` may be faster).
## Documentation and Examples
Visit [PCG-Random website] for information on how to use this library, or look
at the sample code in the `sample` directory -- hopefully it should be fairly
self explanatory.
## Building
The code is written in C++11, as an include-only library (i.e., there is
nothing you need to build). There are some provided demo programs and tests
however. On a Unix-style system (e.g., Linux, Mac OS X) you should be able
to just type
make
To build the demo programs.
## Testing
Run
make test
## Directory Structure
The directories are arranged as follows:
* `include` -- contains `pcg_random.hpp` and supporting include files
* `test-high` -- test code for the high-level API where the functions have
shorter, less scary-looking names.
* `sample` -- sample code, some similar to the code in `test-high` but more
human readable, some other examples too

View File

@ -0,0 +1,618 @@
/*
* PCG Random Number Generation for C++
*
* Copyright 2014-2017 Melissa O'Neill <oneill@pcg-random.org>,
* and the PCG Project contributors.
*
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
*
* Licensed under the Apache License, Version 2.0 (provided in
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
* or under the MIT license (provided in LICENSE-MIT.txt and at
* http://opensource.org/licenses/MIT), at your option. This file may not
* be copied, modified, or distributed except according to those terms.
*
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See your chosen license for details.
*
* For additional information about the PCG random number generation scheme,
* visit http://www.pcg-random.org/.
*/
/*
* This file provides support code that is useful for random-number generation
* but not specific to the PCG generation scheme, including:
* - 128-bit int support for platforms where it isn't available natively
* - bit twiddling operations
* - I/O of 128-bit and 8-bit integers
* - Handling the evilness of SeedSeq
* - Support for efficiently producing random numbers less than a given
* bound
*/
#ifndef PCG_EXTRAS_HPP_INCLUDED
#define PCG_EXTRAS_HPP_INCLUDED 1
#include <cinttypes>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <limits>
#include <iostream>
#include <type_traits>
#include <utility>
#include <locale>
#include <iterator>
#ifdef __GNUC__
#include <cxxabi.h>
#endif
/*
* Abstractions for compiler-specific directives
*/
#ifdef __GNUC__
#define PCG_NOINLINE __attribute__((noinline))
#else
#define PCG_NOINLINE
#endif
/*
* Some members of the PCG library use 128-bit math. When compiling on 64-bit
* platforms, both GCC and Clang provide 128-bit integer types that are ideal
* for the job.
*
* On 32-bit platforms (or with other compilers), we fall back to a C++
* class that provides 128-bit unsigned integers instead. It may seem
* like we're reinventing the wheel here, because libraries already exist
* that support large integers, but most existing libraries provide a very
* generic multiprecision code, but here we're operating at a fixed size.
* Also, most other libraries are fairly heavyweight. So we use a direct
* implementation. Sadly, it's much slower than hand-coded assembly or
* direct CPU support.
*
*/
#if __SIZEOF_INT128__
namespace pcg_extras {
typedef __uint128_t pcg128_t;
}
#define PCG_128BIT_CONSTANT(high,low) \
((pcg128_t(high) << 64) + low)
#else
#include "pcg_uint128.hpp"
namespace pcg_extras {
typedef pcg_extras::uint_x4<uint32_t,uint64_t> pcg128_t;
}
#define PCG_128BIT_CONSTANT(high,low) \
pcg128_t(high,low)
#define PCG_EMULATED_128BIT_MATH 1
#endif
namespace pcg_extras {
/*
* We often need to represent a "number of bits". When used normally, these
* numbers are never greater than 128, so an unsigned char is plenty.
* If you're using a nonstandard generator of a larger size, you can set
* PCG_BITCOUNT_T to have it define it as a larger size. (Some compilers
* might produce faster code if you set it to an unsigned int.)
*/
#ifndef PCG_BITCOUNT_T
typedef uint8_t bitcount_t;
#else
typedef PCG_BITCOUNT_T bitcount_t;
#endif
/*
* C++ requires us to be able to serialize RNG state by printing or reading
* it from a stream. Because we use 128-bit ints, we also need to be able
* ot print them, so here is code to do so.
*
* This code provides enough functionality to print 128-bit ints in decimal
* and zero-padded in hex. It's not a full-featured implementation.
*/
template <typename CharT, typename Traits>
std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& out, pcg128_t value)
{
auto desired_base = out.flags() & out.basefield;
bool want_hex = desired_base == out.hex;
if (want_hex) {
uint64_t highpart = uint64_t(value >> 64);
uint64_t lowpart = uint64_t(value);
auto desired_width = out.width();
if (desired_width > 16) {
out.width(desired_width - 16);
}
if (highpart != 0 || desired_width > 16)
out << highpart;
CharT oldfill = '\0';
if (highpart != 0) {
out.width(16);
oldfill = out.fill('0');
}
auto oldflags = out.setf(decltype(desired_base){}, out.showbase);
out << lowpart;
out.setf(oldflags);
if (highpart != 0) {
out.fill(oldfill);
}
return out;
}
constexpr size_t MAX_CHARS_128BIT = 40;
char buffer[MAX_CHARS_128BIT];
char* pos = buffer+sizeof(buffer);
*(--pos) = '\0';
constexpr auto BASE = pcg128_t(10ULL);
do {
auto div = value / BASE;
auto mod = uint32_t(value - (div * BASE));
*(--pos) = '0' + char(mod);
value = div;
} while(value != pcg128_t(0ULL));
return out << pos;
}
template <typename CharT, typename Traits>
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, pcg128_t& value)
{
typename std::basic_istream<CharT,Traits>::sentry s(in);
if (!s)
return in;
constexpr auto BASE = pcg128_t(10ULL);
pcg128_t current(0ULL);
bool did_nothing = true;
bool overflow = false;
for(;;) {
CharT wide_ch = in.get();
if (!in.good())
break;
auto ch = in.narrow(wide_ch, '\0');
if (ch < '0' || ch > '9') {
in.unget();
break;
}
did_nothing = false;
pcg128_t digit(uint32_t(ch - '0'));
pcg128_t timesbase = current*BASE;
overflow = overflow || timesbase < current;
current = timesbase + digit;
overflow = overflow || current < digit;
}
if (did_nothing || overflow) {
in.setstate(std::ios::failbit);
if (overflow)
current = ~pcg128_t(0ULL);
}
value = current;
return in;
}
/*
* Likewise, if people use tiny rngs, we'll be serializing uint8_t.
* If we just used the provided IO operators, they'd read/write chars,
* not ints, so we need to define our own. We *can* redefine this operator
* here because we're in our own namespace.
*/
template <typename CharT, typename Traits>
std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>&out, uint8_t value)
{
return out << uint32_t(value);
}
template <typename CharT, typename Traits>
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, uint8_t& target)
{
uint32_t value = 0xdecea5edU;
in >> value;
if (!in && value == 0xdecea5edU)
return in;
if (value > uint8_t(~0)) {
in.setstate(std::ios::failbit);
value = ~0U;
}
target = uint8_t(value);
return in;
}
/* Unfortunately, the above functions don't get found in preference to the
* built in ones, so we create some more specific overloads that will.
* Ugh.
*/
inline std::ostream& operator<<(std::ostream& out, uint8_t value)
{
return pcg_extras::operator<< <char>(out, value);
}
inline std::istream& operator>>(std::istream& in, uint8_t& value)
{
return pcg_extras::operator>> <char>(in, value);
}
/*
* Useful bitwise operations.
*/
/*
* XorShifts are invertable, but they are someting of a pain to invert.
* This function backs them out. It's used by the whacky "inside out"
* generator defined later.
*/
template <typename itype>
inline itype unxorshift(itype x, bitcount_t bits, bitcount_t shift)
{
if (2*shift >= bits) {
return x ^ (x >> shift);
}
itype lowmask1 = (itype(1U) << (bits - shift*2)) - 1;
itype highmask1 = ~lowmask1;
itype top1 = x;
itype bottom1 = x & lowmask1;
top1 ^= top1 >> shift;
top1 &= highmask1;
x = top1 | bottom1;
itype lowmask2 = (itype(1U) << (bits - shift)) - 1;
itype bottom2 = x & lowmask2;
bottom2 = unxorshift(bottom2, bits - shift, shift);
bottom2 &= lowmask1;
return top1 | bottom2;
}
/*
* Rotate left and right.
*
* In ideal world, compilers would spot idiomatic rotate code and convert it
* to a rotate instruction. Of course, opinions vary on what the correct
* idiom is and how to spot it. For clang, sometimes it generates better
* (but still crappy) code if you define PCG_USE_ZEROCHECK_ROTATE_IDIOM.
*/
template <typename itype>
inline itype rotl(itype value, bitcount_t rot)
{
constexpr bitcount_t bits = sizeof(itype) * 8;
constexpr bitcount_t mask = bits - 1;
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM
return rot ? (value << rot) | (value >> (bits - rot)) : value;
#else
return (value << rot) | (value >> ((- rot) & mask));
#endif
}
template <typename itype>
inline itype rotr(itype value, bitcount_t rot)
{
constexpr bitcount_t bits = sizeof(itype) * 8;
constexpr bitcount_t mask = bits - 1;
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM
return rot ? (value >> rot) | (value << (bits - rot)) : value;
#else
return (value >> rot) | (value << ((- rot) & mask));
#endif
}
/* Unfortunately, both Clang and GCC sometimes perform poorly when it comes
* to properly recognizing idiomatic rotate code, so for we also provide
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
* (I hope that these compilers get better so that this code can die.)
*
* These overloads will be preferred over the general template code above.
*/
#if PCG_USE_INLINE_ASM && __GNUC__ && (__x86_64__ || __i386__)
inline uint8_t rotr(uint8_t value, bitcount_t rot)
{
asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
inline uint16_t rotr(uint16_t value, bitcount_t rot)
{
asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
inline uint32_t rotr(uint32_t value, bitcount_t rot)
{
asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
#if __x86_64__
inline uint64_t rotr(uint64_t value, bitcount_t rot)
{
asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
#endif // __x86_64__
#endif // PCG_USE_INLINE_ASM
/*
* The C++ SeedSeq concept (modelled by seed_seq) can fill an array of
* 32-bit integers with seed data, but sometimes we want to produce
* larger or smaller integers.
*
* The following code handles this annoyance.
*
* uneven_copy will copy an array of 32-bit ints to an array of larger or
* smaller ints (actually, the code is general it only needing forward
* iterators). The copy is identical to the one that would be performed if
* we just did memcpy on a standard little-endian machine, but works
* regardless of the endian of the machine (or the weirdness of the ints
* involved).
*
* generate_to initializes an array of integers using a SeedSeq
* object. It is given the size as a static constant at compile time and
* tries to avoid memory allocation. If we're filling in 32-bit constants
* we just do it directly. If we need a separate buffer and it's small,
* we allocate it on the stack. Otherwise, we fall back to heap allocation.
* Ugh.
*
* generate_one produces a single value of some integral type using a
* SeedSeq object.
*/
/* uneven_copy helper, case where destination ints are less than 32 bit. */
template<class SrcIter, class DestIter>
SrcIter uneven_copy_impl(
SrcIter src_first, DestIter dest_first, DestIter dest_last,
std::true_type)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bitcount_t SRC_SIZE = sizeof(src_t);
constexpr bitcount_t DEST_SIZE = sizeof(dest_t);
constexpr bitcount_t DEST_BITS = DEST_SIZE * 8;
constexpr bitcount_t SCALE = SRC_SIZE / DEST_SIZE;
size_t count = 0;
src_t value = 0;
while (dest_first != dest_last) {
if ((count++ % SCALE) == 0)
value = *src_first++; // Get more bits
else
value >>= DEST_BITS; // Move down bits
*dest_first++ = dest_t(value); // Truncates, ignores high bits.
}
return src_first;
}
/* uneven_copy helper, case where destination ints are more than 32 bit. */
template<class SrcIter, class DestIter>
SrcIter uneven_copy_impl(
SrcIter src_first, DestIter dest_first, DestIter dest_last,
std::false_type)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr auto SRC_SIZE = sizeof(src_t);
constexpr auto SRC_BITS = SRC_SIZE * 8;
constexpr auto DEST_SIZE = sizeof(dest_t);
constexpr auto SCALE = (DEST_SIZE+SRC_SIZE-1) / SRC_SIZE;
while (dest_first != dest_last) {
dest_t value(0UL);
unsigned int shift = 0;
for (size_t i = 0; i < SCALE; ++i) {
value |= dest_t(*src_first++) << shift;
shift += SRC_BITS;
}
*dest_first++ = value;
}
return src_first;
}
/* uneven_copy, call the right code for larger vs. smaller */
template<class SrcIter, class DestIter>
inline SrcIter uneven_copy(SrcIter src_first,
DestIter dest_first, DestIter dest_last)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bool DEST_IS_SMALLER = sizeof(dest_t) < sizeof(src_t);
return uneven_copy_impl(src_first, dest_first, dest_last,
std::integral_constant<bool, DEST_IS_SMALLER>{});
}
/* generate_to, fill in a fixed-size array of integral type using a SeedSeq
* (actually works for any random-access iterator)
*/
template <size_t size, typename SeedSeq, typename DestIter>
inline void generate_to_impl(SeedSeq&& generator, DestIter dest,
std::true_type)
{
generator.generate(dest, dest+size);
}
template <size_t size, typename SeedSeq, typename DestIter>
void generate_to_impl(SeedSeq&& generator, DestIter dest,
std::false_type)
{
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr auto DEST_SIZE = sizeof(dest_t);
constexpr auto GEN_SIZE = sizeof(uint32_t);
constexpr bool GEN_IS_SMALLER = GEN_SIZE < DEST_SIZE;
constexpr size_t FROM_ELEMS =
GEN_IS_SMALLER
? size * ((DEST_SIZE+GEN_SIZE-1) / GEN_SIZE)
: (size + (GEN_SIZE / DEST_SIZE) - 1)
/ ((GEN_SIZE / DEST_SIZE) + GEN_IS_SMALLER);
// this odd code ^^^^^^^^^^^^^^^^^ is work-around for
// a bug: http://llvm.org/bugs/show_bug.cgi?id=21287
if (FROM_ELEMS <= 1024) {
uint32_t buffer[FROM_ELEMS];
generator.generate(buffer, buffer+FROM_ELEMS);
uneven_copy(buffer, dest, dest+size);
} else {
uint32_t* buffer = static_cast<uint32_t*>(malloc(GEN_SIZE * FROM_ELEMS));
generator.generate(buffer, buffer+FROM_ELEMS);
uneven_copy(buffer, dest, dest+size);
free(static_cast<void*>(buffer));
}
}
template <size_t size, typename SeedSeq, typename DestIter>
inline void generate_to(SeedSeq&& generator, DestIter dest)
{
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bool IS_32BIT = sizeof(dest_t) == sizeof(uint32_t);
generate_to_impl<size>(std::forward<SeedSeq>(generator), dest,
std::integral_constant<bool, IS_32BIT>{});
}
/* generate_one, produce a value of integral type using a SeedSeq
* (optionally, we can have it produce more than one and pick which one
* we want)
*/
template <typename UInt, size_t i = 0UL, size_t N = i+1UL, typename SeedSeq>
inline UInt generate_one(SeedSeq&& generator)
{
UInt result[N];
generate_to<N>(std::forward<SeedSeq>(generator), result);
return result[i];
}
template <typename RngType>
auto bounded_rand(RngType& rng, typename RngType::result_type upper_bound)
-> typename RngType::result_type
{
typedef typename RngType::result_type rtype;
rtype threshold = (RngType::max() - RngType::min() + rtype(1) - upper_bound)
% upper_bound;
for (;;) {
rtype r = rng() - RngType::min();
if (r >= threshold)
return r % upper_bound;
}
}
template <typename Iter, typename RandType>
void shuffle(Iter from, Iter to, RandType&& rng)
{
typedef typename std::iterator_traits<Iter>::difference_type delta_t;
typedef typename std::remove_reference<RandType>::type::result_type result_t;
auto count = to - from;
while (count > 1) {
delta_t chosen = delta_t(bounded_rand(rng, result_t(count)));
--count;
--to;
using std::swap;
swap(*(from + chosen), *to);
}
}
/*
* Although std::seed_seq is useful, it isn't everything. Often we want to
* initialize a random-number generator some other way, such as from a random
* device.
*
* Technically, it does not meet the requirements of a SeedSequence because
* it lacks some of the rarely-used member functions (some of which would
* be impossible to provide). However the C++ standard is quite specific
* that actual engines only called the generate method, so it ought not to be
* a problem in practice.
*/
template <typename RngType>
class seed_seq_from {
private:
RngType rng_;
typedef uint_least32_t result_type;
public:
template<typename... Args>
seed_seq_from(Args&&... args) :
rng_(std::forward<Args>(args)...)
{
// Nothing (else) to do...
}
template<typename Iter>
void generate(Iter start, Iter finish)
{
for (auto i = start; i != finish; ++i)
*i = result_type(rng_());
}
constexpr size_t size() const
{
return (sizeof(typename RngType::result_type) > sizeof(result_type)
&& RngType::max() > ~size_t(0UL))
? ~size_t(0UL)
: size_t(RngType::max());
}
};
// Sometimes, when debugging or testing, it's handy to be able print the name
// of a (in human-readable form). This code allows the idiom:
//
// cout << printable_typename<my_foo_type_t>()
//
// to print out my_foo_type_t (or its concrete type if it is a synonym)
#if __cpp_rtti || __GXX_RTTI
template <typename T>
struct printable_typename {};
template <typename T>
std::ostream& operator<<(std::ostream& out, printable_typename<T>) {
const char *implementation_typename = typeid(T).name();
#ifdef __GNUC__
int status;
char* pretty_name =
abi::__cxa_demangle(implementation_typename, NULL, NULL, &status);
if (status == 0)
out << pretty_name;
free(static_cast<void*>(pretty_name));
if (status == 0)
return out;
#endif
out << implementation_typename;
return out;
}
#endif // __cpp_rtti || __GXX_RTTI
} // namespace pcg_extras
#endif // PCG_EXTRAS_HPP_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,748 @@
/*
* PCG Random Number Generation for C++
*
* Copyright 2014-2017 Melissa O'Neill <oneill@pcg-random.org>,
* and the PCG Project contributors.
*
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
*
* Licensed under the Apache License, Version 2.0 (provided in
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
* or under the MIT license (provided in LICENSE-MIT.txt and at
* http://opensource.org/licenses/MIT), at your option. This file may not
* be copied, modified, or distributed except according to those terms.
*
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See your chosen license for details.
*
* For additional information about the PCG random number generation scheme,
* visit http://www.pcg-random.org/.
*/
/*
* This code provides a a C++ class that can provide 128-bit (or higher)
* integers. To produce 2K-bit integers, it uses two K-bit integers,
* placed in a union that allowes the code to also see them as four K/2 bit
* integers (and access them either directly name, or by index).
*
* It may seem like we're reinventing the wheel here, because several
* libraries already exist that support large integers, but most existing
* libraries provide a very generic multiprecision code, but here we're
* operating at a fixed size. Also, most other libraries are fairly
* heavyweight. So we use a direct implementation. Sadly, it's much slower
* than hand-coded assembly or direct CPU support.
*/
#ifndef PCG_UINT128_HPP_INCLUDED
#define PCG_UINT128_HPP_INCLUDED 1
#include <cstdint>
#include <cstdio>
#include <cassert>
#include <climits>
#include <utility>
#include <initializer_list>
#include <type_traits>
/*
* We want to lay the type out the same way that a native type would be laid
* out, which means we must know the machine's endian, at compile time.
* This ugliness attempts to do so.
*/
#ifndef PCG_LITTLE_ENDIAN
#if defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define PCG_LITTLE_ENDIAN 1
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define PCG_LITTLE_ENDIAN 0
#else
#error __BYTE_ORDER__ does not match a standard endian, pick a side
#endif
#elif __LITTLE_ENDIAN__ || _LITTLE_ENDIAN
#define PCG_LITTLE_ENDIAN 1
#elif __BIG_ENDIAN__ || _BIG_ENDIAN
#define PCG_LITTLE_ENDIAN 0
#elif __x86_64 || __x86_64__ || _M_X64 || __i386 || __i386__ || _M_IX86
#define PCG_LITTLE_ENDIAN 1
#elif __powerpc__ || __POWERPC__ || __ppc__ || __PPC__ \
|| __m68k__ || __mc68000__
#define PCG_LITTLE_ENDIAN 0
#else
#error Unable to determine target endianness
#endif
#endif
namespace pcg_extras {
// Recent versions of GCC have intrinsics we can use to quickly calculate
// the number of leading and trailing zeros in a number. If possible, we
// use them, otherwise we fall back to old-fashioned bit twiddling to figure
// them out.
#ifndef PCG_BITCOUNT_T
typedef uint8_t bitcount_t;
#else
typedef PCG_BITCOUNT_T bitcount_t;
#endif
/*
* Provide some useful helper functions
* * flog2 floor(log2(x))
* * trailingzeros number of trailing zero bits
*/
#ifdef __GNUC__ // Any GNU-compatible compiler supporting C++11 has
// some useful intrinsics we can use.
inline bitcount_t flog2(uint32_t v)
{
return 31 - __builtin_clz(v);
}
inline bitcount_t trailingzeros(uint32_t v)
{
return __builtin_ctz(v);
}
inline bitcount_t flog2(uint64_t v)
{
#if UINT64_MAX == ULONG_MAX
return 63 - __builtin_clzl(v);
#elif UINT64_MAX == ULLONG_MAX
return 63 - __builtin_clzll(v);
#else
#error Cannot find a function for uint64_t
#endif
}
inline bitcount_t trailingzeros(uint64_t v)
{
#if UINT64_MAX == ULONG_MAX
return __builtin_ctzl(v);
#elif UINT64_MAX == ULLONG_MAX
return __builtin_ctzll(v);
#else
#error Cannot find a function for uint64_t
#endif
}
#else // Otherwise, we fall back to bit twiddling
// implementations
inline bitcount_t flog2(uint32_t v)
{
// Based on code by Eric Cole and Mark Dickinson, which appears at
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
static const uint8_t multiplyDeBruijnBitPos[32] = {
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return multiplyDeBruijnBitPos[(uint32_t)(v * 0x07C4ACDDU) >> 27];
}
inline bitcount_t trailingzeros(uint32_t v)
{
static const uint8_t multiplyDeBruijnBitPos[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return multiplyDeBruijnBitPos[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
}
inline bitcount_t flog2(uint64_t v)
{
uint32_t high = v >> 32;
uint32_t low = uint32_t(v);
return high ? 32+flog2(high) : flog2(low);
}
inline bitcount_t trailingzeros(uint64_t v)
{
uint32_t high = v >> 32;
uint32_t low = uint32_t(v);
return low ? trailingzeros(low) : trailingzeros(high)+32;
}
#endif
template <typename UInt>
inline bitcount_t clog2(UInt v)
{
return flog2(v) + ((v & (-v)) != v);
}
template <typename UInt>
inline UInt addwithcarry(UInt x, UInt y, bool carryin, bool* carryout)
{
UInt half_result = y + carryin;
UInt result = x + half_result;
*carryout = (half_result < y) || (result < x);
return result;
}
template <typename UInt>
inline UInt subwithcarry(UInt x, UInt y, bool carryin, bool* carryout)
{
UInt half_result = y + carryin;
UInt result = x - half_result;
*carryout = (half_result < y) || (result > x);
return result;
}
template <typename UInt, typename UIntX2>
class uint_x4 {
// private:
public:
union {
#if PCG_LITTLE_ENDIAN
struct {
UInt v0, v1, v2, v3;
} w;
struct {
UIntX2 v01, v23;
} d;
#else
struct {
UInt v3, v2, v1, v0;
} w;
struct {
UIntX2 v23, v01;
} d;
#endif
// For the array access versions, the code that uses the array
// must handle endian itself. Yuck.
UInt wa[4];
UIntX2 da[2];
};
public:
uint_x4() = default;
constexpr uint_x4(UInt v3, UInt v2, UInt v1, UInt v0)
#if PCG_LITTLE_ENDIAN
: w{v0, v1, v2, v3}
#else
: w{v3, v2, v1, v0}
#endif
{
// Nothing (else) to do
}
constexpr uint_x4(UIntX2 v23, UIntX2 v01)
#if PCG_LITTLE_ENDIAN
: d{v01,v23}
#else
: d{v23,v01}
#endif
{
// Nothing (else) to do
}
template<class Integral,
typename std::enable_if<(std::is_integral<Integral>::value
&& sizeof(Integral) <= sizeof(UIntX2))
>::type* = nullptr>
constexpr uint_x4(Integral v01)
#if PCG_LITTLE_ENDIAN
: d{UIntX2(v01),0UL}
#else
: d{0UL,UIntX2(v01)}
#endif
{
// Nothing (else) to do
}
explicit constexpr operator uint64_t() const
{
return d.v01;
}
explicit constexpr operator uint32_t() const
{
return w.v0;
}
explicit constexpr operator int() const
{
return w.v0;
}
explicit constexpr operator uint16_t() const
{
return w.v0;
}
explicit constexpr operator uint8_t() const
{
return w.v0;
}
typedef typename std::conditional<std::is_same<uint64_t,
unsigned long>::value,
unsigned long long,
unsigned long>::type
uint_missing_t;
explicit constexpr operator uint_missing_t() const
{
return d.v01;
}
explicit constexpr operator bool() const
{
return d.v01 || d.v23;
}
template<typename U, typename V>
friend uint_x4<U,V> operator*(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend std::pair< uint_x4<U,V>,uint_x4<U,V> >
divmod(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator+(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator-(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator<<(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator>>(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator&(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator|(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator^(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator==(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator!=(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator<(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator<=(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator>(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend bool operator>=(const uint_x4<U,V>&, const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator~(const uint_x4<U,V>&);
template<typename U, typename V>
friend uint_x4<U,V> operator-(const uint_x4<U,V>&);
template<typename U, typename V>
friend bitcount_t flog2(const uint_x4<U,V>&);
template<typename U, typename V>
friend bitcount_t trailingzeros(const uint_x4<U,V>&);
uint_x4& operator*=(const uint_x4& rhs)
{
uint_x4 result = *this * rhs;
return *this = result;
}
uint_x4& operator/=(const uint_x4& rhs)
{
uint_x4 result = *this / rhs;
return *this = result;
}
uint_x4& operator%=(const uint_x4& rhs)
{
uint_x4 result = *this % rhs;
return *this = result;
}
uint_x4& operator+=(const uint_x4& rhs)
{
uint_x4 result = *this + rhs;
return *this = result;
}
uint_x4& operator-=(const uint_x4& rhs)
{
uint_x4 result = *this - rhs;
return *this = result;
}
uint_x4& operator&=(const uint_x4& rhs)
{
uint_x4 result = *this & rhs;
return *this = result;
}
uint_x4& operator|=(const uint_x4& rhs)
{
uint_x4 result = *this | rhs;
return *this = result;
}
uint_x4& operator^=(const uint_x4& rhs)
{
uint_x4 result = *this ^ rhs;
return *this = result;
}
uint_x4& operator>>=(bitcount_t shift)
{
uint_x4 result = *this >> shift;
return *this = result;
}
uint_x4& operator<<=(bitcount_t shift)
{
uint_x4 result = *this << shift;
return *this = result;
}
};
template<typename U, typename V>
bitcount_t flog2(const uint_x4<U,V>& v)
{
#if PCG_LITTLE_ENDIAN
for (uint8_t i = 4; i !=0; /* dec in loop */) {
--i;
#else
for (uint8_t i = 0; i < 4; ++i) {
#endif
if (v.wa[i] == 0)
continue;
return flog2(v.wa[i]) + (sizeof(U)*CHAR_BIT)*i;
}
abort();
}
template<typename U, typename V>
bitcount_t trailingzeros(const uint_x4<U,V>& v)
{
#if PCG_LITTLE_ENDIAN
for (uint8_t i = 0; i < 4; ++i) {
#else
for (uint8_t i = 4; i !=0; /* dec in loop */) {
--i;
#endif
if (v.wa[i] != 0)
return trailingzeros(v.wa[i]) + (sizeof(U)*CHAR_BIT)*i;
}
return (sizeof(U)*CHAR_BIT)*4;
}
template <typename UInt, typename UIntX2>
std::pair< uint_x4<UInt,UIntX2>, uint_x4<UInt,UIntX2> >
divmod(const uint_x4<UInt,UIntX2>& orig_dividend,
const uint_x4<UInt,UIntX2>& divisor)
{
// If the dividend is less than the divisor, the answer is always zero.
// This takes care of boundary cases like 0/x (which would otherwise be
// problematic because we can't take the log of zero. (The boundary case
// of division by zero is undefined.)
if (orig_dividend < divisor)
return { uint_x4<UInt,UIntX2>(0UL), orig_dividend };
auto dividend = orig_dividend;
auto log2_divisor = flog2(divisor);
auto log2_dividend = flog2(dividend);
// assert(log2_dividend >= log2_divisor);
bitcount_t logdiff = log2_dividend - log2_divisor;
constexpr uint_x4<UInt,UIntX2> ONE(1UL);
if (logdiff == 0)
return { ONE, dividend - divisor };
// Now we change the log difference to
// floor(log2(divisor)) - ceil(log2(dividend))
// to ensure that we *underestimate* the result.
logdiff -= 1;
uint_x4<UInt,UIntX2> quotient(0UL);
auto qfactor = ONE << logdiff;
auto factor = divisor << logdiff;
do {
dividend -= factor;
quotient += qfactor;
while (dividend < factor) {
factor >>= 1;
qfactor >>= 1;
}
} while (dividend >= divisor);
return { quotient, dividend };
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator/(const uint_x4<UInt,UIntX2>& dividend,
const uint_x4<UInt,UIntX2>& divisor)
{
return divmod(dividend, divisor).first;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator%(const uint_x4<UInt,UIntX2>& dividend,
const uint_x4<UInt,UIntX2>& divisor)
{
return divmod(dividend, divisor).second;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator*(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
uint_x4<UInt,UIntX2> r = {0U, 0U, 0U, 0U};
bool carryin = false;
bool carryout;
UIntX2 a0b0 = UIntX2(a.w.v0) * UIntX2(b.w.v0);
r.w.v0 = UInt(a0b0);
r.w.v1 = UInt(a0b0 >> 32);
UIntX2 a1b0 = UIntX2(a.w.v1) * UIntX2(b.w.v0);
r.w.v2 = UInt(a1b0 >> 32);
r.w.v1 = addwithcarry(r.w.v1, UInt(a1b0), carryin, &carryout);
carryin = carryout;
r.w.v2 = addwithcarry(r.w.v2, UInt(0U), carryin, &carryout);
carryin = carryout;
r.w.v3 = addwithcarry(r.w.v3, UInt(0U), carryin, &carryout);
UIntX2 a0b1 = UIntX2(a.w.v0) * UIntX2(b.w.v1);
carryin = false;
r.w.v2 = addwithcarry(r.w.v2, UInt(a0b1 >> 32), carryin, &carryout);
carryin = carryout;
r.w.v3 = addwithcarry(r.w.v3, UInt(0U), carryin, &carryout);
carryin = false;
r.w.v1 = addwithcarry(r.w.v1, UInt(a0b1), carryin, &carryout);
carryin = carryout;
r.w.v2 = addwithcarry(r.w.v2, UInt(0U), carryin, &carryout);
carryin = carryout;
r.w.v3 = addwithcarry(r.w.v3, UInt(0U), carryin, &carryout);
UIntX2 a1b1 = UIntX2(a.w.v1) * UIntX2(b.w.v1);
carryin = false;
r.w.v2 = addwithcarry(r.w.v2, UInt(a1b1), carryin, &carryout);
carryin = carryout;
r.w.v3 = addwithcarry(r.w.v3, UInt(a1b1 >> 32), carryin, &carryout);
r.d.v23 += a.d.v01 * b.d.v23 + a.d.v23 * b.d.v01;
return r;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator+(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
uint_x4<UInt,UIntX2> r = {0U, 0U, 0U, 0U};
bool carryin = false;
bool carryout;
r.w.v0 = addwithcarry(a.w.v0, b.w.v0, carryin, &carryout);
carryin = carryout;
r.w.v1 = addwithcarry(a.w.v1, b.w.v1, carryin, &carryout);
carryin = carryout;
r.w.v2 = addwithcarry(a.w.v2, b.w.v2, carryin, &carryout);
carryin = carryout;
r.w.v3 = addwithcarry(a.w.v3, b.w.v3, carryin, &carryout);
return r;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator-(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
uint_x4<UInt,UIntX2> r = {0U, 0U, 0U, 0U};
bool carryin = false;
bool carryout;
r.w.v0 = subwithcarry(a.w.v0, b.w.v0, carryin, &carryout);
carryin = carryout;
r.w.v1 = subwithcarry(a.w.v1, b.w.v1, carryin, &carryout);
carryin = carryout;
r.w.v2 = subwithcarry(a.w.v2, b.w.v2, carryin, &carryout);
carryin = carryout;
r.w.v3 = subwithcarry(a.w.v3, b.w.v3, carryin, &carryout);
return r;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator&(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
return uint_x4<UInt,UIntX2>(a.d.v23 & b.d.v23, a.d.v01 & b.d.v01);
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator|(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
return uint_x4<UInt,UIntX2>(a.d.v23 | b.d.v23, a.d.v01 | b.d.v01);
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator^(const uint_x4<UInt,UIntX2>& a,
const uint_x4<UInt,UIntX2>& b)
{
return uint_x4<UInt,UIntX2>(a.d.v23 ^ b.d.v23, a.d.v01 ^ b.d.v01);
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator~(const uint_x4<UInt,UIntX2>& v)
{
return uint_x4<UInt,UIntX2>(~v.d.v23, ~v.d.v01);
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator-(const uint_x4<UInt,UIntX2>& v)
{
return uint_x4<UInt,UIntX2>(0UL,0UL) - v;
}
template <typename UInt, typename UIntX2>
bool operator==(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return (a.d.v01 == b.d.v01) && (a.d.v23 == b.d.v23);
}
template <typename UInt, typename UIntX2>
bool operator!=(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return !operator==(a,b);
}
template <typename UInt, typename UIntX2>
bool operator<(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return (a.d.v23 < b.d.v23)
|| ((a.d.v23 == b.d.v23) && (a.d.v01 < b.d.v01));
}
template <typename UInt, typename UIntX2>
bool operator>(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return operator<(b,a);
}
template <typename UInt, typename UIntX2>
bool operator<=(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return !(operator<(b,a));
}
template <typename UInt, typename UIntX2>
bool operator>=(const uint_x4<UInt,UIntX2>& a, const uint_x4<UInt,UIntX2>& b)
{
return !(operator<(a,b));
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator<<(const uint_x4<UInt,UIntX2>& v,
const bitcount_t shift)
{
uint_x4<UInt,UIntX2> r = {0U, 0U, 0U, 0U};
const bitcount_t bits = sizeof(UInt) * CHAR_BIT;
const bitcount_t bitmask = bits - 1;
const bitcount_t shiftdiv = shift / bits;
const bitcount_t shiftmod = shift & bitmask;
if (shiftmod) {
UInt carryover = 0;
#if PCG_LITTLE_ENDIAN
for (uint8_t out = shiftdiv, in = 0; out < 4; ++out, ++in) {
#else
for (uint8_t out = 4-shiftdiv, in = 4; out != 0; /* dec in loop */) {
--out, --in;
#endif
r.wa[out] = (v.wa[in] << shiftmod) | carryover;
carryover = (v.wa[in] >> (bits - shiftmod));
}
} else {
#if PCG_LITTLE_ENDIAN
for (uint8_t out = shiftdiv, in = 0; out < 4; ++out, ++in) {
#else
for (uint8_t out = 4-shiftdiv, in = 4; out != 0; /* dec in loop */) {
--out, --in;
#endif
r.wa[out] = v.wa[in];
}
}
return r;
}
template <typename UInt, typename UIntX2>
uint_x4<UInt,UIntX2> operator>>(const uint_x4<UInt,UIntX2>& v,
const bitcount_t shift)
{
uint_x4<UInt,UIntX2> r = {0U, 0U, 0U, 0U};
const bitcount_t bits = sizeof(UInt) * CHAR_BIT;
const bitcount_t bitmask = bits - 1;
const bitcount_t shiftdiv = shift / bits;
const bitcount_t shiftmod = shift & bitmask;
if (shiftmod) {
UInt carryover = 0;
#if PCG_LITTLE_ENDIAN
for (uint8_t out = 4-shiftdiv, in = 4; out != 0; /* dec in loop */) {
--out, --in;
#else
for (uint8_t out = shiftdiv, in = 0; out < 4; ++out, ++in) {
#endif
r.wa[out] = (v.wa[in] >> shiftmod) | carryover;
carryover = (v.wa[in] << (bits - shiftmod));
}
} else {
#if PCG_LITTLE_ENDIAN
for (uint8_t out = 4-shiftdiv, in = 4; out != 0; /* dec in loop */) {
--out, --in;
#else
for (uint8_t out = shiftdiv, in = 0; out < 4; ++out, ++in) {
#endif
r.wa[out] = v.wa[in];
}
}
return r;
}
} // namespace pcg_extras
#endif // PCG_UINT128_HPP_INCLUDED

View File

@ -34,7 +34,7 @@ class Foundation_API TraverseBase
{ {
public: public:
typedef std::stack<DirectoryIterator> Stack; typedef std::stack<DirectoryIterator> Stack;
typedef std::pointer_to_unary_function<const Stack&, UInt16> DepthFunPtr; typedef std::function<UInt16(const Stack&)> DepthFunPtr;
enum enum
{ {

View File

@ -45,6 +45,7 @@
#endif #endif
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <atomic>
namespace Poco { namespace Poco {
@ -381,7 +382,7 @@ public:
private: private:
int _fd; int _fd;
bool _stopped; std::atomic<bool> _stopped;
}; };
@ -464,7 +465,7 @@ public:
private: private:
int _queueFD; int _queueFD;
int _dirFD; int _dirFD;
bool _stopped; std::atomic<bool> _stopped;
}; };

View File

@ -79,7 +79,7 @@ inline std::string Element::name() const
class ElementComparator class ElementComparator
{ {
public: public:
bool operator()(const Element::Ptr& s1, const Element::Ptr& s2) bool operator()(const Element::Ptr& s1, const Element::Ptr& s2) const
{ {
return s1->name() < s2->name(); return s1->name() < s2->name();
} }

View File

@ -27,6 +27,8 @@
#include "Poco/Net/HTTPServerParams.h" #include "Poco/Net/HTTPServerParams.h"
#include "Poco/Mutex.h" #include "Poco/Mutex.h"
#include <atomic>
namespace Poco { namespace Poco {
namespace Net { namespace Net {
@ -56,7 +58,7 @@ protected:
private: private:
HTTPServerParams::Ptr _pParams; HTTPServerParams::Ptr _pParams;
HTTPRequestHandlerFactory::Ptr _pFactory; HTTPRequestHandlerFactory::Ptr _pFactory;
bool _stopped; std::atomic<bool> _stopped;
Poco::FastMutex _mutex; Poco::FastMutex _mutex;
}; };

View File

@ -28,6 +28,8 @@
#include "Poco/Thread.h" #include "Poco/Thread.h"
#include "Poco/ThreadPool.h" #include "Poco/ThreadPool.h"
#include <atomic>
namespace Poco { namespace Poco {
namespace Net { namespace Net {
@ -184,7 +186,7 @@ private:
ServerSocket _socket; ServerSocket _socket;
TCPServerDispatcher* _pDispatcher; TCPServerDispatcher* _pDispatcher;
Poco::Thread _thread; Poco::Thread _thread;
bool _stopped; std::atomic<bool> _stopped;
}; };

View File

@ -29,6 +29,8 @@
#include "Poco/ThreadPool.h" #include "Poco/ThreadPool.h"
#include "Poco/Mutex.h" #include "Poco/Mutex.h"
#include <atomic>
namespace Poco { namespace Poco {
namespace Net { namespace Net {
@ -109,7 +111,7 @@ private:
int _currentConnections; int _currentConnections;
int _maxConcurrentConnections; int _maxConcurrentConnections;
int _refusedConnections; int _refusedConnections;
bool _stopped; std::atomic<bool> _stopped;
Poco::NotificationQueue _queue; Poco::NotificationQueue _queue;
TCPServerConnectionFactory::Ptr _pConnectionFactory; TCPServerConnectionFactory::Ptr _pConnectionFactory;
Poco::ThreadPool& _threadPool; Poco::ThreadPool& _threadPool;

View File

@ -80,9 +80,9 @@ extern "C" {
* bitStream encoding API (write forward) * bitStream encoding API (write forward)
********************************************/ ********************************************/
/* bitStream can mix input from multiple sources. /* bitStream can mix input from multiple sources.
* A critical property of these streams is that they encode and decode in **reverse** direction. * A critical property of these streams is that they encode and decode in **reverse** direction.
* So the first bit sequence you add will be the last to be read, like a LIFO stack. * So the first bit sequence you add will be the last to be read, like a LIFO stack.
*/ */
typedef struct typedef struct
{ {
size_t bitContainer; size_t bitContainer;
@ -203,7 +203,7 @@ static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F,
/*! BIT_initCStream() : /*! BIT_initCStream() :
* `dstCapacity` must be > sizeof(size_t) * `dstCapacity` must be > sizeof(size_t)
* @return : 0 if success, * @return : 0 if success,
otherwise an error code (can be tested using ERR_isError() ) */ * otherwise an error code (can be tested using ERR_isError()) */
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
void* startPtr, size_t dstCapacity) void* startPtr, size_t dstCapacity)
{ {
@ -217,8 +217,8 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
} }
/*! BIT_addBits() : /*! BIT_addBits() :
can add up to 26 bits into `bitC`. * can add up to 26 bits into `bitC`.
Does not check for register overflow ! */ * Note : does not check for register overflow ! */
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
size_t value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
@ -268,7 +268,7 @@ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
/*! BIT_closeCStream() : /*! BIT_closeCStream() :
* @return : size of CStream, in bytes, * @return : size of CStream, in bytes,
or 0 if it could not fit into dstBuffer */ * or 0 if it could not fit into dstBuffer */
MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
{ {
BIT_addBitsFast(bitC, 1, 1); /* endMark */ BIT_addBitsFast(bitC, 1, 1); /* endMark */
@ -282,11 +282,11 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
* bitStream decoding * bitStream decoding
**********************************************************/ **********************************************************/
/*! BIT_initDStream() : /*! BIT_initDStream() :
* Initialize a BIT_DStream_t. * Initialize a BIT_DStream_t.
* `bitD` : a pointer to an already allocated BIT_DStream_t structure. * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
* `srcSize` must be the *exact* size of the bitStream, in bytes. * `srcSize` must be the *exact* size of the bitStream, in bytes.
* @return : size of stream (== srcSize) or an errorCode if a problem is detected * @return : size of stream (== srcSize), or an errorCode if a problem is detected
*/ */
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
{ {
if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
@ -327,7 +327,8 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
} }
{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
}
bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
} }
@ -363,9 +364,8 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
* local register is not modified. * local register is not modified.
* On 32-bits, maxNbBits==24. * On 32-bits, maxNbBits==24.
* On 64-bits, maxNbBits==56. * On 64-bits, maxNbBits==56.
* @return : value extracted * @return : value extracted */
*/ MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{ {
#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */ #if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
@ -392,8 +392,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
/*! BIT_readBits() : /*! BIT_readBits() :
* Read (consume) next n bits from local register and update. * Read (consume) next n bits from local register and update.
* Pay attention to not read more than nbBits contained into local register. * Pay attention to not read more than nbBits contained into local register.
* @return : extracted value. * @return : extracted value. */
*/
MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBits(bitD, nbBits); size_t const value = BIT_lookBits(bitD, nbBits);
@ -402,7 +401,7 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
} }
/*! BIT_readBitsFast() : /*! BIT_readBitsFast() :
* unsafe version; only works only if nbBits >= 1 */ * unsafe version; only works only if nbBits >= 1 */
MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
{ {
size_t const value = BIT_lookBitsFast(bitD, nbBits); size_t const value = BIT_lookBitsFast(bitD, nbBits);
@ -412,10 +411,10 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
} }
/*! BIT_reloadDStream() : /*! BIT_reloadDStream() :
* Refill `bitD` from buffer previously set in BIT_initDStream() . * Refill `bitD` from buffer previously set in BIT_initDStream() .
* This function is safe, it guarantees it will not read beyond src buffer. * This function is safe, it guarantees it will not read beyond src buffer.
* @return : status of `BIT_DStream_t` internal register. * @return : status of `BIT_DStream_t` internal register.
if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
{ {
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
@ -446,8 +445,8 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
} }
/*! BIT_endOfDStream() : /*! BIT_endOfDStream() :
* @return Tells if DStream has exactly reached its end (all bits consumed). * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
*/ */
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
{ {
return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
*/
#ifndef ZSTD_COMPILER_H
#define ZSTD_COMPILER_H
/*-*******************************************************
* Compiler specifics
*********************************************************/
/* force inlining */
#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# define INLINE_KEYWORD inline
#else
# define INLINE_KEYWORD
#endif
#if defined(__GNUC__)
# define FORCE_INLINE_ATTR __attribute__((always_inline))
#elif defined(_MSC_VER)
# define FORCE_INLINE_ATTR __forceinline
#else
# define FORCE_INLINE_ATTR
#endif
/**
* FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
* parameters. They must be inlined for the compiler to elimininate the constant
* branches.
*/
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
/**
* HINT_INLINE is used to help the compiler generate better code. It is *not*
* used for "templates", so it can be tweaked based on the compilers
* performance.
*
* gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the
* always_inline attribute.
*
* clang up to 5.0.0 (trunk) benefit tremendously from the always_inline
* attribute.
*/
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
# define HINT_INLINE static INLINE_KEYWORD
#else
# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
#endif
/* force no inlining */
#ifdef _MSC_VER
# define FORCE_NOINLINE static __declspec(noinline)
#else
# ifdef __GNUC__
# define FORCE_NOINLINE static __attribute__((__noinline__))
# else
# define FORCE_NOINLINE static
# endif
#endif
/* prefetch */
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
# define PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0)
#elif defined(__GNUC__)
# define PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
#else
# define PREFETCH(ptr) /* disabled */
#endif
/* disable warnings */
#ifdef _MSC_VER /* Visual Studio */
# include <intrin.h> /* For Visual 2005 */
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
#endif
#endif /* ZSTD_COMPILER_H */

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
/* The purpose of this file is to have a single list of error strings embedded in binary */ /* The purpose of this file is to have a single list of error strings embedded in binary */
@ -20,19 +20,17 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(GENERIC): return "Error (generic)"; case PREFIX(GENERIC): return "Error (generic)";
case PREFIX(prefix_unknown): return "Unknown frame descriptor"; case PREFIX(prefix_unknown): return "Unknown frame descriptor";
case PREFIX(version_unsupported): return "Version not supported"; case PREFIX(version_unsupported): return "Version not supported";
case PREFIX(parameter_unknown): return "Unknown parameter type";
case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode";
case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
case PREFIX(compressionParameter_unsupported): return "Compression parameter is not supported"; case PREFIX(corruption_detected): return "Corrupted block detected";
case PREFIX(compressionParameter_outOfBound): return "Compression parameter is out of bound"; case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
case PREFIX(parameter_unsupported): return "Unsupported parameter";
case PREFIX(parameter_outOfBound): return "Parameter is out of bound";
case PREFIX(init_missing): return "Context should be init first"; case PREFIX(init_missing): return "Context should be init first";
case PREFIX(memory_allocation): return "Allocation error : not enough memory"; case PREFIX(memory_allocation): return "Allocation error : not enough memory";
case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
case PREFIX(srcSize_wrong): return "Src size is incorrect"; case PREFIX(srcSize_wrong): return "Src size is incorrect";
case PREFIX(corruption_detected): return "Corrupted block detected";
case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
/* Note : this module is expected to remain private, do not expose it */ /* Note : this module is expected to remain private, do not expose it */

View File

@ -31,13 +31,14 @@
You can contact the author at : You can contact the author at :
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
****************************************************************** */ ****************************************************************** */
#ifndef FSE_H
#define FSE_H
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
#ifndef FSE_H
#define FSE_H
/*-***************************************** /*-*****************************************
* Dependencies * Dependencies
@ -297,8 +298,10 @@ FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<
If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)
*/ */
#endif /* FSE_H */
#ifdef FSE_STATIC_LINKING_ONLY #if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
#define FSE_H_FSE_STATIC_LINKING_ONLY
/* *** Dependency *** */ /* *** Dependency *** */
#include "bitstream.h" #include "bitstream.h"
@ -381,6 +384,11 @@ size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog); size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog);
/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */ /**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */
typedef enum {
FSE_repeat_none, /**< Cannot use the previous table */
FSE_repeat_check, /**< Can use the previous table but it must be checked */
FSE_repeat_valid /**< Can use the previous table and it is asumed to be valid */
} FSE_repeat;
/* ***************************************** /* *****************************************
* FSE symbol compression API * FSE symbol compression API
@ -694,5 +702,3 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* FSE_H */

View File

@ -33,35 +33,16 @@
****************************************************************** */ ****************************************************************** */
/* **************************************************************
* Compiler specifics
****************************************************************/
#ifdef _MSC_VER /* Visual Studio */
# define FORCE_INLINE static __forceinline
# include <intrin.h> /* For Visual 2005 */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
#else
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# ifdef __GNUC__
# define FORCE_INLINE static inline __attribute__((always_inline))
# else
# define FORCE_INLINE static inline
# endif
# else
# define FORCE_INLINE static
# endif /* __STDC_VERSION__ */
#endif
/* ************************************************************** /* **************************************************************
* Includes * Includes
****************************************************************/ ****************************************************************/
#include <stdlib.h> /* malloc, free, qsort */ #include <stdlib.h> /* malloc, free, qsort */
#include <string.h> /* memcpy, memset */ #include <string.h> /* memcpy, memset */
#include "bitstream.h" #include "bitstream.h"
#include "compiler.h"
#define FSE_STATIC_LINKING_ONLY #define FSE_STATIC_LINKING_ONLY
#include "fse.h" #include "fse.h"
#include "error_private.h"
/* ************************************************************** /* **************************************************************
@ -216,7 +197,7 @@ size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
return 0; return 0;
} }
FORCE_INLINE size_t FSE_decompress_usingDTable_generic( FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
void* dst, size_t maxDstSize, void* dst, size_t maxDstSize,
const void* cSrc, size_t cSrcSize, const void* cSrc, size_t cSrcSize,
const FSE_DTable* dt, const unsigned fast) const FSE_DTable* dt, const unsigned fast)

View File

@ -31,13 +31,13 @@
You can contact the author at : You can contact the author at :
- Source repository : https://github.com/Cyan4973/FiniteStateEntropy - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
****************************************************************** */ ****************************************************************** */
#ifndef HUF_H_298734234
#define HUF_H_298734234
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
#ifndef HUF_H_298734234
#define HUF_H_298734234
/* *** Dependencies *** */ /* *** Dependencies *** */
#include <stddef.h> /* size_t */ #include <stddef.h> /* size_t */
@ -124,6 +124,7 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const
#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) #define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10)
#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) #define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
#endif /* HUF_H_298734234 */
/* ****************************************************************** /* ******************************************************************
* WARNING !! * WARNING !!
@ -132,7 +133,8 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const
* because they are not guaranteed to remain stable in the future. * because they are not guaranteed to remain stable in the future.
* Only consider them in association with static linking. * Only consider them in association with static linking.
*******************************************************************/ *******************************************************************/
#ifdef HUF_STATIC_LINKING_ONLY #if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY)
#define HUF_H_HUF_STATIC_LINKING_ONLY
/* *** Dependencies *** */ /* *** Dependencies *** */
#include "mem.h" /* U32 */ #include "mem.h" /* U32 */
@ -295,9 +297,6 @@ size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* c
#endif /* HUF_STATIC_LINKING_ONLY */ #endif /* HUF_STATIC_LINKING_ONLY */
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* HUF_H_298734234 */

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
#ifndef MEM_H_MODULE #ifndef MEM_H_MODULE
@ -110,7 +110,7 @@ Only use if no other choice to achieve best performance on target platform */
MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
MEM_STATIC U64 MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
@ -131,7 +131,7 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
MEM_STATIC U64 MEM_readST(const void* ptr) { return ((const unalign*)ptr)->st; } MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalign*)ptr)->st; }
MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
@ -39,6 +39,12 @@ struct POOL_ctx_s {
size_t queueHead; size_t queueHead;
size_t queueTail; size_t queueTail;
size_t queueSize; size_t queueSize;
/* The number of threads working on jobs */
size_t numThreadsBusy;
/* Indicates if the queue is empty */
int queueEmpty;
/* The mutex protects the queue */ /* The mutex protects the queue */
pthread_mutex_t queueMutex; pthread_mutex_t queueMutex;
/* Condition variable for pushers to wait on when the queue is full */ /* Condition variable for pushers to wait on when the queue is full */
@ -60,30 +66,41 @@ static void* POOL_thread(void* opaque) {
for (;;) { for (;;) {
/* Lock the mutex and wait for a non-empty queue or until shutdown */ /* Lock the mutex and wait for a non-empty queue or until shutdown */
pthread_mutex_lock(&ctx->queueMutex); pthread_mutex_lock(&ctx->queueMutex);
while (ctx->queueHead == ctx->queueTail && !ctx->shutdown) {
while (ctx->queueEmpty && !ctx->shutdown) {
pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex); pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
} }
/* empty => shutting down: so stop */ /* empty => shutting down: so stop */
if (ctx->queueHead == ctx->queueTail) { if (ctx->queueEmpty) {
pthread_mutex_unlock(&ctx->queueMutex); pthread_mutex_unlock(&ctx->queueMutex);
return opaque; return opaque;
} }
/* Pop a job off the queue */ /* Pop a job off the queue */
{ POOL_job const job = ctx->queue[ctx->queueHead]; { POOL_job const job = ctx->queue[ctx->queueHead];
ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize; ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
ctx->numThreadsBusy++;
ctx->queueEmpty = ctx->queueHead == ctx->queueTail;
/* Unlock the mutex, signal a pusher, and run the job */ /* Unlock the mutex, signal a pusher, and run the job */
pthread_mutex_unlock(&ctx->queueMutex); pthread_mutex_unlock(&ctx->queueMutex);
pthread_cond_signal(&ctx->queuePushCond); pthread_cond_signal(&ctx->queuePushCond);
job.function(job.opaque); job.function(job.opaque);
}
} /* If the intended queue size was 0, signal after finishing job */
if (ctx->queueSize == 1) {
pthread_mutex_lock(&ctx->queueMutex);
ctx->numThreadsBusy--;
pthread_mutex_unlock(&ctx->queueMutex);
pthread_cond_signal(&ctx->queuePushCond);
} }
} /* for (;;) */
/* Unreachable */ /* Unreachable */
} }
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) { POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
POOL_ctx *ctx; POOL_ctx *ctx;
/* Check the parameters */ /* Check the parameters */
if (!numThreads || !queueSize) { return NULL; } if (!numThreads) { return NULL; }
/* Allocate the context and zero initialize */ /* Allocate the context and zero initialize */
ctx = (POOL_ctx *)calloc(1, sizeof(POOL_ctx)); ctx = (POOL_ctx *)calloc(1, sizeof(POOL_ctx));
if (!ctx) { return NULL; } if (!ctx) { return NULL; }
@ -92,15 +109,17 @@ POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
* and full queues. * and full queues.
*/ */
ctx->queueSize = queueSize + 1; ctx->queueSize = queueSize + 1;
ctx->queue = (POOL_job *)malloc(ctx->queueSize * sizeof(POOL_job)); ctx->queue = (POOL_job*) malloc(ctx->queueSize * sizeof(POOL_job));
ctx->queueHead = 0; ctx->queueHead = 0;
ctx->queueTail = 0; ctx->queueTail = 0;
pthread_mutex_init(&ctx->queueMutex, NULL); ctx->numThreadsBusy = 0;
pthread_cond_init(&ctx->queuePushCond, NULL); ctx->queueEmpty = 1;
pthread_cond_init(&ctx->queuePopCond, NULL); (void)pthread_mutex_init(&ctx->queueMutex, NULL);
(void)pthread_cond_init(&ctx->queuePushCond, NULL);
(void)pthread_cond_init(&ctx->queuePopCond, NULL);
ctx->shutdown = 0; ctx->shutdown = 0;
/* Allocate space for the thread handles */ /* Allocate space for the thread handles */
ctx->threads = (pthread_t *)malloc(numThreads * sizeof(pthread_t)); ctx->threads = (pthread_t*)malloc(numThreads * sizeof(pthread_t));
ctx->numThreads = 0; ctx->numThreads = 0;
/* Check for errors */ /* Check for errors */
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; } if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
@ -153,22 +172,37 @@ size_t POOL_sizeof(POOL_ctx *ctx) {
+ ctx->numThreads * sizeof(pthread_t); + ctx->numThreads * sizeof(pthread_t);
} }
void POOL_add(void *ctxVoid, POOL_function function, void *opaque) { /**
POOL_ctx *ctx = (POOL_ctx *)ctxVoid; * Returns 1 if the queue is full and 0 otherwise.
*
* If the queueSize is 1 (the pool was created with an intended queueSize of 0),
* then a queue is empty if there is a thread free and no job is waiting.
*/
static int isQueueFull(POOL_ctx const* ctx) {
if (ctx->queueSize > 1) {
return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
} else {
return ctx->numThreadsBusy == ctx->numThreads ||
!ctx->queueEmpty;
}
}
void POOL_add(void* ctxVoid, POOL_function function, void *opaque) {
POOL_ctx* const ctx = (POOL_ctx*)ctxVoid;
if (!ctx) { return; } if (!ctx) { return; }
pthread_mutex_lock(&ctx->queueMutex); pthread_mutex_lock(&ctx->queueMutex);
{ POOL_job const job = {function, opaque}; { POOL_job const job = {function, opaque};
/* Wait until there is space in the queue for the new job */ /* Wait until there is space in the queue for the new job */
size_t newTail = (ctx->queueTail + 1) % ctx->queueSize; while (isQueueFull(ctx) && !ctx->shutdown) {
while (ctx->queueHead == newTail && !ctx->shutdown) {
pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex); pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
newTail = (ctx->queueTail + 1) % ctx->queueSize;
} }
/* The queue is still going => there is space */ /* The queue is still going => there is space */
if (!ctx->shutdown) { if (!ctx->shutdown) {
ctx->queueEmpty = 0;
ctx->queue[ctx->queueTail] = job; ctx->queue[ctx->queueTail] = job;
ctx->queueTail = newTail; ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
} }
} }
pthread_mutex_unlock(&ctx->queueMutex); pthread_mutex_unlock(&ctx->queueMutex);
@ -183,22 +217,22 @@ struct POOL_ctx_s {
int data; int data;
}; };
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) { POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
(void)numThreads; (void)numThreads;
(void)queueSize; (void)queueSize;
return (POOL_ctx *)malloc(sizeof(POOL_ctx)); return (POOL_ctx*)malloc(sizeof(POOL_ctx));
} }
void POOL_free(POOL_ctx *ctx) { void POOL_free(POOL_ctx* ctx) {
if (ctx) free(ctx); free(ctx);
} }
void POOL_add(void *ctx, POOL_function function, void *opaque) { void POOL_add(void* ctx, POOL_function function, void* opaque) {
(void)ctx; (void)ctx;
function(opaque); function(opaque);
} }
size_t POOL_sizeof(POOL_ctx *ctx) { size_t POOL_sizeof(POOL_ctx* ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */ if (ctx==NULL) return 0; /* supports sizeof NULL */
return sizeof(*ctx); return sizeof(*ctx);
} }

View File

@ -1,11 +1,12 @@
/** /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
#ifndef POOL_H #ifndef POOL_H
#define POOL_H #define POOL_H
@ -19,11 +20,10 @@ extern "C" {
typedef struct POOL_ctx_s POOL_ctx; typedef struct POOL_ctx_s POOL_ctx;
/*! POOL_create() : /*! POOL_create() :
Create a thread pool with at most `numThreads` threads. * Create a thread pool with at most `numThreads` threads.
`numThreads` must be at least 1. * `numThreads` must be at least 1.
The maximum number of queued jobs before blocking is `queueSize`. * The maximum number of queued jobs before blocking is `queueSize`.
`queueSize` must be at least 1. * @return : POOL_ctx pointer on success, else NULL.
@return : The POOL_ctx pointer on success else NULL.
*/ */
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize); POOL_ctx *POOL_create(size_t numThreads, size_t queueSize);

View File

@ -1,4 +1,3 @@
/** /**
* Copyright (c) 2016 Tino Reichardt * Copyright (c) 2016 Tino Reichardt
* All rights reserved. * All rights reserved.
@ -42,14 +41,14 @@ extern "C" {
/* mutex */ /* mutex */
#define pthread_mutex_t CRITICAL_SECTION #define pthread_mutex_t CRITICAL_SECTION
#define pthread_mutex_init(a,b) InitializeCriticalSection((a)) #define pthread_mutex_init(a,b) (InitializeCriticalSection((a)), 0)
#define pthread_mutex_destroy(a) DeleteCriticalSection((a)) #define pthread_mutex_destroy(a) DeleteCriticalSection((a))
#define pthread_mutex_lock(a) EnterCriticalSection((a)) #define pthread_mutex_lock(a) EnterCriticalSection((a))
#define pthread_mutex_unlock(a) LeaveCriticalSection((a)) #define pthread_mutex_unlock(a) LeaveCriticalSection((a))
/* condition variable */ /* condition variable */
#define pthread_cond_t CONDITION_VARIABLE #define pthread_cond_t CONDITION_VARIABLE
#define pthread_cond_init(a, b) InitializeConditionVariable((a)) #define pthread_cond_init(a, b) (InitializeConditionVariable((a)), 0)
#define pthread_cond_destroy(a) /* No delete */ #define pthread_cond_destroy(a) /* No delete */
#define pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE) #define pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
#define pthread_cond_signal(a) WakeConditionVariable((a)) #define pthread_cond_signal(a) WakeConditionVariable((a))
@ -80,14 +79,14 @@ int _pthread_join(pthread_t* thread, void** value_ptr);
#else /* ZSTD_MULTITHREAD not defined */ #else /* ZSTD_MULTITHREAD not defined */
/* No multithreading support */ /* No multithreading support */
#define pthread_mutex_t int /* #define rather than typedef, as sometimes pthread support is implicit, resulting in duplicated symbols */ #define pthread_mutex_t int /* #define rather than typedef, because sometimes pthread support is implicit, resulting in duplicated symbols */
#define pthread_mutex_init(a,b) #define pthread_mutex_init(a,b) ((void)a, 0)
#define pthread_mutex_destroy(a) #define pthread_mutex_destroy(a)
#define pthread_mutex_lock(a) #define pthread_mutex_lock(a)
#define pthread_mutex_unlock(a) #define pthread_mutex_unlock(a)
#define pthread_cond_t int #define pthread_cond_t int
#define pthread_cond_init(a,b) #define pthread_cond_init(a,b) ((void)a, 0)
#define pthread_cond_destroy(a) #define pthread_cond_destroy(a)
#define pthread_cond_wait(a,b) #define pthread_cond_wait(a,b)
#define pthread_cond_signal(a) #define pthread_cond_signal(a)

View File

@ -113,19 +113,25 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
/* ************************************* /* *************************************
* Compiler Specific Options * Compiler Specific Options
***************************************/ ***************************************/
#ifdef _MSC_VER /* Visual Studio */ #if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # define INLINE_KEYWORD inline
# define FORCE_INLINE static __forceinline
#else #else
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # define INLINE_KEYWORD
# ifdef __GNUC__ #endif
# define FORCE_INLINE static inline __attribute__((always_inline))
# else #if defined(__GNUC__)
# define FORCE_INLINE static inline # define FORCE_INLINE_ATTR __attribute__((always_inline))
# endif #elif defined(_MSC_VER)
# else # define FORCE_INLINE_ATTR __forceinline
# define FORCE_INLINE static #else
# endif /* __STDC_VERSION__ */ # define FORCE_INLINE_ATTR
#endif
#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
#ifdef _MSC_VER
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
#endif #endif
@ -248,7 +254,7 @@ typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
*****************************/ *****************************/
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
{ {
if (align==XXH_unaligned) if (align==XXH_unaligned)
return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
@ -256,7 +262,7 @@ FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_a
return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
} }
FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
{ {
return XXH_readLE32_align(ptr, endian, XXH_unaligned); return XXH_readLE32_align(ptr, endian, XXH_unaligned);
} }
@ -266,7 +272,7 @@ static U32 XXH_readBE32(const void* ptr)
return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
} }
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
{ {
if (align==XXH_unaligned) if (align==XXH_unaligned)
return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
@ -274,7 +280,7 @@ FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_a
return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
} }
FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
{ {
return XXH_readLE64_align(ptr, endian, XXH_unaligned); return XXH_readLE64_align(ptr, endian, XXH_unaligned);
} }
@ -335,7 +341,7 @@ static U32 XXH32_round(U32 seed, U32 input)
return seed; return seed;
} }
FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
{ {
const BYTE* p = (const BYTE*)input; const BYTE* p = (const BYTE*)input;
const BYTE* bEnd = p + len; const BYTE* bEnd = p + len;
@ -435,7 +441,7 @@ static U64 XXH64_mergeRound(U64 acc, U64 val)
return acc; return acc;
} }
FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
{ {
const BYTE* p = (const BYTE*)input; const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len; const BYTE* const bEnd = p + len;
@ -584,7 +590,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long
} }
FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
{ {
const BYTE* p = (const BYTE*)input; const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len; const BYTE* const bEnd = p + len;
@ -654,7 +660,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void*
FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
{ {
const BYTE * p = (const BYTE*)state->mem32; const BYTE * p = (const BYTE*)state->mem32;
const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
@ -704,7 +710,7 @@ XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
/* **** XXH64 **** */ /* **** XXH64 **** */
FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
{ {
const BYTE* p = (const BYTE*)input; const BYTE* p = (const BYTE*)input;
const BYTE* const bEnd = p + len; const BYTE* const bEnd = p + len;
@ -771,7 +777,7 @@ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void*
FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
{ {
const BYTE * p = (const BYTE*)state->mem64; const BYTE * p = (const BYTE*)state->mem64;
const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */

View File

@ -1,10 +1,10 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
#ifndef ZSTD_ERRORS_H_398273423 #ifndef ZSTD_ERRORS_H_398273423
@ -37,43 +37,41 @@ extern "C" {
/*-**************************************** /*-****************************************
* error codes list * error codes list
* note : this API is still considered unstable * note : this API is still considered unstable
* it should not be used with a dynamic library * and shall not be used with a dynamic library.
* only static linking is allowed * only static linking is allowed
******************************************/ ******************************************/
typedef enum { typedef enum {
ZSTD_error_no_error, ZSTD_error_no_error = 0,
ZSTD_error_GENERIC, ZSTD_error_GENERIC = 1,
ZSTD_error_prefix_unknown, ZSTD_error_prefix_unknown = 10,
ZSTD_error_version_unsupported, ZSTD_error_version_unsupported = 12,
ZSTD_error_parameter_unknown, ZSTD_error_frameParameter_unsupported = 14,
ZSTD_error_frameParameter_unsupported, ZSTD_error_frameParameter_windowTooLarge = 16,
ZSTD_error_frameParameter_unsupportedBy32bits, ZSTD_error_corruption_detected = 20,
ZSTD_error_frameParameter_windowTooLarge, ZSTD_error_checksum_wrong = 22,
ZSTD_error_compressionParameter_unsupported, ZSTD_error_dictionary_corrupted = 30,
ZSTD_error_compressionParameter_outOfBound, ZSTD_error_dictionary_wrong = 32,
ZSTD_error_init_missing, ZSTD_error_dictionaryCreation_failed = 34,
ZSTD_error_memory_allocation, ZSTD_error_parameter_unsupported = 40,
ZSTD_error_stage_wrong, ZSTD_error_parameter_outOfBound = 42,
ZSTD_error_dstSize_tooSmall, ZSTD_error_tableLog_tooLarge = 44,
ZSTD_error_srcSize_wrong, ZSTD_error_maxSymbolValue_tooLarge = 46,
ZSTD_error_corruption_detected, ZSTD_error_maxSymbolValue_tooSmall = 48,
ZSTD_error_checksum_wrong, ZSTD_error_stage_wrong = 60,
ZSTD_error_tableLog_tooLarge, ZSTD_error_init_missing = 62,
ZSTD_error_maxSymbolValue_tooLarge, ZSTD_error_memory_allocation = 64,
ZSTD_error_maxSymbolValue_tooSmall, ZSTD_error_dstSize_tooSmall = 70,
ZSTD_error_dictionary_corrupted, ZSTD_error_srcSize_wrong = 72,
ZSTD_error_dictionary_wrong, ZSTD_error_frameIndex_tooLarge = 100,
ZSTD_error_dictionaryCreation_failed, ZSTD_error_seekableIO = 102,
ZSTD_error_frameIndex_tooLarge, ZSTD_error_maxCode = 120 /* never EVER use this value directly, it may change in future versions! Use ZSTD_isError() instead */
ZSTD_error_seekableIO,
ZSTD_error_maxCode
} ZSTD_ErrorCode; } ZSTD_ErrorCode;
/*! ZSTD_getErrorCode() : /*! ZSTD_getErrorCode() :
convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
which can be used to compare with enum list published above */ which can be used to compare with enum list published above */
ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */
#if defined (__cplusplus) #if defined (__cplusplus)

View File

@ -1,55 +1,28 @@
/** /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under the BSD-style license found in the * This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree. An additional grant * LICENSE file in the root directory of this source tree) and the GPLv2 (found
* of patent rights can be found in the PATENTS file in the same directory. * in the COPYING file in the root directory of this source tree).
*/ */
#ifndef ZSTD_CCOMMON_H_MODULE #ifndef ZSTD_CCOMMON_H_MODULE
#define ZSTD_CCOMMON_H_MODULE #define ZSTD_CCOMMON_H_MODULE
/*-*******************************************************
* Compiler specifics
*********************************************************/
#ifdef _MSC_VER /* Visual Studio */
# define FORCE_INLINE static __forceinline
# include <intrin.h> /* For Visual 2005 */
# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
# pragma warning(disable : 4324) /* disable: C4324: padded structure */
#else
# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# ifdef __GNUC__
# define FORCE_INLINE static inline __attribute__((always_inline))
# else
# define FORCE_INLINE static inline
# endif
# else
# define FORCE_INLINE static
# endif /* __STDC_VERSION__ */
#endif
#ifdef _MSC_VER
# define FORCE_NOINLINE static __declspec(noinline)
#else
# ifdef __GNUC__
# define FORCE_NOINLINE static __attribute__((__noinline__))
# else
# define FORCE_NOINLINE static
# endif
#endif
/*-************************************* /*-*************************************
* Dependencies * Dependencies
***************************************/ ***************************************/
#include "compiler.h"
#include "mem.h" #include "mem.h"
#include "error_private.h" #include "error_private.h"
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h" #include "zstd.h"
#define FSE_STATIC_LINKING_ONLY
#include "fse.h"
#define HUF_STATIC_LINKING_ONLY
#include "huf.h"
#ifndef XXH_STATIC_LINKING_ONLY #ifndef XXH_STATIC_LINKING_ONLY
# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */ # define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
#endif #endif
@ -211,20 +184,6 @@ MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* s
*********************************************/ *********************************************/
typedef struct ZSTD_stats_s ZSTD_stats_t; typedef struct ZSTD_stats_s ZSTD_stats_t;
typedef struct {
U32 off;
U32 len;
} ZSTD_match_t;
typedef struct {
U32 price;
U32 off;
U32 mlen;
U32 litlen;
U32 rep[ZSTD_REP_NUM];
} ZSTD_optimal_t;
typedef struct seqDef_s { typedef struct seqDef_s {
U32 offset; U32 offset;
U16 litLength; U16 litLength;
@ -242,13 +201,31 @@ typedef struct {
BYTE* ofCode; BYTE* ofCode;
U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */ U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
U32 longLengthPos; U32 longLengthPos;
/* opt */ U32 rep[ZSTD_REP_NUM];
ZSTD_optimal_t* priceTable; U32 repToConfirm[ZSTD_REP_NUM];
ZSTD_match_t* matchTable; } seqStore_t;
U32* matchLengthFreq;
U32* litLengthFreq; typedef struct {
U32 off;
U32 len;
} ZSTD_match_t;
typedef struct {
U32 price;
U32 off;
U32 mlen;
U32 litlen;
U32 rep[ZSTD_REP_NUM];
} ZSTD_optimal_t;
typedef struct {
U32* litFreq; U32* litFreq;
U32* litLengthFreq;
U32* matchLengthFreq;
U32* offCodeFreq; U32* offCodeFreq;
ZSTD_match_t* matchTable;
ZSTD_optimal_t* priceTable;
U32 matchLengthSum; U32 matchLengthSum;
U32 matchSum; U32 matchSum;
U32 litLengthSum; U32 litLengthSum;
@ -264,7 +241,19 @@ typedef struct {
U32 cachedPrice; U32 cachedPrice;
U32 cachedLitLength; U32 cachedLitLength;
const BYTE* cachedLiterals; const BYTE* cachedLiterals;
} seqStore_t; } optState_t;
typedef struct {
U32 hufCTable[HUF_CTABLE_SIZE_U32(255)];
FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
U32 workspace[HUF_WORKSPACE_SIZE_U32];
HUF_repeat hufCTable_repeatMode;
FSE_repeat offcode_repeatMode;
FSE_repeat matchlength_repeatMode;
FSE_repeat litlength_repeatMode;
} ZSTD_entropyCTables_t;
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
@ -331,4 +320,16 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict); ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict);
typedef struct {
blockType_e blockType;
U32 lastBlock;
U32 origSize;
} blockProperties_t;
/*! ZSTD_getcBlockSize() :
* Provides the size of compressed block from block header `src` */
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
blockProperties_t* bpPtr);
#endif /* ZSTD_CCOMMON_H_MODULE */ #endif /* ZSTD_CCOMMON_H_MODULE */

Some files were not shown because too many files have changed in this diff Show More