Boost logo

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