123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- #ifndef BOOST_RANDOM_SOBOL_HPP
- #define BOOST_RANDOM_SOBOL_HPP
- #include <boost/random/detail/sobol_table.hpp>
- #include <boost/random/detail/gray_coded_qrng.hpp>
- #include <boost/assert.hpp>
- namespace boost {
- namespace random {
- namespace qrng_detail {
- template<typename UIntType, unsigned w, typename SobolTables>
- struct sobol_lattice
- {
- typedef UIntType value_type;
- BOOST_STATIC_ASSERT(w > 0u);
- BOOST_STATIC_CONSTANT(unsigned, bit_count = w);
- private:
- typedef std::vector<value_type> container_type;
- public:
- explicit sobol_lattice(std::size_t dimension)
- {
- resize(dimension);
- }
-
- void resize(std::size_t dimension)
- {
- dimension_assert("Sobol", dimension, SobolTables::max_dimension);
-
- container_type cj(bit_count * dimension);
-
- for (unsigned k = 0; k != bit_count; ++k)
- cj[dimension*k] = static_cast<value_type>(1);
-
- for (std::size_t dim = 1; dim < dimension; ++dim)
- {
- const typename SobolTables::value_type poly = SobolTables::polynomial(dim-1);
- if (poly > (std::numeric_limits<value_type>::max)()) {
- boost::throw_exception( std::range_error("sobol: polynomial value outside the given value type range") );
- }
- const unsigned degree = qrng_detail::msb(poly);
-
- for (unsigned k = 0; k != degree; ++k)
- cj[dimension*k + dim] = SobolTables::minit(dim-1, k);
-
-
- for (unsigned j = degree; j < bit_count; ++j)
- {
- typename SobolTables::value_type p_i = poly;
- const std::size_t bit_offset = dimension*j + dim;
- cj[bit_offset] = cj[dimension*(j-degree) + dim];
- for (unsigned k = 0; k != degree; ++k, p_i >>= 1)
- {
- int rem = degree - k;
- cj[bit_offset] ^= ((p_i & 1) * cj[dimension*(j-rem) + dim]) << rem;
- }
- }
- }
-
- unsigned p = 1u;
- for (int j = bit_count-1-1; j >= 0; --j, ++p)
- {
- const std::size_t bit_offset = dimension * j;
- for (std::size_t dim = 0; dim != dimension; ++dim)
- cj[bit_offset + dim] <<= p;
- }
- bits.swap(cj);
- }
- typename container_type::const_iterator iter_at(std::size_t n) const
- {
- BOOST_ASSERT(!(n > bits.size()));
- return bits.begin() + n;
- }
- private:
- container_type bits;
- };
- }
- typedef detail::qrng_tables::sobol default_sobol_table;
- template<typename UIntType, unsigned w, typename SobolTables = default_sobol_table>
- class sobol_engine
- : public qrng_detail::gray_coded_qrng<
- qrng_detail::sobol_lattice<UIntType, w, SobolTables>
- >
- {
- typedef qrng_detail::sobol_lattice<UIntType, w, SobolTables> lattice_t;
- typedef qrng_detail::gray_coded_qrng<lattice_t> base_t;
- public:
-
-
-
- explicit sobol_engine(std::size_t s)
- : base_t(s)
- {}
-
- #ifdef BOOST_RANDOM_DOXYGEN
-
- typedef UIntType result_type;
-
- static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
- { return (base_t::min)(); }
-
- static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
- { return (base_t::max)(); }
-
- std::size_t dimension() const { return base_t::dimension(); }
-
- void seed()
- {
- base_t::seed();
- }
-
- void seed(UIntType init)
- {
- base_t::seed(init);
- }
-
- result_type operator()()
- {
- return base_t::operator()();
- }
-
- void discard(boost::uintmax_t z)
- {
- base_t::discard(z);
- }
-
- BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(sobol_engine, x, y)
- { return static_cast<const base_t&>(x) == y; }
-
- BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(sobol_engine)
-
- BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, sobol_engine, s)
- { return os << static_cast<const base_t&>(s); }
-
- BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, sobol_engine, s)
- { return is >> static_cast<base_t&>(s); }
- #endif
- };
- typedef sobol_engine<boost::uint_least64_t, 64u, default_sobol_table> sobol;
- }
- }
- #endif
|