add boost on mac
This commit is contained in:
166
macx64/include/boost/random/detail/gray_coded_qrng.hpp
Normal file
166
macx64/include/boost/random/detail/gray_coded_qrng.hpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/* boost random/detail/gray_coded_qrng.hpp header file
|
||||
*
|
||||
* Copyright Justinas Vygintas Daugmaudis 2010-2018
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_RANDOM_DETAIL_GRAY_CODED_QRNG_HPP
|
||||
#define BOOST_RANDOM_DETAIL_GRAY_CODED_QRNG_HPP
|
||||
|
||||
#include <boost/random/detail/qrng_base.hpp>
|
||||
|
||||
#include <boost/multiprecision/integer.hpp> // lsb
|
||||
|
||||
#include <functional> // bit_xor
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
#include <boost/integer/integer_mask.hpp>
|
||||
|
||||
//!\file
|
||||
//!Describes the gray-coded quasi-random number generator base class template.
|
||||
|
||||
namespace boost {
|
||||
namespace random {
|
||||
|
||||
namespace qrng_detail {
|
||||
|
||||
template<typename LatticeT>
|
||||
class gray_coded_qrng
|
||||
: public qrng_base<
|
||||
gray_coded_qrng<LatticeT>
|
||||
, LatticeT
|
||||
, typename LatticeT::value_type
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef typename LatticeT::value_type result_type;
|
||||
typedef result_type size_type;
|
||||
|
||||
private:
|
||||
typedef gray_coded_qrng<LatticeT> self_t;
|
||||
typedef qrng_base<self_t, LatticeT, size_type> base_t;
|
||||
|
||||
// The base needs to access modifying member f-ns, and we
|
||||
// don't want these functions to be available for the public use
|
||||
friend class qrng_base<self_t, LatticeT, size_type>;
|
||||
|
||||
// Respect lattice bit_count here
|
||||
struct check_nothing {
|
||||
inline static void bit_pos(unsigned) {}
|
||||
inline static void code_size(size_type) {}
|
||||
};
|
||||
struct check_bit_range {
|
||||
static void raise_bit_count() {
|
||||
boost::throw_exception( std::range_error("gray_coded_qrng: bit_count") );
|
||||
}
|
||||
inline static void bit_pos(unsigned bit_pos) {
|
||||
if (bit_pos >= LatticeT::bit_count)
|
||||
raise_bit_count();
|
||||
}
|
||||
inline static void code_size(size_type code) {
|
||||
if (code > (self_t::max)())
|
||||
raise_bit_count();
|
||||
}
|
||||
};
|
||||
|
||||
// We only want to check whether bit pos is outside the range if given bit_count
|
||||
// is narrower than the size_type, otherwise checks compile to nothing.
|
||||
BOOST_STATIC_ASSERT(LatticeT::bit_count <= std::numeric_limits<size_type>::digits);
|
||||
|
||||
typedef typename mpl::if_c<
|
||||
((LatticeT::bit_count) < std::numeric_limits<size_type>::digits)
|
||||
, check_bit_range
|
||||
, check_nothing
|
||||
>::type check_bit_range_t;
|
||||
|
||||
public:
|
||||
//!Returns: Tight lower bound on the set of values returned by operator().
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{ return 0; }
|
||||
|
||||
//!Returns: Tight upper bound on the set of values returned by operator().
|
||||
//!
|
||||
//!Throws: nothing.
|
||||
static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION ()
|
||||
{ return low_bits_mask_t<LatticeT::bit_count>::sig_bits; }
|
||||
|
||||
explicit gray_coded_qrng(std::size_t dimension)
|
||||
: base_t(dimension)
|
||||
{}
|
||||
|
||||
// default copy c-tor is fine
|
||||
|
||||
// default assignment operator is fine
|
||||
|
||||
void seed()
|
||||
{
|
||||
set_zero_state();
|
||||
update_quasi(0);
|
||||
base_t::reset_seq(0);
|
||||
}
|
||||
|
||||
void seed(const size_type init)
|
||||
{
|
||||
if (init != this->curr_seq())
|
||||
{
|
||||
// We don't want negative seeds.
|
||||
check_seed_sign(init);
|
||||
|
||||
size_type seq_code = boost::next(init);
|
||||
if (BOOST_UNLIKELY(!(init < seq_code)))
|
||||
boost::throw_exception( std::range_error("gray_coded_qrng: seed") );
|
||||
|
||||
seq_code ^= (seq_code >> 1);
|
||||
// Fail if we see that seq_code is outside bit range.
|
||||
// We do that before we even touch engine state.
|
||||
check_bit_range_t::code_size(seq_code);
|
||||
|
||||
set_zero_state();
|
||||
for (unsigned r = 0; seq_code != 0; ++r, seq_code >>= 1)
|
||||
{
|
||||
if (seq_code & static_cast<size_type>(1))
|
||||
update_quasi(r);
|
||||
}
|
||||
}
|
||||
// Everything went well, set the new seq count
|
||||
base_t::reset_seq(init);
|
||||
}
|
||||
|
||||
private:
|
||||
void compute_seq(size_type seq)
|
||||
{
|
||||
// Find the position of the least-significant zero in sequence count.
|
||||
// This is the bit that changes in the Gray-code representation as
|
||||
// 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)());
|
||||
check_bit_range_t::bit_pos(r);
|
||||
update_quasi(r);
|
||||
}
|
||||
|
||||
void update_quasi(unsigned r)
|
||||
{
|
||||
// Calculate the next state.
|
||||
std::transform(this->state_begin(), this->state_end(),
|
||||
this->lattice.iter_at(r * this->dimension()), this->state_begin(),
|
||||
std::bit_xor<result_type>());
|
||||
}
|
||||
|
||||
void set_zero_state()
|
||||
{
|
||||
std::fill(this->state_begin(), this->state_end(), result_type /*zero*/ ());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace qrng_detail
|
||||
|
||||
} // namespace random
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_RANDOM_DETAIL_GRAY_CODED_QRNG_HPP
|
||||
Reference in New Issue
Block a user