mirror of
https://github.com/boostorg/random.git
synced 2026-01-19 04:22:17 +00:00
Merge pull request #127 from boostorg/remove_array
Remove Heavy Dependencies
This commit is contained in:
@@ -17,14 +17,12 @@ target_include_directories(boost_random PUBLIC include)
|
||||
|
||||
target_link_libraries(boost_random
|
||||
PUBLIC
|
||||
Boost::array
|
||||
Boost::assert
|
||||
Boost::config
|
||||
Boost::core
|
||||
Boost::dynamic_bitset
|
||||
Boost::integer
|
||||
Boost::io
|
||||
Boost::range
|
||||
Boost::static_assert
|
||||
Boost::system
|
||||
Boost::throw_exception
|
||||
@@ -51,4 +49,3 @@ if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
|
||||
add_subdirectory(test)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
require-b2 5.2 ;
|
||||
|
||||
constant boost_dependencies :
|
||||
/boost/array//boost_array
|
||||
/boost/assert//boost_assert
|
||||
/boost/config//boost_config
|
||||
/boost/core//boost_core
|
||||
/boost/dynamic_bitset//boost_dynamic_bitset
|
||||
/boost/integer//boost_integer
|
||||
/boost/io//boost_io
|
||||
/boost/range//boost_range
|
||||
/boost/static_assert//boost_static_assert
|
||||
/boost/system//boost_system
|
||||
/boost/throw_exception//boost_throw_exception
|
||||
@@ -33,4 +31,3 @@ explicit
|
||||
call-if : boost-library random
|
||||
: install boost_random
|
||||
;
|
||||
|
||||
|
||||
41
include/boost/random/detail/size.hpp
Normal file
41
include/boost/random/detail/size.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright Matt Borland 2025.
|
||||
* 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 <iterator>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
|
||||
#if defined (__cpp_lib_nonmember_container_access) && __cpp_lib_nonmember_container_access >= 201411L
|
||||
|
||||
using std::size;
|
||||
|
||||
#else
|
||||
|
||||
template <typename C>
|
||||
constexpr auto size(const C& c) -> decltype(c.size())
|
||||
{
|
||||
return c.size();
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
constexpr std::size_t size(const T (&array)[N]) noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace boost
|
||||
@@ -29,9 +29,6 @@
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/random/detail/disable_warnings.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -268,7 +265,7 @@ public:
|
||||
*/
|
||||
template<class Range>
|
||||
explicit param_type(const Range& range)
|
||||
: _probabilities(boost::begin(range), boost::end(range))
|
||||
: _probabilities(std::begin(range), std::end(range))
|
||||
{
|
||||
normalize();
|
||||
}
|
||||
@@ -308,7 +305,7 @@ public:
|
||||
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)
|
||||
{
|
||||
@@ -389,7 +386,7 @@ public:
|
||||
template<class Range>
|
||||
explicit discrete_distribution(const Range& range)
|
||||
{
|
||||
init(boost::begin(range), boost::end(range));
|
||||
init(std::begin(range), std::end(range));
|
||||
}
|
||||
/**
|
||||
* Constructs a discrete_distribution that approximates a function.
|
||||
@@ -440,7 +437,7 @@ public:
|
||||
return(_impl._alias_table[static_cast<std::size_t>(result)].second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a value distributed according to the parameters
|
||||
* specified by param.
|
||||
@@ -472,7 +469,7 @@ public:
|
||||
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. */
|
||||
@@ -520,7 +517,7 @@ public:
|
||||
{
|
||||
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.
|
||||
@@ -576,7 +573,7 @@ private:
|
||||
std::vector<std::pair<WeightType, IntType> > above_average;
|
||||
below_average.reserve(input_size);
|
||||
above_average.reserve(input_size);
|
||||
|
||||
|
||||
WeightType weight_average = _impl.init_average(first, last);
|
||||
WeightType normalized_average = _impl.get_weight(0);
|
||||
std::size_t i = 0;
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
#include <boost/core/cmath.hpp>
|
||||
#include <boost/random/detail/operators.hpp>
|
||||
#include <boost/random/detail/vector_io.hpp>
|
||||
#include <boost/random/detail/size.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 <cmath>
|
||||
#include <cstddef>
|
||||
@@ -294,8 +292,8 @@ class hyperexponential_distribution
|
||||
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))
|
||||
: probs_(std::begin(prob_range), std::end(prob_range)),
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
hyperexp_detail::normalize(probs_);
|
||||
|
||||
@@ -330,8 +328,8 @@ class hyperexponential_distribution
|
||||
// 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,
|
||||
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)
|
||||
@@ -355,8 +353,8 @@ class hyperexponential_distribution
|
||||
*/
|
||||
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))
|
||||
: probs_(boost::random::detail::size(rate_range), 1), // Will be normalized below
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
hyperexp_detail::normalize(probs_);
|
||||
|
||||
@@ -529,7 +527,7 @@ class hyperexponential_distribution
|
||||
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)
|
||||
|
||||
@@ -608,7 +606,7 @@ class hyperexponential_distribution
|
||||
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))
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
BOOST_ASSERT( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
|
||||
}
|
||||
@@ -667,8 +665,8 @@ class hyperexponential_distribution
|
||||
*/
|
||||
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))
|
||||
: dd_(std::vector<RealT>(boost::random::detail::size(rate_range), 1)),
|
||||
rates_(std::begin(rate_range), std::end(rate_range))
|
||||
{
|
||||
BOOST_ASSERT( hyperexp_detail::check_params(dd_.probabilities(), rates_) );
|
||||
}
|
||||
@@ -854,7 +852,7 @@ class hyperexponential_distribution
|
||||
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.
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#ifndef BOOST_RANDOM_MIXMAX_HPP
|
||||
#define BOOST_RANDOM_MIXMAX_HPP
|
||||
|
||||
#include <array>
|
||||
#include <sstream>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/random/detail/seed.hpp>
|
||||
#include <boost/random/detail/seed_impl.hpp>
|
||||
@@ -55,37 +55,37 @@ namespace random {
|
||||
*
|
||||
*/
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> // MIXMAX TEMPLATE PARAMETERS
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> // MIXMAX TEMPLATE PARAMETERS
|
||||
class mixmax_engine{
|
||||
public:
|
||||
// Interfaces required by C++11 std::random and boost::random
|
||||
typedef boost::uint64_t result_type ;
|
||||
BOOST_STATIC_CONSTANT(boost::uint64_t,mixmax_min=0);
|
||||
BOOST_STATIC_CONSTANT(boost::uint64_t,mixmax_max=((1ULL<<61)-1));
|
||||
typedef std::uint64_t result_type ;
|
||||
BOOST_STATIC_CONSTANT(std::uint64_t,mixmax_min=0);
|
||||
BOOST_STATIC_CONSTANT(std::uint64_t,mixmax_max=((1ULL<<61)-1));
|
||||
BOOST_STATIC_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION() {return mixmax_min;}
|
||||
BOOST_STATIC_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION() {return mixmax_max;}
|
||||
static const bool has_fixed_range = false;
|
||||
BOOST_STATIC_CONSTANT(int,N=Ndim); ///< The main internal parameter, size of the defining MIXMAX matrix
|
||||
// CONSTRUCTORS:
|
||||
explicit mixmax_engine(); ///< Constructor, unit vector as initial state, acted on by A^2^512
|
||||
explicit mixmax_engine(boost::uint64_t); ///< Constructor, one 64-bit seed
|
||||
explicit mixmax_engine(std::uint64_t); ///< Constructor, one 64-bit seed
|
||||
explicit mixmax_engine(uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID ); ///< Constructor, four 32-bit seeds for 128-bit seeding flexibility
|
||||
void seed(boost::uint64_t seedval=default_seed){seed_uniquestream( &S, 0, 0, (uint32_t)(seedval>>32), (uint32_t)seedval );} ///< seed with one 64-bit seed
|
||||
|
||||
void seed(std::uint64_t seedval=default_seed){seed_uniquestream( &S, 0, 0, (uint32_t)(seedval>>32), (uint32_t)seedval );} ///< seed with one 64-bit seed
|
||||
|
||||
private: // DATATYPES
|
||||
struct rng_state_st{
|
||||
boost::array<boost::uint64_t, Ndim> V;
|
||||
boost::uint64_t sumtot;
|
||||
std::array<std::uint64_t, Ndim> V;
|
||||
std::uint64_t sumtot;
|
||||
int counter;
|
||||
};
|
||||
|
||||
|
||||
typedef struct rng_state_st rng_state_t; // struct alias
|
||||
rng_state_t S;
|
||||
|
||||
|
||||
public: // SEEDING FUNCTIONS
|
||||
template<class It> mixmax_engine(It& first, It last) { seed(first,last); }
|
||||
BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(mixmax_engine, SeedSeq, seq){ seed(seq); }
|
||||
|
||||
|
||||
/** Sets the state of the generator using values from an iterator range. */
|
||||
template<class It>
|
||||
void seed(It& first, It last){
|
||||
@@ -99,9 +99,9 @@ public: // SEEDING FUNCTIONS
|
||||
detail::seed_array_int<32>(seq, v);
|
||||
seed_uniquestream( &S, v[0], v[1], v[2], v[3]);
|
||||
}
|
||||
|
||||
|
||||
/** return one uint64 between min=0 and max=2^61-1 */
|
||||
boost::uint64_t operator()(){
|
||||
std::uint64_t operator()(){
|
||||
if (S.counter<=(Ndim-1) ){
|
||||
return S.V[S.counter++];
|
||||
}else{
|
||||
@@ -110,33 +110,33 @@ public: // SEEDING FUNCTIONS
|
||||
return S.V[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Fills a range with random values */
|
||||
template<class Iter>
|
||||
void generate(Iter first, Iter last) { detail::generate_from_int(*this, first, last); }
|
||||
|
||||
void discard(boost::uint64_t nsteps) { for(boost::uint64_t j = 0; j < nsteps; ++j) (*this)(); } ///< discard n steps, required in boost::random
|
||||
|
||||
|
||||
void discard(std::uint64_t nsteps) { for(std::uint64_t j = 0; j < nsteps; ++j) (*this)(); } ///< discard n steps, required in boost::random
|
||||
|
||||
/** save the state of the RNG to a stream */
|
||||
template<class CharT, class Traits>
|
||||
friend std::basic_ostream<CharT,Traits>&
|
||||
operator<< (std::basic_ostream<CharT,Traits>& ost, const mixmax_engine& me){
|
||||
ost << Ndim << " " << me.S.counter << " " << me.S.sumtot << " ";
|
||||
for (int j=0; (j< (Ndim) ); j++) {
|
||||
ost << (boost::uint64_t)me.S.V[j] << " ";
|
||||
ost << (std::uint64_t)me.S.V[j] << " ";
|
||||
}
|
||||
ost << "\n";
|
||||
ost.flush();
|
||||
return ost;
|
||||
}
|
||||
|
||||
|
||||
/** read the state of the RNG from a stream */
|
||||
template<class CharT, class Traits>
|
||||
friend std::basic_istream<CharT,Traits>&
|
||||
operator>> (std::basic_istream<CharT,Traits> &in, mixmax_engine& me){
|
||||
// will set std::ios::failbit if the input format is not right
|
||||
boost::array<boost::uint64_t, Ndim> vec;
|
||||
boost::uint64_t sum=0, savedsum=0, counter=0;
|
||||
std::array<std::uint64_t, Ndim> vec;
|
||||
std::uint64_t sum=0, savedsum=0, counter=0;
|
||||
in >> counter >> std::ws;
|
||||
BOOST_ASSERT(counter==Ndim);
|
||||
in >> counter >> std::ws;
|
||||
@@ -161,43 +161,43 @@ friend bool operator!=(const mixmax_engine & x,
|
||||
|
||||
private:
|
||||
BOOST_STATIC_CONSTANT(int, BITS=61);
|
||||
BOOST_STATIC_CONSTANT(boost::uint64_t, M61=2305843009213693951ULL);
|
||||
BOOST_STATIC_CONSTANT(boost::uint64_t, default_seed=1);
|
||||
inline boost::uint64_t MOD_MERSENNE(boost::uint64_t k) {return ((((k)) & M61) + (((k)) >> BITS) );}
|
||||
inline boost::uint64_t MULWU(boost::uint64_t k);
|
||||
BOOST_STATIC_CONSTANT(std::uint64_t, M61=2305843009213693951ULL);
|
||||
BOOST_STATIC_CONSTANT(std::uint64_t, default_seed=1);
|
||||
inline std::uint64_t MOD_MERSENNE(std::uint64_t k) {return ((((k)) & M61) + (((k)) >> BITS) );}
|
||||
inline std::uint64_t MULWU(std::uint64_t k);
|
||||
inline void seed_vielbein(rng_state_t* X, unsigned int i); // seeds with the i-th unit vector, i = 0..Ndim-1, for testing only
|
||||
inline void seed_uniquestream( rng_state_t* Xin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID );
|
||||
inline boost::uint64_t iterate_raw_vec(boost::uint64_t* Y, boost::uint64_t sumtotOld);
|
||||
inline boost::uint64_t apply_bigskip(boost::uint64_t* Vout, boost::uint64_t* Vin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID );
|
||||
inline boost::uint64_t modadd(boost::uint64_t foo, boost::uint64_t bar);
|
||||
inline boost::uint64_t fmodmulM61(boost::uint64_t cum, boost::uint64_t s, boost::uint64_t a);
|
||||
inline std::uint64_t iterate_raw_vec(std::uint64_t* Y, std::uint64_t sumtotOld);
|
||||
inline std::uint64_t apply_bigskip(std::uint64_t* Vout, std::uint64_t* Vin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID );
|
||||
inline std::uint64_t modadd(std::uint64_t foo, std::uint64_t bar);
|
||||
inline std::uint64_t fmodmulM61(std::uint64_t cum, std::uint64_t s, std::uint64_t a);
|
||||
};
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine()
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine()
|
||||
///< constructor, with no params, seeds with seed=0, random numbers are as good as from any other seed
|
||||
{
|
||||
seed_uniquestream( &S, 0, 0, 0, default_seed);
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine(boost::uint64_t seedval){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine(std::uint64_t seedval){
|
||||
///< constructor, one uint64_t seed, random numbers are statistically independent from any two distinct seeds, e.g. consecutive seeds are ok
|
||||
seed_uniquestream( &S, 0, 0, (uint32_t)(seedval>>32), (uint32_t)seedval );
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine(uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::mixmax_engine(uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID){
|
||||
// constructor, four 32-bit seeds for 128-bit seeding flexibility
|
||||
seed_uniquestream( &S, clusterID, machineID, runID, streamID );
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::MULWU (uint64_t k){ return (( (k)<<(SPECIALMUL) & M61) ^ ( (k) >> (BITS-SPECIALMUL)) ) ;}
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::MULWU (uint64_t k){ return (( (k)<<(SPECIALMUL) & M61) ^ ( (k) >> (BITS-SPECIALMUL)) ) ;}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> boost::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::iterate_raw_vec(boost::uint64_t* Y, boost::uint64_t sumtotOld){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> std::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::iterate_raw_vec(std::uint64_t* Y, std::uint64_t sumtotOld){
|
||||
// operates with a raw vector, uses known sum of elements of Y
|
||||
boost::uint64_t tempP=0, tempV=sumtotOld;
|
||||
std::uint64_t tempP=0, tempV=sumtotOld;
|
||||
Y[0] = tempV;
|
||||
boost::uint64_t sumtot = Y[0], ovflow = 0; // will keep a running sum of all new elements
|
||||
std::uint64_t sumtot = Y[0], ovflow = 0; // will keep a running sum of all new elements
|
||||
for (int i=1; i<Ndim; i++){
|
||||
boost::uint64_t tempPO = MULWU(tempP);
|
||||
std::uint64_t tempPO = MULWU(tempP);
|
||||
tempV = (tempV+tempPO);
|
||||
tempP = modadd(tempP, Y[i]);
|
||||
tempV = modadd(tempV, tempP); // new Y[i] = old Y[i] + old partial * m
|
||||
@@ -207,7 +207,7 @@ template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> boost::uint
|
||||
return MOD_MERSENNE(MOD_MERSENNE(sumtot) + (ovflow <<3 ));
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> void mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::seed_vielbein(rng_state_t* X, unsigned int index){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> void mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::seed_vielbein(rng_state_t* X, unsigned int index){
|
||||
for (int i=0; i < Ndim; i++){
|
||||
X->V[i] = 0;
|
||||
}
|
||||
@@ -217,58 +217,58 @@ template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> void mixmax
|
||||
}
|
||||
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> void mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::seed_uniquestream( rng_state_t* Xin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID ){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> void mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::seed_uniquestream( rng_state_t* Xin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID ){
|
||||
seed_vielbein(Xin,0);
|
||||
Xin->sumtot = apply_bigskip(Xin->V.data(), Xin->V.data(), clusterID, machineID, runID, streamID );
|
||||
Xin->counter = 1;
|
||||
}
|
||||
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> boost::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::apply_bigskip( boost::uint64_t* Vout, boost::uint64_t* Vin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID ){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> std::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::apply_bigskip( std::uint64_t* Vout, std::uint64_t* Vin, uint32_t clusterID, uint32_t machineID, uint32_t runID, uint32_t streamID ){
|
||||
/*
|
||||
makes a derived state vector, Vout, from the mother state vector Vin
|
||||
by skipping a large number of steps, determined by the given seeding ID's
|
||||
|
||||
|
||||
it is mathematically guaranteed that the substreams derived in this way from the SAME (!!!) Vin will not collide provided
|
||||
1) at least one bit of ID is different
|
||||
2) less than 10^100 numbers are drawn from the stream
|
||||
(this is good enough : a single CPU will not exceed this in the lifetime of the universe, 10^19 sec,
|
||||
even if it had a clock cycle of Planck time, 10^44 Hz )
|
||||
|
||||
|
||||
Caution: never apply this to a derived vector, just choose some mother vector Vin, for example the unit vector by seed_vielbein(X,0),
|
||||
and use it in all your runs, just change runID to get completely nonoverlapping streams of random numbers on a different day.
|
||||
|
||||
|
||||
clusterID and machineID are provided for the benefit of large organizations who wish to ensure that a simulation
|
||||
which is running in parallel on a large number of clusters and machines will have non-colliding source of random numbers.
|
||||
|
||||
|
||||
did i repeat it enough times? the non-collision guarantee is absolute, not probabilistic
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
const boost::uint64_t skipMat17[128][17] =
|
||||
|
||||
|
||||
const std::uint64_t skipMat17[128][17] =
|
||||
#include "boost/random/detail/mixmax_skip_N17.ipp"
|
||||
;
|
||||
|
||||
const boost::uint64_t* skipMat[128];
|
||||
|
||||
const std::uint64_t* skipMat[128];
|
||||
BOOST_ASSERT(Ndim==17);
|
||||
for (int i=0; i<128; i++) { skipMat[i] = skipMat17[i];}
|
||||
|
||||
|
||||
uint32_t IDvec[4] = {streamID, runID, machineID, clusterID};
|
||||
boost::uint64_t Y[Ndim], cum[Ndim];
|
||||
boost::uint64_t sumtot=0;
|
||||
|
||||
std::uint64_t Y[Ndim], cum[Ndim];
|
||||
std::uint64_t sumtot=0;
|
||||
|
||||
for (int i=0; i<Ndim; i++) { Y[i] = Vin[i]; sumtot = modadd( sumtot, Vin[i]); } ;
|
||||
for (int IDindex=0; IDindex<4; IDindex++) { // go from lower order to higher order ID
|
||||
uint32_t id=IDvec[IDindex];
|
||||
int r = 0;
|
||||
while (id){
|
||||
if (id & 1) {
|
||||
boost::uint64_t* rowPtr = (boost::uint64_t*)skipMat[r + IDindex*8*sizeof(uint32_t)];
|
||||
std::uint64_t* rowPtr = (std::uint64_t*)skipMat[r + IDindex*8*sizeof(uint32_t)];
|
||||
for (int i=0; i<Ndim; i++){ cum[i] = 0; }
|
||||
for (int j=0; j<Ndim; j++){ // j is lag, enumerates terms of the poly
|
||||
// for zero lag Y is already given
|
||||
boost::uint64_t coeff = rowPtr[j]; // same coeff for all i
|
||||
std::uint64_t coeff = rowPtr[j]; // same coeff for all i
|
||||
for (int i =0; i<Ndim; i++){
|
||||
cum[i] = fmodmulM61( cum[i], coeff , Y[i] ) ;
|
||||
}
|
||||
@@ -285,10 +285,10 @@ template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> boost::uint
|
||||
return (sumtot) ;
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> inline boost::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::fmodmulM61(boost::uint64_t cum, boost::uint64_t s, boost::uint64_t a){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> inline std::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::fmodmulM61(std::uint64_t cum, std::uint64_t s, std::uint64_t a){
|
||||
// works on all platforms, including 32-bit linux, PPC and PPC64, ARM and Windows
|
||||
const boost::uint64_t MASK32=0xFFFFFFFFULL;
|
||||
boost::uint64_t o,ph,pl,ah,al;
|
||||
const std::uint64_t MASK32=0xFFFFFFFFULL;
|
||||
std::uint64_t o,ph,pl,ah,al;
|
||||
o=(s)*a;
|
||||
ph = ((s)>>32);
|
||||
pl = (s) & MASK32;
|
||||
@@ -300,7 +300,7 @@ template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> inline boos
|
||||
return o;
|
||||
}
|
||||
|
||||
template <int Ndim, unsigned int SPECIALMUL, boost::int64_t SPECIAL> boost::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::modadd(boost::uint64_t foo, boost::uint64_t bar){
|
||||
template <int Ndim, unsigned int SPECIALMUL, std::int64_t SPECIAL> std::uint64_t mixmax_engine <Ndim, SPECIALMUL, SPECIAL> ::modadd(std::uint64_t foo, std::uint64_t bar){
|
||||
return MOD_MERSENNE(foo+bar);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace random {
|
||||
|
||||
@@ -127,8 +124,8 @@ public:
|
||||
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))
|
||||
: _intervals(std::begin(intervals_arg), std::end(intervals_arg)),
|
||||
_weights(std::begin(weights_arg), std::end(weights_arg))
|
||||
{
|
||||
if(_intervals.size() < 2) {
|
||||
_intervals.clear();
|
||||
@@ -185,7 +182,7 @@ public:
|
||||
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)
|
||||
{
|
||||
@@ -318,7 +315,7 @@ public:
|
||||
piecewise_constant_distribution(const IntervalsRange& intervals_arg,
|
||||
const WeightsRange& weights_arg)
|
||||
: _bins(weights_arg),
|
||||
_intervals(boost::begin(intervals_arg), boost::end(intervals_arg))
|
||||
_intervals(std::begin(intervals_arg), std::end(intervals_arg))
|
||||
{
|
||||
if(_intervals.size() < 2) {
|
||||
_intervals.clear();
|
||||
@@ -367,7 +364,7 @@ public:
|
||||
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.
|
||||
@@ -377,7 +374,7 @@ public:
|
||||
{
|
||||
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(); }
|
||||
@@ -414,7 +411,7 @@ public:
|
||||
_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.
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace random {
|
||||
|
||||
@@ -134,8 +131,8 @@ public:
|
||||
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))
|
||||
: _intervals(std::begin(intervals_arg), std::end(intervals_arg)),
|
||||
_weights(std::begin(weights_arg), std::end(weights_arg))
|
||||
{
|
||||
if(_intervals.size() < 2) {
|
||||
_weights.clear();
|
||||
@@ -200,7 +197,7 @@ public:
|
||||
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)
|
||||
{
|
||||
@@ -321,8 +318,8 @@ public:
|
||||
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))
|
||||
: _intervals(std::begin(intervals_arg), std::end(intervals_arg)),
|
||||
_weights(std::begin(weights_arg), std::end(weights_arg))
|
||||
{
|
||||
if(_intervals.size() < 2) {
|
||||
default_init();
|
||||
@@ -383,7 +380,7 @@ public:
|
||||
return (std::min)(dist(urng), dist(urng));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a value distributed according to the parameters
|
||||
* specified by param.
|
||||
@@ -393,7 +390,7 @@ public:
|
||||
{
|
||||
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(); }
|
||||
@@ -439,7 +436,7 @@ public:
|
||||
_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.
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -53,7 +51,7 @@ public:
|
||||
/** Initializes the sequence from Boost.Range range. */
|
||||
template<class Range>
|
||||
explicit seed_seq(const Range& range)
|
||||
: v(boost::begin(range), boost::end(range)) {}
|
||||
: v(std::begin(range), std::end(range)) {}
|
||||
|
||||
/**
|
||||
* Fills a range with 32-bit values based on the stored sequence.
|
||||
|
||||
Reference in New Issue
Block a user