Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66798 - in sandbox/math_constants: boost/math/constants libs/math/test
From: john_at_[hidden]
Date: 2010-11-27 12:16:33


Author: johnmaddock
Date: 2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
New Revision: 66798
URL: http://svn.boost.org/trac/boost/changeset/66798

Log:
Policy enable the getter functions.
Text files modified:
   sandbox/math_constants/boost/math/constants/constants.hpp | 69 ++++++++++++++++++++++++---------------
   sandbox/math_constants/libs/math/test/test_constants.cpp | 63 +++++++++++++++++++++++++++++++++++
   2 files changed, 104 insertions(+), 28 deletions(-)

Modified: sandbox/math_constants/boost/math/constants/constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/constants.hpp (original)
+++ sandbox/math_constants/boost/math/constants/constants.hpp 2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
@@ -17,7 +17,10 @@
 #ifdef BOOST_MSVC
 #pragma warning(pop)
 #endif
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
 #include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 
 namespace boost{ namespace math
 {
@@ -39,37 +42,49 @@
 
    enum construction_method
    {
- construct_from_float = 0,
- construct_from_double = 1,
- construct_from_long_double = 2,
- construct_from_string = 3,
- construct_from_calculation = 4,
+ construct_from_float = 1,
+ construct_from_double = 2,
+ construct_from_long_double = 3,
+ construct_from_string = 4,
    };
 
- template <class Real>
+ //
+ // Max number of binary digits in the string representations
+ // of our constants:
+ //
+ BOOST_STATIC_CONSTANT(int, max_string_digits = (101 * 1000L) / 301L);
+
+ template <class Real, class Policy>
    struct construction_traits
    {
- BOOST_STATIC_CONSTANT(construction_method, value = construct_from_string);
- };
- template <>
- struct construction_traits<float>
- {
- BOOST_STATIC_CONSTANT(construction_method, value = construct_from_float);
- };
- template <>
- struct construction_traits<double>
- {
- BOOST_STATIC_CONSTANT(construction_method, value = construct_from_double);
- };
- template <>
- struct construction_traits<long double>
- {
- BOOST_STATIC_CONSTANT(construction_method, value = construct_from_long_double);
+ private:
+ typedef typename policies::precision<Real, Policy>::type t1;
+ typedef typename policies::precision<float, Policy>::type t2;
+ typedef typename policies::precision<double, Policy>::type t3;
+ typedef typename policies::precision<long double, Policy>::type t4;
+ public:
+ typedef typename mpl::if_<
+ mpl::and_<boost::is_convertible<float, Real>, mpl::bool_< t1::value <= t2::value>, mpl::bool_<0 != t1::value> >,
+ mpl::int_<construct_from_float>,
+ typename mpl::if_<
+ mpl::and_<boost::is_convertible<double, Real>, mpl::bool_< t1::value <= t3::value>, mpl::bool_<0 != t1::value> >,
+ mpl::int_<construct_from_double>,
+ typename mpl::if_<
+ mpl::and_<boost::is_convertible<long double, Real>, mpl::bool_< t1::value <= t4::value>, mpl::bool_<0 != t1::value> >,
+ mpl::int_<construct_from_long_double>,
+ typename mpl::if_<
+ mpl::and_<mpl::bool_< t1::value <= max_string_digits>, mpl::bool_<0 != t1::value> >,
+ mpl::int_<construct_from_string>,
+ mpl::int_<t1::value>
+ >::type
+ >::type
+ >::type
+ >::type type;
    };
 
    #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\
    /* Forward declaration of the calculation method, just in case it's not been provided yet */ \
- template <class T> T BOOST_JOIN(calculate_, name)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)); \
+ template <class T> T BOOST_JOIN(calculate_, name)(int BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T)); \
    /* The default implementations come next: */ \
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_string>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
@@ -82,13 +97,13 @@
    { return BOOST_JOIN(x, BOOST_JOIN(e, exp)); }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_long_double>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { return BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), L); }\
- template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_calculation>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
- { static const T result = BOOST_JOIN(calculate_, name)<T>(); return result; }\
+ template <class T, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
+ { static const T result = BOOST_JOIN(calculate_, name)<T>(N ? N : tools::digits<T>()); return result; }\
    /* The actual forwarding function: */ \
+ template <class T, class Policy> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))\
+ { return BOOST_JOIN(get_, name)<T>(typename construction_traits<T, Policy>::type()); }\
    template <class T> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    { return name<T, boost::math::policies::policy<> >(); }\
- template <class T, class Policy> inline T name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy))\
- { return BOOST_JOIN(get_, name)<T>(mpl::int_<construction_traits<T>::value>()); }\
    /* Now the namespace specific versions: */ \
    } namespace float_constants{ static const float name = BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), F); }\
    namespace double_constants{ static const double name = BOOST_JOIN(x, BOOST_JOIN(e, exp)); } \

Modified: sandbox/math_constants/libs/math/test/test_constants.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_constants.cpp (original)
+++ sandbox/math_constants/libs/math/test/test_constants.cpp 2010-11-27 12:16:31 EST (Sat, 27 Nov 2010)
@@ -16,6 +16,18 @@
 
 #include <boost/math/constants/constants.hpp>
 #include <boost/math/tools/test.hpp>
+#include <boost/static_assert.hpp>
+
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<float, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_float> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<double, boost::math::policies::policy<> >::type, boost::mpl::int_<boost::math::constants::construct_from_double> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<long double, boost::math::policies::policy<> >::type, boost::mpl::int_<(sizeof(double) == sizeof(long double) ? boost::math::constants::construct_from_double : boost::math::constants::construct_from_long_double)> >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, boost::math::policies::policy<> >::type, boost::mpl::int_<0> >::value));
+
+typedef boost::math::policies::policy<boost::math::policies::digits2<LDBL_MANT_DIG> > real_concept_policy_1;
+typedef boost::math::policies::policy<boost::math::policies::digits2<LDBL_MANT_DIG + 2> > real_concept_policy_2;
+
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, real_concept_policy_1 >::type, boost::mpl::int_<(sizeof(double) == sizeof(long double) ? boost::math::constants::construct_from_double : boost::math::constants::construct_from_long_double) > >::value));
+BOOST_STATIC_ASSERT((boost::is_same<boost::math::constants::construction_traits<boost::math::concepts::real_concept, real_concept_policy_2 >::type, boost::mpl::int_<boost::math::constants::construct_from_string> >::value));
 
 template <class RealType>
 void test_spots(RealType)
@@ -25,6 +37,10 @@
    RealType tolerance = boost::math::tools::epsilon<RealType>() * 2; // double
    std::cout << "Tolerance for type " << typeid(RealType).name() << " is " << tolerance << "." << std::endl;
 
+ //typedef typename boost::math::policies::precision<RealType, boost::math::policies::policy<> >::type t1;
+
+ //std::cout << "Precision for type " << typeid(RealType).name() << " is " << t1::value << "." << std::endl;
+
    using namespace boost::math::constants;
    using namespace std; // Help ADL of std exp, log...
    using std::exp;
@@ -157,6 +173,47 @@
 
 } // template <class RealType>void test_spots(RealType)
 
+template <class Policy>
+void test_real_concept_policy(const Policy&)
+{
+ // Basic sanity checks for constants.
+
+ boost::math::concepts::real_concept tolerance = boost::math::tools::epsilon<boost::math::concepts::real_concept>() * 2; // double
+ std::cout << "Tolerance for type " << typeid(boost::math::concepts::real_concept).name() << " is " << tolerance << "." << std::endl;
+
+ //typedef typename boost::math::policies::precision<boost::math::concepts::real_concept, boost::math::policies::policy<> >::type t1;
+
+ //std::cout << "Precision for type " << typeid(boost::math::concepts::real_concept).name() << " is " << t1::value << "." << std::endl;
+
+ using namespace boost::math::constants;
+ using namespace std; // Help ADL of std exp, log...
+ using std::exp;
+
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(3.14159265358979323846264338327950288419716939937510L), (pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L)), (root_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L/2)), (root_half_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(3.14159265358979323846264338327950288419716939937510L * 2)), (root_two_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(log(4.0L))), (root_ln_four<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(2.71828182845904523536028747135266249775724709369995L), (e<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.5), (half<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.57721566490153286060651209008240243104259335L), (euler<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(sqrt(2.0L)), (root_two<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(log(2.0L)), (ln_two<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(log(log(2.0L))), (ln_ln_two<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(1)/3, (third<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(2)/3, (twothirds<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(0.14159265358979323846264338327950288419716939937510L), (pi_minus_three<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(4. - 3.14159265358979323846264338327950288419716939937510L), (four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(pow((4 - 3.14159265358979323846264338327950288419716939937510L), 1.5L)), (pow23_four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(exp(-0.5L)), (exp_minus_half<boost::math::concepts::real_concept, Policy>)(), tolerance);
+#else
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(pow((4 - 3.14159265358979323846264338327950288419716939937510), 1.5)), (pow23_four_minus_pi<boost::math::concepts::real_concept, Policy>)(), tolerance);
+ BOOST_CHECK_CLOSE_FRACTION(static_cast<boost::math::concepts::real_concept>(exp(-0.5)), (exp_minus_half<boost::math::concepts::real_concept, Policy>)(), tolerance);
+#endif
+
+} // template <class boost::math::concepts::real_concept>void test_spots(boost::math::concepts::real_concept)
+
 int test_main(int, char* [])
 {
    // Basic sanity-check spot values.
@@ -165,13 +222,17 @@
    test_double_spots();
    test_long_double_spots();
 
+ test_real_concept_policy(real_concept_policy_1());
+ test_real_concept_policy(real_concept_policy_2());
+ test_real_concept_policy(boost::math::policies::policy<>());
+
    // (Parameter value, arbitrarily zero, only communicates the floating point type).
    test_spots(0.0F); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
    test_spots(0.0); // Test double. OK at decdigits 7, tolerance = 1e07 %
 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
    test_spots(0.0L); // Test long double.
 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0582))
- test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
+ //test_spots(boost::math::concepts::real_concept(0.)); // Test real concept.
 #endif
 #else
   std::cout << "<note>The long double tests have been disabled on this platform "


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