From 2e8ae88394c3917c539937fad5b192b0397dc730 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 1 Jan 2021 18:14:29 +0200 Subject: [PATCH] Remove dependence on multiprecision::lsb, msb --- .../boost/random/detail/gray_coded_qrng.hpp | 29 +++++++++++++++++-- include/boost/random/niederreiter_base2.hpp | 2 +- include/boost/random/sobol.hpp | 3 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/boost/random/detail/gray_coded_qrng.hpp b/include/boost/random/detail/gray_coded_qrng.hpp index 7589c5f..f527487 100644 --- a/include/boost/random/detail/gray_coded_qrng.hpp +++ b/include/boost/random/detail/gray_coded_qrng.hpp @@ -11,7 +11,9 @@ #include -#include // lsb +#include // lsb +#include +#include #include // bit_xor @@ -27,6 +29,26 @@ namespace random { namespace qrng_detail { +template static int lsb( T x ) +{ + if( x == 0 ) + { + BOOST_THROW_EXCEPTION( std::range_error( "qrng_detail::lsb: argument is 0" ) ); + } + + return boost::core::countr_zero( x ); +} + +template static int msb( T x ) +{ + if( x == 0 ) + { + BOOST_THROW_EXCEPTION( std::range_error( "qrng_detail::msb: argument is 0" ) ); + } + + return std::numeric_limits::digits - 1 - boost::core::countl_zero( x ); +} + template class gray_coded_qrng : public qrng_base< @@ -111,7 +133,7 @@ public: // We don't want negative seeds. check_seed_sign(init); - size_type seq_code = boost::next(init); + size_type seq_code = init + 1; if (BOOST_UNLIKELY(!(init < seq_code))) boost::throw_exception( std::range_error("gray_coded_qrng: seed") ); @@ -132,6 +154,7 @@ public: } private: + void compute_seq(size_type seq) { // Find the position of the least-significant zero in sequence count. @@ -139,7 +162,7 @@ private: // the count is advanced. // Xor'ing with max() has the effect of flipping all the bits in seq, // except for the sign bit. - unsigned r = multiprecision::lsb(seq ^ (self_t::max)()); + unsigned r = qrng_detail::lsb(seq ^ (self_t::max)()); check_bit_range_t::bit_pos(r); update_quasi(r); } diff --git a/include/boost/random/niederreiter_base2.hpp b/include/boost/random/niederreiter_base2.hpp index 149a4a4..e1a874b 100644 --- a/include/boost/random/niederreiter_base2.hpp +++ b/include/boost/random/niederreiter_base2.hpp @@ -123,7 +123,7 @@ public: boost::throw_exception( std::range_error("niederreiter_base2: polynomial value outside the given value type range") ); } - const unsigned degree = multiprecision::msb(poly); // integer log2(poly) + const unsigned degree = qrng_detail::msb(poly); // integer log2(poly) const unsigned space_required = degree * ((bit_count / degree) + 1); // ~ degree + bit_count v.resize(degree + bit_count - 1); diff --git a/include/boost/random/sobol.hpp b/include/boost/random/sobol.hpp index 2518b37..703155b 100644 --- a/include/boost/random/sobol.hpp +++ b/include/boost/random/sobol.hpp @@ -11,6 +11,7 @@ #include #include +#include namespace boost { namespace random { @@ -61,7 +62,7 @@ public: if (poly > std::numeric_limits::max()) { boost::throw_exception( std::range_error("sobol: polynomial value outside the given value type range") ); } - const unsigned degree = multiprecision::msb(poly); // integer log2(poly) + const unsigned degree = qrng_detail::msb(poly); // integer log2(poly) // set initial values of m from table for (unsigned k = 0; k != degree; ++k)