|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r64599 - in sandbox/SOC/2010/quasi_random/boost/random: . detail
From: jvd_at_[hidden]
Date: 2010-08-04 15:45:15
Author: qrng
Date: 2010-08-04 15:45:13 EDT (Wed, 04 Aug 2010)
New Revision: 64599
URL: http://svn.boost.org/trac/boost/changeset/64599
Log:
While undoubtedly more elegant, mpl::for_each with boost::bind come with a price. Reverted the generators to use
the older recursive template instantiation idiom. This reduces gsl_validate.cpp compile times from over 4
minutes to ~1 minute. Also, the generated executable is subtantially smaller.
Text files modified:
sandbox/SOC/2010/quasi_random/boost/random/detail/gray_coded_qrng_base.hpp | 2
sandbox/SOC/2010/quasi_random/boost/random/niederreiter_base2.hpp | 28 +++++++++------
sandbox/SOC/2010/quasi_random/boost/random/sobol.hpp | 72 +++++++++++++++++++++++++---------------
3 files changed, 63 insertions(+), 39 deletions(-)
Modified: sandbox/SOC/2010/quasi_random/boost/random/detail/gray_coded_qrng_base.hpp
==============================================================================
--- sandbox/SOC/2010/quasi_random/boost/random/detail/gray_coded_qrng_base.hpp (original)
+++ sandbox/SOC/2010/quasi_random/boost/random/detail/gray_coded_qrng_base.hpp 2010-08-04 15:45:13 EDT (Wed, 04 Aug 2010)
@@ -120,7 +120,7 @@
void update_quasi(std::size_t r, const char* msg)
{
- if(r >= (std::size_t)LatticeT::bit_count)
+ if(r >= LatticeT::bit_count)
boost::throw_exception( std::overflow_error(msg) );
// Calculate the next state.
Modified: sandbox/SOC/2010/quasi_random/boost/random/niederreiter_base2.hpp
==============================================================================
--- sandbox/SOC/2010/quasi_random/boost/random/niederreiter_base2.hpp (original)
+++ sandbox/SOC/2010/quasi_random/boost/random/niederreiter_base2.hpp 2010-08-04 15:45:13 EDT (Wed, 04 Aug 2010)
@@ -15,14 +15,11 @@
#include <limits>
#include <bitset>
-#include <boost/cstdint.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/static_assert.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/bind.hpp>
+#include <boost/cstdint.hpp>
//!\file
//!Describes the quasi-random number generator class template niederreiter_base2.
@@ -178,15 +175,15 @@
BOOST_STATIC_CONSTANT(int, value = Degree * ( (BitCount / Degree) + 1 ));
};
+template<std::size_t Depth>
struct compute_lattice
{
- typedef void result_type;
- template<typename Int, typename T, int BitCount, int MaxE, std::size_t Dimension>
- void operator()(Int, T (&ci)[BitCount][BitCount], T (&v)[MaxE],
- T (&cj)[BitCount][Dimension]) const
+ template<typename T, int BitCount, int MaxE, std::size_t Dimension>
+ static void apply(T (&ci)[BitCount][BitCount], T (&v)[MaxE],
+ T (&cj)[BitCount][Dimension])
{
enum {
- iteration = Int::value,
+ iteration = Dimension - Depth,
poly_index = iteration + 1,
px_value = primitive_polynomial<poly_index>::value,
px_degree = primitive_polynomial<poly_index>::degree,
@@ -238,9 +235,19 @@
term = 2*term + ci[r][j];
cj[r][iteration] = term;
}
+
+ compute_lattice<Depth - 1>::apply(ci, v, cj);
}
};
+template<>
+struct compute_lattice<0>
+{
+ template<typename T, typename U, typename V>
+ static void apply(const T&, const U&, const V&)
+ { /* recursion stop */ }
+};
+
} // namespace nb2
template<typename IntType, std::size_t Dimension>
@@ -269,8 +276,7 @@
// initial lattice computation
IntType ci[bit_count][bit_count];
IntType v[prim_degree + max_degree];
- mpl::for_each< mpl::range_c<std::size_t, 0, Dimension> >(
- bind(nb2::compute_lattice(), _1, ref(ci), ref(v), ref(bits)) );
+ nb2::compute_lattice<Dimension>::apply(ci, v, bits);
}
result_type operator()(std::size_t i, std::size_t j) const
Modified: sandbox/SOC/2010/quasi_random/boost/random/sobol.hpp
==============================================================================
--- sandbox/SOC/2010/quasi_random/boost/random/sobol.hpp (original)
+++ sandbox/SOC/2010/quasi_random/boost/random/sobol.hpp 2010-08-04 15:45:13 EDT (Wed, 04 Aug 2010)
@@ -21,9 +21,6 @@
#include <boost/mpl/vector/vector40_c.hpp>
#include <boost/mpl/at.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/for_each.hpp>
-#include <boost/bind.hpp>
//!\file
//!Describes the quasi-random number generator class template sobol.
@@ -104,7 +101,7 @@
template<std::size_t D>
struct vinit40;
-template<> struct vinit40<0> {
+template<> struct vinit40<1> {
typedef mpl::vector40_c<int,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -112,7 +109,7 @@
1, 1, 1, 1, 1, 1, 1, 1, 1, 1> type;
};
-template<> struct vinit40<1>
+template<> struct vinit40<2>
{
typedef mpl::vector40_c<int,
0, 0, 1, 3, 1, 3, 1, 3, 3, 1,
@@ -121,7 +118,7 @@
3, 1, 1, 3, 1, 3, 1, 3, 1, 3> type;
};
-template<> struct vinit40<2>
+template<> struct vinit40<3>
{
typedef mpl::vector40_c<int,
0, 0, 0, 7, 5, 1, 3, 3, 7, 5,
@@ -130,7 +127,7 @@
5, 1, 1, 5, 7, 7, 5, 1, 3, 3> type;
};
-template<> struct vinit40<3>
+template<> struct vinit40<4>
{
typedef mpl::vector40_c<int,
0, 0, 0, 0, 0, 1, 7, 9, 13, 11,
@@ -139,7 +136,7 @@
5, 15, 1, 15, 11, 5, 3, 1, 7, 9> type;
};
-template<> struct vinit40<4>
+template<> struct vinit40<5>
{
typedef mpl::vector40_c<int,
0, 0, 0, 0, 0, 0, 0, 9, 3, 27,
@@ -148,7 +145,7 @@
21, 5, 1, 17, 13, 7, 15, 9, 31, 9> type;
};
-template<> struct vinit40<5>
+template<> struct vinit40<6>
{
typedef mpl::vector40_c<int,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -157,7 +154,7 @@
9, 49, 33, 19, 29, 11, 19, 27, 15, 25> type;
};
-template<> struct vinit40<6>
+template<> struct vinit40<7>
{
typedef mpl::vector40_c<int,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -166,7 +163,7 @@
7, 59, 65, 21, 3, 113, 61, 89, 45, 107> type;
};
-template<> struct vinit40<7>
+template<> struct vinit40<8>
{
typedef mpl::vector40_c<int,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -176,34 +173,46 @@
};
-template<std::size_t Iteration>
+template<std::size_t Degree>
struct leading_elements
{
- typedef void result_type;
- template<typename Int, typename T, std::size_t BitCount, std::size_t Dimension>
- void operator()(Int, T (&cj)[BitCount][Dimension]) const
+ template<std::size_t Iteration, typename T, int BitCount, std::size_t Dimension>
+ static void assign(T (&cj)[BitCount][Dimension])
{
- typedef typename vinit40<Int::value>::type elems_t;
+ typedef typename vinit40<Degree>::type elems_t;
typedef typename mpl::at_c<elems_t, Iteration>::type val_t;
- cj[Int::value][Iteration] = val_t::value;
+ cj[Degree - 1][Iteration] = val_t::value;
+ leading_elements<Degree - 1>::template assign<Iteration>(cj);
}
};
+template<>
+struct leading_elements<0>
+{
+ template<std::size_t Iteration, typename T>
+ static void assign(const T&)
+ { /* recursion stop */ }
+};
+
+
+template<std::size_t Depth>
struct compute_lattice
{
- typedef void result_type;
- template<typename Int, typename T, std::size_t BitCount, std::size_t Dimension>
- void operator()(Int, T (&cj)[BitCount][Dimension]) const
+ BOOST_STATIC_ASSERT( Depth != 0 );
+
+ template<typename T, int BitCount, std::size_t Dimension>
+ static void apply(T (&cj)[BitCount][Dimension])
{
enum {
- iteration = Int::value,
+ iteration = Dimension - Depth + 1,
px_value = primitive_polynomial<iteration>::value,
degree_i = primitive_polynomial<iteration>::degree
};
// Leading elements for dimension i come from vinit<>.
- mpl::for_each< mpl::range_c<std::size_t, 0, degree_i> >(
- bind(leading_elements<iteration>(), _1, ref(cj)) );
+ //for(int k = 0; k < degree_i; ++k )
+ // cj[k][iteration] = v_init[k][iteration];
+ leading_elements<degree_i>::template assign<iteration>(cj);
// Expand the polynomial bit pattern to separate
// components of the logical array includ[].
@@ -214,7 +223,7 @@
// Calculate remaining elements for this dimension,
// as explained in Bratley+Fox, section 2.
- for(std::size_t j = degree_i; j < BitCount; ++j)
+ for(int j = degree_i; j < BitCount; ++j)
{
T p = 2;
T w = cj[j - degree_i][iteration];
@@ -223,9 +232,19 @@
w ^= (cj[j-k-1][iteration] * p);
cj[j][iteration] = w;
}
+
+ compute_lattice<Depth - 1>::apply(cj);
}
};
+template<>
+struct compute_lattice<1>
+{
+ template<typename T>
+ static void apply(const T&)
+ { /* recursion stop */ }
+};
+
} // namespace sbl
template<typename IntType, std::size_t Dimension>
@@ -250,13 +269,12 @@
bits[k][0] = 1;
// Initialize in remaining dimensions.
- mpl::for_each< mpl::range_c<std::size_t, 1, Dimension> >(
- bind(sbl::compute_lattice(), _1, ref(bits)) );
+ sbl::compute_lattice<Dimension>::apply(bits);
// Multiply columns of v by appropriate power of 2.
IntType p = 2;
for(int j = bit_count-1-1; j >= 0; --j, p <<= 1)
- for(std::size_t k = 0; k != Dimension; ++k)
+ for(std::size_t k = 0; k != Dimension; ++k )
bits[j][k] *= p;
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk