Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75588 - in sandbox/math_constants: boost/math/constants libs/math/test
From: john_at_[hidden]
Date: 2011-11-21 06:42:20


Author: johnmaddock
Date: 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
New Revision: 75588
URL: http://svn.boost.org/trac/boost/changeset/75588

Log:
Add tentative cpp_float support.
Add Euler-Gamma calculation.
Update constant values.
Change constant initialization to be lock free.
Added:
   sandbox/math_constants/libs/math/test/cpp_float_test.cpp (contents, props changed)
Text files modified:
   sandbox/math_constants/boost/math/constants/calculate_constants.hpp | 88 ++++++++++++++++++++++++++++-
   sandbox/math_constants/boost/math/constants/constants.hpp | 120 ++++++++++++++++++++++++++++++----------
   sandbox/math_constants/boost/math/constants/generate.hpp | 8 ++
   sandbox/math_constants/boost/math/constants/info.hpp | 4 +
   sandbox/math_constants/libs/math/test/test_constant_generate.cpp | 20 ++++++
   sandbox/math_constants/libs/math/test/test_constants.cpp | 12 +++-
   sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp | 2
   7 files changed, 217 insertions(+), 37 deletions(-)

Modified: sandbox/math_constants/boost/math/constants/calculate_constants.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/calculate_constants.hpp (original)
+++ sandbox/math_constants/boost/math/constants/calculate_constants.hpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -12,7 +12,54 @@
 inline T calculate_pi(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
    BOOST_MATH_STD_USING
- return 2 * acos(static_cast<T>(0));
+
+ return ldexp(acos(T(0)), 1);
+
+ /*
+ // Although this code works well, it's usually more accurate to just call acos
+ // and access the numner types own representation of PI which is usually calculated
+ // at slightly higher precision...
+
+ T result;
+ T a = 1;
+ T b;
+ T A(a);
+ T B = 0.5f;
+ T D = 0.25f;
+
+ T lim;
+ lim = boost::math::tools::epsilon<T>();
+
+ unsigned k = 1;
+
+ do
+ {
+ result = A + B;
+ result = ldexp(result, -2);
+ b = sqrt(B);
+ a += b;
+ a = ldexp(a, -1);
+ A = a * a;
+ B = A - result;
+ B = ldexp(B, 1);
+ result = A - B;
+ bool neg = boost::math::sign(result) < 0;
+ if(neg)
+ result = -result;
+ if(result <= lim)
+ break;
+ if(neg)
+ result = -result;
+ result = ldexp(result, k - 1);
+ D -= result;
+ ++k;
+ lim = ldexp(lim, 1);
+ }
+ while(true);
+
+ result = B / D;
+ return result;
+ */
 }
 
 template <class T, int N>
@@ -58,6 +105,11 @@
 template <class T, int N>
 inline T calculate_e(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
+ //
+ // Although we can clearly calculate this from first principles, this hooks into
+ // T's own notion of e, which hopefully will more accurate than one calculated to
+ // a few epsilon:
+ //
    BOOST_MATH_STD_USING
    return exp(static_cast<T>(1));
 }
@@ -71,8 +123,33 @@
 template <class T, int N>
 inline T calculate_euler(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
- throw std::runtime_error("A true arbitrary precision Euler's constant is not available - it's too expensive to calculate on the fly - this constant is only supported up to 100 decimal digits.");
- return 0;
+ //
+ // This is the method described in:
+ // "Some New Algorithms for High-Precision Computation of Euler's Constant"
+ // Richard P Brent and Edwin M McMillan.
+ // Mathematics of Comnputation, Volume 34, Number 149, Jan 1980, pages 305-312.
+ // See equation 17 with p = 2.
+ //
+ T n = 3 + boost::math::tools::digits<T>() / 4;
+ T lnn = log(n);
+ T term = 1;
+ T N = -lnn;
+ T D = 1;
+ T Hk = 0;
+ T one = 1;
+
+ for(unsigned k = 1;; ++k)
+ {
+ term *= n * n;
+ term /= k * k;
+ Hk += one / k;
+ N += term * (Hk - lnn);
+ D += term;
+
+ if(term < D * boost::math::tools::epsilon<T>())
+ break;
+ }
+ return N / D;
 }
 
 template <class T, int N>
@@ -92,6 +169,11 @@
 template <class T, int N>
 inline T calculate_ln_two(const mpl::int_<N>&BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
 {
+ //
+ // Although there are good ways to calculate this from scratch, this hooks into
+ // T's own notion of log(2) which will hopefully be accurate to the full precision
+ // of T:
+ //
    BOOST_MATH_STD_USING
    return log(static_cast<T>(2));
 }

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 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -22,9 +22,6 @@
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/int.hpp>
 #include <boost/type_traits/is_convertible.hpp>
-#ifdef BOOST_HAS_THREADS
-# include <boost/thread/once.hpp>
-#endif
 
 namespace boost{ namespace math
 {
@@ -94,6 +91,73 @@
 #define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix)
 #endif
 
+ namespace detail{
+
+ template <class Real>
+ Real convert_from_string(const char* p, const mpl::false_&)
+ {
+ return boost::lexical_cast<Real>(p);
+ }
+ template <class Real>
+ const char* convert_from_string(const char* p, const mpl::true_&)
+ {
+ return p;
+ }
+
+ template <class T, T (*F)(BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+ struct constant_initializer
+ {
+ static void do_nothing()
+ {
+ init.do_nothing();
+ }
+ private:
+ struct initializer
+ {
+ initializer()
+ {
+ F(
+ #ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
+ 0
+ #endif
+ );
+ }
+ void do_nothing()const{}
+ };
+ static const initializer init;
+ };
+
+ template <class T, T (*F)(BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+ typename constant_initializer<T, F>::initializer const constant_initializer<T, F>::init;
+
+ template <class T, int N, T (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+ struct constant_initializer2
+ {
+ static void do_nothing()
+ {
+ init.do_nothing();
+ }
+ private:
+ struct initializer
+ {
+ initializer()
+ {
+ F(
+ #ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
+ mpl::int_<N>() , 0
+ #endif
+ );
+ }
+ void do_nothing()const{}
+ };
+ static const initializer init;
+ };
+
+ template <class T, int N, T (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpl::int_<N>) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+ typename constant_initializer2<T, N, F>::initializer const constant_initializer2<T, N, F>::init;
+
+ }
+
    #define BOOST_DEFINE_MATH_CONSTANT(name, x, y, exp)\
    namespace detail{\
    /* Forward declaration of the calculation method, just in case it's not been provided yet */ \
@@ -102,12 +166,12 @@
    /* The default implementations come next: */ \
    template <class T> inline T BOOST_JOIN(string_get_, name)(BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
- static const T result = ::boost::lexical_cast<T>(BOOST_STRINGIZE(BOOST_JOIN(BOOST_JOIN(x, y), BOOST_JOIN(e, exp))));\
+ static const T result = detail::convert_from_string<T>(BOOST_STRINGIZE(BOOST_JOIN(BOOST_JOIN(x, y), BOOST_JOIN(e, exp))), boost::is_convertible<const char*, T>());\
       return result;\
    }\
    template <class T> inline T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_string>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))\
    {\
- BOOST_MATH_CONSTANT_THREAD_HELPER(name, string_)\
+ constant_initializer<T, & BOOST_JOIN(string_get_, name)<T> >::do_nothing();\
       return BOOST_JOIN(string_get_, name)<T>();\
    }\
    template <class T> inline BOOST_CONSTEXPR T BOOST_JOIN(get_, name)(const mpl::int_<construct_from_float>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
@@ -121,7 +185,7 @@
    { static const T result = BOOST_JOIN(calculate_, name)<T>(mpl::int_<N>()); return result; }\
    template <class T, int N> inline T BOOST_JOIN(get_, name)(const mpl::int_<N>& n BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))\
    {\
- BOOST_MATH_CONSTANT_THREAD_HELPER(name, compute_)\
+ constant_initializer2<T, N, & BOOST_JOIN(compute_get_, name)<T, N> >::do_nothing();\
       return BOOST_JOIN(compute_get_, name)<T, N>(); \
    }\
    /* This one is for true arbitary precision, which may well vary at runtime: */ \
@@ -143,31 +207,27 @@
    namespace long_double_constants{ static const long double name = BOOST_JOIN(BOOST_JOIN(x, BOOST_JOIN(e, exp)), L); }\
    namespace constants{
 
- BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884197169399375105820974944, 59230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196, 0)
- BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.2831853071795864769252867665590057683943388015061, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 0.70710678118654752440084436210484903928483593756084, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.7724538509055160272981674833411451827975, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626503, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253007, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.1774100225154746910115693264596996377473856893858205385225257565000, 2658854698492680841813836877081, 0)
- BOOST_DEFINE_MATH_CONSTANT(e, 2.7182818284590452353602874713526624977572470936999595749669676, 27724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011, 0)
- BOOST_DEFINE_MATH_CONSTANT(half, 0.5, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(euler, 0.577215664901532860606512090082402431042159335939923598805, 76723488486, 0)
- BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078569671875376948073, 17667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206, 0)
- BOOST_DEFINE_MATH_CONSTANT(half_root_two, 0.70710678118654752440084436210484903928483593756084, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(ln_two, 0.693147180559945309417232121458176568075500134360255254, 120680009493393621969694715605863326996418687, 0)
- BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -0.36651292058166432701243915823266946945426344783710526305367771367056, 16153193527385494558228566989083583025230453648347655663425171940646634, 0)
- BOOST_DEFINE_MATH_CONSTANT(third, 0.3333333333333333333333333333333333333333333333333333333333333333333333, 3333333333333333333333333333333333333333333333333333333333333333333333333, 0)
- BOOST_DEFINE_MATH_CONSTANT(twothirds, 0.66666666666666666666666666666666666666666666666666666666666666666666, 66666666666666666666666666666666666666666666666666666666666666666666667, 0)
- BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 0.141592653589793238462643383279502884197169399375105820974944, 59230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196, 0)
- BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 0.85840734641020676153735661672049711580283060062489417902505540769218359, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 0.79531676737159754434839533505680658072763917332771320544530223438582161, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 0.6065306597126334236037995349911804534419181354871869556828921587350565194137, 484239986476115079894560, 0)
- BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 0.70710678118654752440084436210484903928483593756084, 0, 0)
- BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 0.39894228040143267793994605993438186847585863095671, 0, 0)
-
+BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884, 1971693993751058209749445923078164062862089986280348253421170679821480865, 0);
+BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768, 394338798750211641949889184615632812572417997256069650684234135964296173, 0);
+BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620, 3445964574045644874766734405889679763422653509011380276625308595607284273, -1);
+BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182, 7975494561223871282138077898529112845910321813749506567385446654162268236, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626, 5034933703049691583149617881711468273039209874732979191890286330580049863, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253,0069867406099383166299235763422936546078419749465958383780572661160099727, 0);
+BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637, 7473856893858205385225257565000265885469849268084181383687708110674715786, 0);
+BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497, 7572470936999595749669676277240766303535475945713821785251664274274663919, 0);
+BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310, 4215933593992359880576723488486772677766467093694706329174674951463144725, -1);
+BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078, 5696718753769480731766797379907324784621070388503875343276415727350138462, 0);
+BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392, 8483593768847403658833986899536623923105351942519376716382078636750692312, -1);
+BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680, 7550013436025525412068000949339362196969471560586332699641868754200148102, -1);
+BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694, 5426344783710526305367771367056161531935273854945582285669890835830252305, -1);
+BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333, 3333333333333333333333333333333333333333333333333333333333333333333333333, -1);
+BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666, 6666666666666666666666666666666666666666666666666666666666666666666666667, -1);
+BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841, 9716939937510582097494459230781640628620899862803482534211706798214808651, -1);
+BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158, 0283060062489417902505540769218359371379100137196517465788293201785191349, -1);
+BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807, 2763917332771320544530223438885626826751818759075800688860082843683980018, -1);
+BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534, 4191813548718695568289215873505651941374842399864761150798945602642378979, -1);
 
- } // namespace constants
+} // namespace constants
 } // namespace math
 } // namespace boost
 

Modified: sandbox/math_constants/boost/math/constants/generate.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/generate.hpp (original)
+++ sandbox/math_constants/boost/math/constants/generate.hpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -16,6 +16,8 @@
 #include <boost/math/bindings/mpfr.hpp>
 #elif defined(USE_MPREAL)
 #include <boost/math/bindings/mpreal.hpp>
+#elif defined(USE_CPP_FLOAT)
+#include <boost/multiprecision/cpp_float.hpp>
 #else
 #include <boost/math/bindings/rr.hpp>
 #endif
@@ -26,6 +28,8 @@
 typedef mpfr_class generator_type;
 #elif defined(USE_MPREAL)
 typedef mpfr::mpreal generator_type;
+#elif defined(USE_CPP_FLOAT)
+typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_float<500> > generator_type;
 #else
 typedef ntl::RR generator_type;
 #endif
@@ -36,13 +40,15 @@
    mpfr_class::set_dprec(((200 + 1) * 1000L) / 301L);
 #elif defined(USE_MPREAL)
    mpfr::mpreal::set_default_prec(((200 + 1) * 1000L) / 301L);
+#elif defined(USE_CPP_FLOAT)
+ // Nothing to do, precision is already set.
 #else
    ntl::RR::SetPrecision(((200 + 1) * 1000L) / 301L);
    ntl::RR::SetOutputPrecision(102);
 #endif
    generator_type value = f(boost::mpl::int_<0>());
    std::stringstream os;
- os << std::setprecision(102) << std::scientific;
+ os << std::setprecision(110) << std::scientific;
    os << value;
    std::string s = os.str();
    static const regex e("([+-]?\\d+(?:\\.\\d{0,36})?)(\\d*)(?:e([+-]?\\d+))?");

Modified: sandbox/math_constants/boost/math/constants/info.hpp
==============================================================================
--- sandbox/math_constants/boost/math/constants/info.hpp (original)
+++ sandbox/math_constants/boost/math/constants/info.hpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -108,6 +108,10 @@
       os <<
          "The constant will be constructed from a string (and the result cached).\n";
       break;
+ default:
+ os <<
+ "The constant will be calculated (and the result cached).\n";
+ break;
    }
    os << std::endl;
 #ifdef BOOST_MSVC

Added: sandbox/math_constants/libs/math/test/cpp_float_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/math_constants/libs/math/test/cpp_float_test.cpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -0,0 +1,153 @@
+// cpp_float_test.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/constants/info.hpp>
+#include <boost/multiprecision/cpp_float.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T>
+T brent_gamma()
+{
+ T n = 3 + boost::math::tools::digits<T>() / 4;
+ T lnn = log(n);
+ T term = 1;
+ T N = -lnn;
+ T D = 1;
+ T Hk = 0;
+ T one = 1;
+
+ for(unsigned k = 1;; ++k)
+ {
+ term *= n * n;
+ term /= k * k;
+ Hk += one / k;
+ N += term * (Hk - lnn);
+ D += term;
+
+ if(term < D * boost::math::tools::epsilon<T>())
+ break;
+ }
+ return N / D;
+}
+
+template <class T>
+T eg()
+{
+ T n = boost::math::tools::digits<T>() * 4;
+ T k_fact = 1;
+ T A = 0;
+ T B = 1;
+ T H = 0;
+ T n_k = 1;
+
+ for(unsigned k = 1;; ++k)
+ {
+ H += T(1) / k;
+ k_fact *= k;
+ n_k *= n;
+ T term = n_k / (k_fact * k_fact);
+ A += term * H;
+ B += term;
+
+ if((term < B * boost::math::tools::epsilon<T>()) && (term * H < A * boost::math::tools::epsilon<T>()))
+ break;
+ }
+ return A / B - log(n) / 2;
+}
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > log2 =
+ "6.931471805599453094172321214581765680755001343602552541206800094933936219696947"
+ "15605863326996418687542001481020570685733685520235758130557032670751635075961930"
+ "72757082837143519030703862389167347112335011536449795523912047517268157493206515"
+ "55247341395258829504530070953263666426541042391578149520437404303855008019441706"
+ "41671518644712839968171784546957026271631064546150257207402481637773389638550695"
+ "26066834113727387372292895649354702576265209885969320196505855476470330679365443"
+ "25476327449512504060694381471046899465062201677204245245296126879465461931651746"
+ "81392672504103802546259656869144192871608293803172714367782654877566485085674077"
+ "64845146443994046142260319309673540257444607030809608504748663852313818167675143"
+ "86674766478908814371419854942315199735488037516586127535291661000710535582498794"
+ "14729509293113897155998205654392871700072180857610252368892132449713893203784393"
+ "53088774825970171559107088236836275898425891853530243634214367061189236789192372"
+ "31467232172053401649256872747782344535348e-1";
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > pi =
+ "3.141592653589793238462643383279502884197169399375105820974944592307816406286208"
+ "99862803482534211706798214808651328230664709384460955058223172535940812848111745"
+ "02841027019385211055596446229489549303819644288109756659334461284756482337867831"
+ "65271201909145648566923460348610454326648213393607260249141273724587006606315588"
+ "17488152092096282925409171536436789259036001133053054882046652138414695194151160"
+ "94330572703657595919530921861173819326117931051185480744623799627495673518857527"
+ "24891227938183011949129833673362440656643086021394946395224737190702179860943702"
+ "77053921717629317675238467481846766940513200056812714526356082778577134275778960"
+ "91736371787214684409012249534301465495853710507922796892589235420199561121290219"
+ "60864034418159813629774771309960518707211349999998372978049951059731732816096318"
+ "59502445945534690830264252230825334468503526193118817101000313783875288658753320"
+ "83814206171776691473035982534904287554687311595628638823537875937519577818577805"
+ "32171226806613001927876611195909216420199";
+
+boost::multiprecision::mp_number<boost::multiprecision::cpp_float<1000> > euler =
+ "5.772156649015328606065120900824024310421593359399235988057672348848677267776646"
+ "70936947063291746749514631447249807082480960504014486542836224173997644923536253"
+ "50033374293733773767394279259525824709491600873520394816567085323315177661152862"
+ "11995015079847937450857057400299213547861466940296043254215190587755352673313992"
+ "54012967420513754139549111685102807984234877587205038431093997361372553060889331"
+ "26760017247953783675927135157722610273492913940798430103417771778088154957066107"
+ "50101619166334015227893586796549725203621287922655595366962817638879272680132431"
+ "01047650596370394739495763890657296792960100901512519595092224350140934987122824"
+ "79497471956469763185066761290638110518241974448678363808617494551698927923018773"
+ "91072945781554316005002182844096053772434203285478367015177394398700302370339518"
+ "32869000155819398804270741154222781971652301107356583396734871765049194181230004"
+ "06546931429992977795693031005030863034185698032310836916400258929708909854868257"
+ "77364288253954925873629596133298574739302e-1";
+
+/*
+template <class T>
+void test()
+{
+ T p = boost::math::constants::pi<T>();
+ T err = fabs((p - T(pi)) / T(pi)) / boost::math::tools::epsilon<T>();
+ unsigned e = err.template convert_to<unsigned>();
+ BOOST_TEST(e < 30);
+}
+*/
+template <unsigned N>
+void test()
+{
+ typedef boost::multiprecision::mp_number<boost::multiprecision::cpp_float<N> > mp_t;
+ mp_t val = boost::math::constants::euler<mp_t>();
+ mp_t err = fabs((val - mp_t(euler)) / (mp_t(euler) * std::numeric_limits<mp_t>::epsilon()));
+ unsigned error = err.template convert_to<unsigned>();
+ BOOST_TEST(error < 30);
+
+ val = boost::math::constants::pi<mp_t>();
+ err = fabs((val - mp_t(pi)) / (mp_t(pi) * std::numeric_limits<mp_t>::epsilon()));
+ error = err.template convert_to<unsigned>();
+ BOOST_TEST(error < 30);
+
+ val = boost::math::constants::ln_two<mp_t>();
+ err = fabs((val - mp_t(log2)) / (mp_t(log2) * std::numeric_limits<mp_t>::epsilon()));
+ error = err.template convert_to<unsigned>();
+ BOOST_TEST(error < 30);
+}
+
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+ boost::math::constants::print_info_on_type<boost::multiprecision::cpp_float_50>();
+ boost::math::constants::print_info_on_type<boost::multiprecision::cpp_float_100>();
+ boost::math::constants::print_info_on_type<boost::multiprecision::mp_number<boost::multiprecision::cpp_float<300> > >();
+
+ test<15>();
+ test<30>();
+ test<50>();
+ test<100>();
+ test<200>();
+ test<300>();
+ test<500>();
+
+ return boost::report_errors();
+}
+

Modified: sandbox/math_constants/libs/math/test/test_constant_generate.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_constant_generate.cpp (original)
+++ sandbox/math_constants/libs/math/test/test_constant_generate.cpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -10,6 +10,26 @@
 int main()
 {
    BOOST_CONSTANTS_GENERATE(pi);
+ BOOST_CONSTANTS_GENERATE(two_pi);
+ BOOST_CONSTANTS_GENERATE(one_div_two_pi);
+ BOOST_CONSTANTS_GENERATE(root_pi);
+ BOOST_CONSTANTS_GENERATE(root_half_pi);
+ BOOST_CONSTANTS_GENERATE(root_two_pi);
+ BOOST_CONSTANTS_GENERATE(root_ln_four);
+ BOOST_CONSTANTS_GENERATE(e);
+ BOOST_CONSTANTS_GENERATE(euler);
+ BOOST_CONSTANTS_GENERATE(root_two);
+ BOOST_CONSTANTS_GENERATE(half_root_two);
+ BOOST_CONSTANTS_GENERATE(ln_two);
+ BOOST_CONSTANTS_GENERATE(ln_ln_two);
+ BOOST_CONSTANTS_GENERATE(third);
+ BOOST_CONSTANTS_GENERATE(twothirds);
+ BOOST_CONSTANTS_GENERATE(pi_minus_three);
+ BOOST_CONSTANTS_GENERATE(four_minus_pi);
+ BOOST_CONSTANTS_GENERATE(pow23_four_minus_pi);
+ BOOST_CONSTANTS_GENERATE(exp_minus_half);
+ BOOST_CONSTANTS_GENERATE(one_div_root_two);
+ BOOST_CONSTANTS_GENERATE(one_div_root_two_pi);
    return 0;
 }
 

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 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -8,8 +8,6 @@
 
 // test_constants.cpp
 
-#include <pch.hpp>
-
 #include <boost/math/concepts/real_concept.hpp> // for real_concept
 #include <boost/test/test_exec_monitor.hpp> // Boost.Test
 #include <boost/test/floating_point_comparison.hpp>
@@ -17,6 +15,7 @@
 #include <boost/math/constants/constants.hpp>
 #include <boost/math/tools/test.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.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));
@@ -41,7 +40,7 @@
 public:
    big_real_concept() {}
    template <class T>
- big_real_concept(const T& t) : real_concept(t) {}
+ big_real_concept(const T& t, typename enable_if<is_convertible<T, real_concept> >::type* = 0) : real_concept(t) {}
 };
 
 }
@@ -63,7 +62,10 @@
    // Actual tolerance is never really smaller than epsilon for long double, even if some of our
    // test types pretend otherwise:
    //
+ typedef typename boost::math::constants::construction_traits<RealType, boost::math::policies::policy<> >::type construction_type;
    RealType tolerance = std::max(static_cast<RealType>(boost::math::tools::epsilon<long double>()), boost::math::tools::epsilon<RealType>()) * 2; // double
+ if((construction_type::value == 0) && (boost::math::tools::digits<RealType>() > boost::math::constants::max_string_digits))
+ tolerance *= 30; // allow a little extra tolerance for calculated constants.
    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;
@@ -74,6 +76,10 @@
    using namespace std; // Help ADL of std exp, log...
    using std::exp;
 
+ RealType a = pi<RealType>();
+ RealType b = static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L);
+ a = fabs((a-b) / b);
+
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L), pi<RealType>(), tolerance);
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(3.14159265358979323846264338327950288419716939937510L), (pi<RealType, boost::math::policies::policy<> >)(), tolerance);
    BOOST_CHECK_CLOSE_FRACTION(static_cast<RealType>(sqrt(3.14159265358979323846264338327950288419716939937510L)), root_pi<RealType>(), tolerance);

Modified: sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp
==============================================================================
--- sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp (original)
+++ sandbox/math_constants/libs/math/test/test_print_info_on_type.cpp 2011-11-21 06:42:15 EST (Mon, 21 Nov 2011)
@@ -8,6 +8,8 @@
 #include <boost/math/constants/info.hpp>
 #include <boost/math/concepts/real_concept.hpp>
 
+#include <boost/multiprecision/cpp_float.hpp>
+
 
 int main()
 {


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