2
0
mirror of https://github.com/boostorg/random.git synced 2026-01-19 04:22:17 +00:00

Remove dependence on multiprecision::lsb, msb

This commit is contained in:
Peter Dimov
2021-01-01 18:14:29 +02:00
parent 1e778bfc22
commit 2e8ae88394
3 changed files with 29 additions and 5 deletions

View File

@@ -11,7 +11,9 @@
#include <boost/random/detail/qrng_base.hpp>
#include <boost/multiprecision/integer.hpp> // lsb
#include <boost/core/bit.hpp> // lsb
#include <boost/throw_exception.hpp>
#include <stdexcept>
#include <functional> // bit_xor
@@ -27,6 +29,26 @@ namespace random {
namespace qrng_detail {
template<class T> 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<class T> static int msb( T x )
{
if( x == 0 )
{
BOOST_THROW_EXCEPTION( std::range_error( "qrng_detail::msb: argument is 0" ) );
}
return std::numeric_limits<T>::digits - 1 - boost::core::countl_zero( x );
}
template<typename LatticeT>
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);
}

View File

@@ -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);

View File

@@ -11,6 +11,7 @@
#include <boost/random/detail/sobol_table.hpp>
#include <boost/random/detail/gray_coded_qrng.hpp>
#include <boost/assert.hpp>
namespace boost {
namespace random {
@@ -61,7 +62,7 @@ public:
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 = 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)