// Copyright Paul Bristow 2007, 2011. // Copyright John Maddock 2006, 2011. // Use, modification and distribution are subject to 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) // Check values of constants are drawn from an independent source, or calculated. // Both must be at long double precision for the most precise compilers floating-point implementation. // So all values use static_cast() of values at least 40 decimal digits // and that have suffix L to ensure floating-point type is long double. // Steve Moshier's command interpreter V1.3 100 digits calculator used for some values. #ifdef _MSC_VER # pragma warning(disable : 4127) // conditional expression is constant. #endif #include "math_unit_test.hpp" #include // for real_concept #include #include #ifdef BOOST_MATH_HAS_FLOAT128 #include #endif #include #include #include #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) #include // Check at compile time that the construction method for constants of type float, is "construct from a float", or "construct from a double", ... static_assert((std::is_same>::type, std::integral_constant>::value), "Need to be able to construct from float"); static_assert((std::is_same>::type, std::integral_constant>::value), "Need to be able to construct from double"); static_assert((std::is_same>::type, std::integral_constant>::value), "Need to be able to construct from long double"); static_assert((std::is_same>::type, std::integral_constant>::value), "Need to be able to construct from real_concept"); // Policy to set precision at maximum possible using long double. using real_concept_policy_1 = boost::math::policies::policy::digits>>; // Policy with precision +2 (could be any reasonable value), // forces the precision of the policy to be greater than // that of a long double, and therefore triggers different code (construct from string). #ifdef BOOST_MATH_USE_FLOAT128 using real_concept_policy_2 = boost::math::policies::policy>; #else using real_concept_policy_2 = boost::math::policies::policy::digits + 2>>; #endif // Policy with precision greater than the string representations, forces computation of values (i.e. different code path): using real_concept_policy_3 = boost::math::policies::policy>; static_assert((std::is_same::type, std::integral_constant>::value), "Need to be able to construct from long double"); static_assert((std::is_same::type, std::integral_constant>::value), "Need to be able to construct integer from string"); static_assert((boost::math::constants::construction_traits::type::value >= 5), "Need 5 digits"); #endif // C++11 // We need to declare a conceptual type whose precision is unknown at // compile time, and is so enormous when checked at runtime, // that we're forced to calculate the values of the constants ourselves. namespace boost{ namespace math{ namespace concepts{ class big_real_concept : public real_concept { public: big_real_concept() {} template big_real_concept(const T& t, typename std::enable_if::value, bool>::type = false) : real_concept(t) {} }; inline int itrunc(const big_real_concept& val) { BOOST_MATH_STD_USING return itrunc(val.value()); } } namespace tools{ template <> inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept { return 2 * boost::math::constants::max_string_digits; } }}} template void test_spots(RealType) { // Basic sanity checks for constants, // where template parameter RealType can be float, double, long double, // or real_concept, a prototype for user-defined floating-point types. // Parameter RealType is only used to communicate the RealType, // and is an arbitrary zero for all tests. //typedef typename boost::math::constants::construction_traits>::type construction_type; using namespace boost::math::constants; BOOST_MATH_STD_USING CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L, pi(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L), root_pi(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L/2), root_half_pi(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L * 2), root_two_pi(), 2); CHECK_ULP_CLOSE(sqrt(log(4.0L)), root_ln_four(), 2); CHECK_ULP_CLOSE(2.71828182845904523536028747135266249775724709369995L, e(), 2); CHECK_ULP_CLOSE(0.5L, half(), 2); CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104259335L, euler(), 2); CHECK_ULP_CLOSE(sqrt(2.0L), root_two(), 2); CHECK_ULP_CLOSE(log(2.0L), ln_two(), 2); CHECK_ULP_CLOSE(log(10.0L), ln_ten(), 2); CHECK_ULP_CLOSE(log(log(2.0L)), ln_ln_two(), 2); CHECK_ULP_CLOSE(static_cast(1)/3, third(), 2); CHECK_ULP_CLOSE(static_cast(2)/3, twothirds(), 2); CHECK_ULP_CLOSE(0.14159265358979323846264338327950288419716939937510L, pi_minus_three(), 2); CHECK_ULP_CLOSE(4.L - 3.14159265358979323846264338327950288419716939937510L, four_minus_pi(), 2); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L), pi_pow_e(), 2); CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 0.33333333333333333333333333333333333333333333333333L), cbrt_pi(), 2); CHECK_ULP_CLOSE(exp(-0.5L), exp_minus_half(), 2); CHECK_ULP_CLOSE(pow(2.71828182845904523536028747135266249775724709369995L, 3.14159265358979323846264338327950288419716939937510L), e_pow_pi(), 3); #else // Only double, so no suffix L. CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995), pi_pow_e(), 2); CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333), cbrt_pi(), 2); CHECK_ULP_CLOSE(exp(-0.5), exp_minus_half(), 2); #endif // Rational fractions. CHECK_ULP_CLOSE(0.333333333333333333333333333333333333333L, third(), 2); CHECK_ULP_CLOSE(0.666666666666666666666666666666666666667L, two_thirds(), 2); CHECK_ULP_CLOSE(0.75L, three_quarters(), 2); CHECK_ULP_CLOSE(0.1666666666666666666666666666666666666667L, sixth(), 2); // Two and related. CHECK_ULP_CLOSE(sqrt(2.L), root_two(), 2); CHECK_ULP_CLOSE(sqrt(3.L), root_three(), 2); CHECK_ULP_CLOSE(sqrt(2.L)/2, half_root_two(), 2); CHECK_ULP_CLOSE(log(2.L), ln_two(), 2); CHECK_ULP_CLOSE(log(log(2.0L)), ln_ln_two(), 2); CHECK_ULP_CLOSE(sqrt(log(4.0L)), root_ln_four(), 2); CHECK_ULP_CLOSE(1/sqrt(2.0L), one_div_root_two(), 2); // pi. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L, pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/2, half_pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/4, quarter_pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/3, third_pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/4, quarter_pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/6, sixth_pi(), 2); CHECK_ULP_CLOSE(2 * 3.14159265358979323846264338327950288419716939937510L, two_pi(), 2); CHECK_ULP_CLOSE(2 * 3.14159265358979323846264338327950288419716939937510L, tau(), 2); CHECK_ULP_CLOSE(3 * 3.14159265358979323846264338327950288419716939937510L / 4, three_quarters_pi(), 2); CHECK_ULP_CLOSE(4 * 3.14159265358979323846264338327950288419716939937510L / 3, four_thirds_pi(), 2); CHECK_ULP_CLOSE(1 / (3.14159265358979323846264338327950288419716939937510L), one_div_pi(), 2); CHECK_ULP_CLOSE(2 / (3.14159265358979323846264338327950288419716939937510L), two_div_pi(), 2); CHECK_ULP_CLOSE(1 / (2 * 3.14159265358979323846264338327950288419716939937510L), one_div_two_pi(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L), root_pi(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L / 2), root_half_pi(), 2); CHECK_ULP_CLOSE(sqrt(2 * 3.14159265358979323846264338327950288419716939937510L), root_two_pi(), 2); CHECK_ULP_CLOSE(1 / sqrt(3.14159265358979323846264338327950288419716939937510L), one_div_root_pi(), 2); CHECK_ULP_CLOSE(2 / sqrt(3.14159265358979323846264338327950288419716939937510L), two_div_root_pi(), 2); CHECK_ULP_CLOSE(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510L), one_div_root_two_pi(), 2); CHECK_ULP_CLOSE(sqrt(1. / 3.14159265358979323846264338327950288419716939937510L), root_one_div_pi(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L - 3.L, pi_minus_three(), 4 * 4 ); // 4 * 2 because of cancellation loss. CHECK_ULP_CLOSE(4.L - 3.14159265358979323846264338327950288419716939937510L, four_minus_pi(), 4 ); // CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L), pi_pow_e(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, pi_sqr(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L/6, pi_sqr_div_six(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, pi_cubed(), 2); // See above. // CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, cbrt_pi(), 2); // See above. CHECK_ULP_CLOSE(cbrt_pi() * cbrt_pi() * cbrt_pi(), pi(), 2); CHECK_ULP_CLOSE((1)/cbrt_pi(), one_div_cbrt_pi(), 2); // Euler CHECK_ULP_CLOSE(2.71828182845904523536028747135266249775724709369995L, e(), 2); //CHECK_ULP_CLOSE(exp(-0.5L), exp_minus_half(), 2); // See above. CHECK_ULP_CLOSE(exp(-1.L), exp_minus_one(), 2); CHECK_ULP_CLOSE(pow(e(), pi()), e_pow_pi(), 3); // See also above. CHECK_ULP_CLOSE(sqrt(e()), root_e(), 2); CHECK_ULP_CLOSE(log10(e()), log10_e(), 2); CHECK_ULP_CLOSE(1/log10(e()), one_div_log10_e(), 2); CHECK_ULP_CLOSE((1/ln_two()), log2_e(), 2); // Trigonometric CHECK_ULP_CLOSE(pi()/180, degree(), 2); CHECK_ULP_CLOSE(180 / pi(), radian(), 2); CHECK_ULP_CLOSE(sin(1.L), sin_one(), 2); CHECK_ULP_CLOSE(cos(1.L), cos_one(), 2); CHECK_ULP_CLOSE(sinh(1.L), sinh_one(), 2); CHECK_ULP_CLOSE(cosh(1.L), cosh_one(), 2); // Phi CHECK_ULP_CLOSE((1.L + sqrt(5.L)) /2, phi(), 2); CHECK_ULP_CLOSE(log((1.L + sqrt(5.L)) /2), ln_phi(), 2); CHECK_ULP_CLOSE(1.L / log((1.L + sqrt(5.L)) /2), one_div_ln_phi(), 2); //Euler's Gamma CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L, euler(), 2); // (sequence A001620 in OEIS). CHECK_ULP_CLOSE(1.L/ 0.57721566490153286060651209008240243104215933593992L, one_div_euler(), 2); // (from sequence A001620 in OEIS). CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L * 0.57721566490153286060651209008240243104215933593992L, euler_sqr(), 2); // (from sequence A001620 in OEIS). // Misc CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206L, zeta_two(), 2); // A013661 as a constant (usually base 10) in OEIS. CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227L, zeta_three(), 2); // (sequence A002117 in OEIS) CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213L, catalan(), 2); // A006752 as a constant in OEIS. CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150L, extreme_value_skewness(), 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067L, rayleigh_skewness(), 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01L, rayleigh_kurtosis_excess(), 4 * 2); CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515L, khinchin(), 4 ); // A002210 as a constant https://oeis.org/A002210/constant CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011L, glaisher(), 4 ); // https://oeis.org/A074962/constant // // Last of all come the test cases that behave differently if we're calculating the constants on the fly: // if(boost::math::tools::digits() > boost::math::constants::max_string_digits) { // This suffers from cancellation error, so increased 4: CHECK_ULP_CLOSE(static_cast(4. - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi(), 4 * 3); CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510L), pi_minus_three(), 4 * 3); } else { CHECK_ULP_CLOSE(static_cast(4. - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi(), 2); CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510L), pi_minus_three(), 2); } } // template void test_spots(RealType) void test_float_spots() { // Basic sanity checks for constants in boost::math::float_constants:: // for example: boost::math::float_constants::pi // (rather than boost::math::constants::pi() ). using namespace boost::math::float_constants; BOOST_MATH_STD_USING CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F), pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F/2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F * 2)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995F), e, 2); CHECK_ULP_CLOSE(static_cast(0.5), half, 2); CHECK_ULP_CLOSE(static_cast(0.57721566490153286060651209008240243104259335F), euler, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.0F)), root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.0F)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0F))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(1)/3, third, 2); CHECK_ULP_CLOSE(static_cast(2)/3, twothirds, 2); CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510F), pi_minus_three, 2); CHECK_ULP_CLOSE(static_cast(4.F - 3.14159265358979323846264338327950288419716939937510F), four_minus_pi, 2); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F), 2.71828182845904523536028747135266249775724709369995F)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F), 0.33333333333333333333333333333333333333333333333333F)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5F)), exp_minus_half, 2); CHECK_ULP_CLOSE(static_cast(pow(2.71828182845904523536028747135266249775724709369995F, 3.14159265358979323846264338327950288419716939937510F)), e_pow_pi, 2); #else // Only double, so no suffix F. CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); #endif // Rational fractions. CHECK_ULP_CLOSE(static_cast(0.333333333333333333333333333333333333333F), third, 2); CHECK_ULP_CLOSE(static_cast(0.666666666666666666666666666666666666667F), two_thirds, 2); CHECK_ULP_CLOSE(static_cast(0.75F), three_quarters, 2); // Two and related. CHECK_ULP_CLOSE(static_cast(sqrt(2.F)), root_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.F)), root_three, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.F)/2), half_root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.F)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0F))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0F))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(1/sqrt(2.0F)), one_div_root_two, 2); // pi. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F), pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F/2), half_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F/4), quarter_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F/3), third_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F/6), sixth_pi, 2); CHECK_ULP_CLOSE(static_cast(2 * 3.14159265358979323846264338327950288419716939937510F), two_pi, 2); CHECK_ULP_CLOSE(static_cast(3 * 3.14159265358979323846264338327950288419716939937510F / 4), three_quarters_pi, 2); CHECK_ULP_CLOSE(static_cast(4 * 3.14159265358979323846264338327950288419716939937510F / 3), four_thirds_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (3.14159265358979323846264338327950288419716939937510F)), one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / (3.14159265358979323846264338327950288419716939937510F)), two_div_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (2 * 3.14159265358979323846264338327950288419716939937510F)), one_div_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510F / 2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2 * 3.14159265358979323846264338327950288419716939937510F)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(3.14159265358979323846264338327950288419716939937510F)), one_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / sqrt(3.14159265358979323846264338327950288419716939937510F)), two_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510F)), one_div_root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(1. / 3.14159265358979323846264338327950288419716939937510F)), root_one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L - 3.L), pi_minus_three, 4 * 2 ); // 4 * 2 because of cancellation loss. CHECK_ULP_CLOSE(static_cast(4.L - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi, 4 ); // CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510F), 2.71828182845904523536028747135266249775724709369995F)), pi_pow_e, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F * 3.14159265358979323846264338327950288419716939937510F), pi_sqr, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F * 3.14159265358979323846264338327950288419716939937510F/6), pi_sqr_div_six, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F * 3.14159265358979323846264338327950288419716939937510F * 3.14159265358979323846264338327950288419716939937510F), pi_cubed, 2); // See above. // CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510F * 3.14159265358979323846264338327950288419716939937510F), cbrt_pi, 2); // See above. CHECK_ULP_CLOSE(cbrt_pi * cbrt_pi * cbrt_pi, pi, 2); CHECK_ULP_CLOSE((static_cast(1)/cbrt_pi), one_div_cbrt_pi, 2); // Euler CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995F), e, 2); //CHECK_ULP_CLOSE(static_cast(exp(-0.5F)), exp_minus_half, 2); // See above. CHECK_ULP_CLOSE(pow(e, pi), e_pow_pi, 2); // See also above. CHECK_ULP_CLOSE(sqrt(e), root_e, 2); CHECK_ULP_CLOSE(log10(e), log10_e, 2); CHECK_ULP_CLOSE(static_cast(1)/log10(e), one_div_log10_e, 2); // Trigonometric CHECK_ULP_CLOSE(pi/180, degree, 2); CHECK_ULP_CLOSE(180 / pi, radian, 2); CHECK_ULP_CLOSE(sin(1.F), sin_one, 2); CHECK_ULP_CLOSE(cos(1.F), cos_one, 2); CHECK_ULP_CLOSE(sinh(1.F), sinh_one, 2); CHECK_ULP_CLOSE(cosh(1.F), cosh_one, 2); // Phi CHECK_ULP_CLOSE((1.F + sqrt(5.F)) /2, phi, 2); CHECK_ULP_CLOSE(log((1.F + sqrt(5.F)) /2), ln_phi, 2); CHECK_ULP_CLOSE(1.F / log((1.F + sqrt(5.F)) /2), one_div_ln_phi, 2); // Euler's Gamma CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F, euler, 2); // (sequence A001620 in OEIS). CHECK_ULP_CLOSE(1.F/ 0.57721566490153286060651209008240243104215933593992F, one_div_euler, 2); // (from sequence A001620 in OEIS). CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992F * 0.57721566490153286060651209008240243104215933593992F, euler_sqr, 2); // (from sequence A001620 in OEIS). // Misc CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206F, zeta_two, 2); // A013661 as a constant (usually base 10) in OEIS. CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227F, zeta_three, 2); // (sequence A002117 in OEIS) CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213F, catalan, 2); // A006752 as a constant in OEIS. CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150F, extreme_value_skewness, 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067F, rayleigh_skewness, 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01F, rayleigh_kurtosis_excess, 2); CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515F, khinchin, 4 ); // A002210 as a constant https://oeis.org/A002210/constant CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011F, glaisher, 4 ); // https://oeis.org/A074962/constant CHECK_ULP_CLOSE(4.66920160910299067185320382046620161725F, first_feigenbaum, 1); } // template void test_spots(RealType) void test_double_spots() { // Basic sanity checks for constants in boost::math::double_constants:: // for example: boost::math::double_constants::pi // (rather than boost::math::constants::pi() ). using namespace boost::math::double_constants; BOOST_MATH_STD_USING CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510), pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510/2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510 * 2)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995), e, 2); CHECK_ULP_CLOSE(static_cast(0.5), half, 2); CHECK_ULP_CLOSE(static_cast(0.57721566490153286060651209008240243104259335), euler, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.0)), root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.0)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(1)/3, third, 2); CHECK_ULP_CLOSE(static_cast(2)/3, twothirds, 2); CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510), pi_minus_three, 2); CHECK_ULP_CLOSE(static_cast(4. - 3.14159265358979323846264338327950288419716939937510), four_minus_pi, 2); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); CHECK_ULP_CLOSE(static_cast(pow(2.71828182845904523536028747135266249775724709369995, 3.14159265358979323846264338327950288419716939937510)), e_pow_pi, 2); #else // Only double, so no suffix . CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); #endif // Rational fractions. CHECK_ULP_CLOSE(static_cast(0.333333333333333333333333333333333333333), third, 2); CHECK_ULP_CLOSE(static_cast(0.666666666666666666666666666666666666667), two_thirds, 2); CHECK_ULP_CLOSE(static_cast(0.75), three_quarters, 2); // Two and related. CHECK_ULP_CLOSE(static_cast(sqrt(2.)), root_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.)), root_three, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.)/2), half_root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(1/sqrt(2.0)), one_div_root_two, 2); // pi. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510), pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510/2), half_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510/4), quarter_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510/3), third_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510/6), sixth_pi, 2); CHECK_ULP_CLOSE(static_cast(2 * 3.14159265358979323846264338327950288419716939937510), two_pi, 2); CHECK_ULP_CLOSE(static_cast(3 * 3.14159265358979323846264338327950288419716939937510 / 4), three_quarters_pi, 2); CHECK_ULP_CLOSE(static_cast(4 * 3.14159265358979323846264338327950288419716939937510 / 3), four_thirds_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (3.14159265358979323846264338327950288419716939937510)), one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / (3.14159265358979323846264338327950288419716939937510)), two_div_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (2 * 3.14159265358979323846264338327950288419716939937510)), one_div_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510 / 2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2 * 3.14159265358979323846264338327950288419716939937510)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(3.14159265358979323846264338327950288419716939937510)), one_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / sqrt(3.14159265358979323846264338327950288419716939937510)), two_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510)), one_div_root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(1. / 3.14159265358979323846264338327950288419716939937510)), root_one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 - 3.), pi_minus_three, 4 * 2 ); // 4 * 2 because of cancellation loss. CHECK_ULP_CLOSE(static_cast(4. - 3.14159265358979323846264338327950288419716939937510), four_minus_pi, 4 ); // CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510), pi_sqr, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510/6), pi_sqr_div_six, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510), pi_cubed, 2); // See above. // CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510 * 3.14159265358979323846264338327950288419716939937510), cbrt_pi, 2); // See above. CHECK_ULP_CLOSE(cbrt_pi * cbrt_pi * cbrt_pi, pi, 2); CHECK_ULP_CLOSE((static_cast(1)/cbrt_pi), one_div_cbrt_pi, 2); // Euler CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995), e, 2); //CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); // See above. CHECK_ULP_CLOSE(pow(e, pi), e_pow_pi, 2); // See also above. CHECK_ULP_CLOSE(sqrt(e), root_e, 2); CHECK_ULP_CLOSE(log10(e), log10_e, 2); CHECK_ULP_CLOSE(static_cast(1)/log10(e), one_div_log10_e, 2); // Trigonometric CHECK_ULP_CLOSE(pi/180, degree, 2); CHECK_ULP_CLOSE(180 / pi, radian, 2); CHECK_ULP_CLOSE(sin(1.), sin_one, 2); CHECK_ULP_CLOSE(cos(1.), cos_one, 2); CHECK_ULP_CLOSE(sinh(1.), sinh_one, 2); CHECK_ULP_CLOSE(cosh(1.), cosh_one, 2); // Phi CHECK_ULP_CLOSE((1. + sqrt(5.)) /2, phi, 2); CHECK_ULP_CLOSE(log((1. + sqrt(5.)) /2), ln_phi, 2); CHECK_ULP_CLOSE(1. / log((1. + sqrt(5.)) /2), one_div_ln_phi, 2); //Euler's Gamma CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992, euler, 2); // (sequence A001620 in OEIS). CHECK_ULP_CLOSE(1./ 0.57721566490153286060651209008240243104215933593992, one_div_euler, 2); // (from sequence A001620 in OEIS). CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992 * 0.57721566490153286060651209008240243104215933593992, euler_sqr, 2); // (from sequence A001620 in OEIS). // Misc CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206, zeta_two, 2); // A013661 as a constant (usually base 10) in OEIS. CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227, zeta_three, 2); // (sequence A002117 in OEIS) CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213, catalan, 2); // A006752 as a constant in OEIS. CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150, extreme_value_skewness, 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067, rayleigh_skewness, 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01, rayleigh_kurtosis_excess, 2); CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515, khinchin, 4 ); // A002210 as a constant https://oeis.org/A002210/constant CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011, glaisher, 4 ); // https://oeis.org/A074962/constant } // template void test_spots(RealType) void test_long_double_spots() { // Basic sanity checks for constants in boost::math::long double_constants:: // for example: boost::math::long_double_constants::pi // (rather than boost::math::constants::pi() ). // All constants are tested here using at least long double precision // with independent calculated or listed values, // or calculations using long double (sometime a little less accurate). using namespace boost::math::long_double_constants; BOOST_MATH_STD_USING CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L), pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510L)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510L/2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510L * 2)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0L))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995L), e, 2); CHECK_ULP_CLOSE(static_cast(0.5), half, 2); CHECK_ULP_CLOSE(static_cast(0.57721566490153286060651209008240243104259335L), euler, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.0L)), root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.0L)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0L))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(1)/3, third, 2); CHECK_ULP_CLOSE(static_cast(2)/3, twothirds, 2); CHECK_ULP_CLOSE(static_cast(0.14159265358979323846264338327950288419716939937510L), pi_minus_three, 2); CHECK_ULP_CLOSE(static_cast(4.L - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi, 2); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510L), 0.33333333333333333333333333333333333333333333333333L)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5L)), exp_minus_half, 2); CHECK_ULP_CLOSE(static_cast(pow(2.71828182845904523536028747135266249775724709369995L, 3.14159265358979323846264338327950288419716939937510L)), e_pow_pi, 3); #else // Only double, so no suffix L. CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995)), pi_pow_e, 2); CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333)), cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(exp(-0.5)), exp_minus_half, 2); #endif // Rational fractions. CHECK_ULP_CLOSE(static_cast(0.333333333333333333333333333333333333333L), third, 2); CHECK_ULP_CLOSE(static_cast(0.666666666666666666666666666666666666667L), two_thirds, 2); CHECK_ULP_CLOSE(static_cast(0.75L), three_quarters, 2); // Two and related. CHECK_ULP_CLOSE(static_cast(sqrt(2.L)), root_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.L)), root_three, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2.L)/2), half_root_two, 2); CHECK_ULP_CLOSE(static_cast(log(2.L)), ln_two, 2); CHECK_ULP_CLOSE(static_cast(log(log(2.0L))), ln_ln_two, 2); CHECK_ULP_CLOSE(static_cast(sqrt(log(4.0L))), root_ln_four, 2); CHECK_ULP_CLOSE(static_cast(1/sqrt(2.0L)), one_div_root_two, 2); // pi. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L), pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L/2), half_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L/4), quarter_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L/3), third_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L/6), sixth_pi, 2); CHECK_ULP_CLOSE(static_cast(2 * 3.14159265358979323846264338327950288419716939937510L), two_pi, 2); CHECK_ULP_CLOSE(static_cast(3 * 3.14159265358979323846264338327950288419716939937510L / 4), three_quarters_pi, 2); CHECK_ULP_CLOSE(static_cast(4 * 3.14159265358979323846264338327950288419716939937510L / 3), four_thirds_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (3.14159265358979323846264338327950288419716939937510L)), one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / (3.14159265358979323846264338327950288419716939937510L)), two_div_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / (2 * 3.14159265358979323846264338327950288419716939937510L)), one_div_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510L)), root_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(3.14159265358979323846264338327950288419716939937510L / 2)), root_half_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(2 * 3.14159265358979323846264338327950288419716939937510L)), root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(3.14159265358979323846264338327950288419716939937510L)), one_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(2 / sqrt(3.14159265358979323846264338327950288419716939937510L)), two_div_root_pi, 2); CHECK_ULP_CLOSE(static_cast(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510L)), one_div_root_two_pi, 2); CHECK_ULP_CLOSE(static_cast(sqrt(1. / 3.14159265358979323846264338327950288419716939937510L)), root_one_div_pi, 2); CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L - 3.L), pi_minus_three, 4 * 4 ); // 4 * 2 because of cancellation loss. CHECK_ULP_CLOSE(static_cast(4.L - 3.14159265358979323846264338327950288419716939937510L), four_minus_pi, 4 ); // CHECK_ULP_CLOSE(static_cast(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L)), pi_pow_e, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L), pi_sqr, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L/6), pi_sqr_div_six, 2); // See above. CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L), pi_cubed, 2); // See above. // CHECK_ULP_CLOSE(static_cast(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L), cbrt_pi, 2); // See above. CHECK_ULP_CLOSE(cbrt_pi * cbrt_pi * cbrt_pi, pi, 2); CHECK_ULP_CLOSE((static_cast(1)/cbrt_pi), one_div_cbrt_pi, 2); CHECK_ULP_CLOSE(static_cast(6.366197723675813430755350534900574481378385829618257E-1L), two_div_pi, 4 * 3); // 2/pi CHECK_ULP_CLOSE(static_cast(7.97884560802865355879892119868763736951717262329869E-1L), root_two_div_pi, 4 * 3); // sqrt(2/pi) // Euler CHECK_ULP_CLOSE(static_cast(2.71828182845904523536028747135266249775724709369995L), e, 2); //CHECK_ULP_CLOSE(static_cast(exp(-0.5L)), exp_minus_half, 2); // See above. CHECK_ULP_CLOSE(pow(e, pi), e_pow_pi, 3); // See also above. CHECK_ULP_CLOSE(sqrt(e), root_e, 2); CHECK_ULP_CLOSE(log10(e), log10_e, 2); CHECK_ULP_CLOSE(static_cast(1)/log10(e), one_div_log10_e, 2); // Trigonometric CHECK_ULP_CLOSE(pi/180, degree, 2); CHECK_ULP_CLOSE(180 / pi, radian, 2); CHECK_ULP_CLOSE(sin(1.L), sin_one, 2); CHECK_ULP_CLOSE(cos(1.L), cos_one, 2); CHECK_ULP_CLOSE(sinh(1.L), sinh_one, 2); CHECK_ULP_CLOSE(cosh(1.L), cosh_one, 2); // Phi CHECK_ULP_CLOSE((1.L + sqrt(5.L)) /2, phi, 2); CHECK_ULP_CLOSE(log((1.L + sqrt(5.L)) /2), ln_phi, 2); CHECK_ULP_CLOSE(1.L / log((1.L + sqrt(5.L)) /2), one_div_ln_phi, 2); //Euler's Gamma CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L, euler, 2); // (sequence A001620 in OEIS). CHECK_ULP_CLOSE(1.L/ 0.57721566490153286060651209008240243104215933593992L, one_div_euler, 2); // (from sequence A001620 in OEIS). CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L * 0.57721566490153286060651209008240243104215933593992L, euler_sqr, 2); // (from sequence A001620 in OEIS). // Misc CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206L, zeta_two, 2); // A013661 as a constant (usually base 10) in OEIS. CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227L, zeta_three, 2); // (sequence A002117 in OEIS) CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213L, catalan, 2); // A006752 as a constant in OEIS. CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150L, extreme_value_skewness, 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067L, rayleigh_skewness, 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01L, rayleigh_kurtosis_excess, 2); CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515L, khinchin, 4 ); // A002210 as a constant https://oeis.org/A002210/constant CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011L, glaisher, 4 ); // https://oeis.org/A074962/constant } // template void test_spots(RealType) template void test_real_concept_policy(const Policy&) { // Basic sanity checks for constants using real_concept. // Parameter Policy is used to control precision. using boost::math::concepts::real_concept; //typedef typename boost::math::policies::precision>::type t1; // A precision of zero means we don't know what the precision of this type is until runtime. //std::cout << "Precision for type " << typeid(boost::math::concepts::real_concept).name() << " is " << t1::value << "." << std::endl; using namespace boost::math::constants; BOOST_MATH_STD_USING CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L, (pi)(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L), (root_pi)(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L/2), (root_half_pi)(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L * 2), (root_two_pi)(), 2); CHECK_ULP_CLOSE(sqrt(log(4.0L)), (root_ln_four)(), 2); CHECK_ULP_CLOSE(2.71828182845904523536028747135266249775724709369995L, (e)(), 2); CHECK_ULP_CLOSE(0.5, (half)(), 2); CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104259335L, (euler)(), 2); CHECK_ULP_CLOSE(sqrt(2.0L), (root_two)(), 2); CHECK_ULP_CLOSE(log(2.0L), (ln_two)(), 2); CHECK_ULP_CLOSE(log(log(2.0L)), (ln_ln_two)(), 2); CHECK_ULP_CLOSE(static_cast(1)/3, (third)(), 2); CHECK_ULP_CLOSE(static_cast(2)/3, (twothirds)(), 2); CHECK_ULP_CLOSE(0.14159265358979323846264338327950288419716939937510L, (pi_minus_three)(), 2); CHECK_ULP_CLOSE(4.L - 3.14159265358979323846264338327950288419716939937510L, (four_minus_pi)(), 2); #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L), (pi_pow_e)(), 2); CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 0.33333333333333333333333333333333333333333333333333L), (cbrt_pi)(), 2); CHECK_ULP_CLOSE(exp(-0.5L), (exp_minus_half)(), 2); CHECK_ULP_CLOSE(pow(2.71828182845904523536028747135266249775724709369995L, 3.14159265358979323846264338327950288419716939937510L), (e_pow_pi)(), 2); #else // Only double, so no suffix L. CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510), 2.71828182845904523536028747135266249775724709369995), (pi_pow_e)(), 2); CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510), 0.33333333333333333333333333333333333333333333333333), (cbrt_pi)(), 2); CHECK_ULP_CLOSE(exp(-0.5), (exp_minus_half)(), 2); #endif // Rational fractions. CHECK_ULP_CLOSE(0.333333333333333333333333333333333333333L, (third)(), 2); CHECK_ULP_CLOSE(0.666666666666666666666666666666666666667L, (two_thirds)(), 2); CHECK_ULP_CLOSE(0.75L, (three_quarters)(), 2); // Two and related. CHECK_ULP_CLOSE(sqrt(2.L), (root_two)(), 2); CHECK_ULP_CLOSE(sqrt(3.L), (root_three)(), 2); CHECK_ULP_CLOSE(sqrt(2.L)/2, (half_root_two)(), 2); CHECK_ULP_CLOSE(log(2.L), (ln_two)(), 2); CHECK_ULP_CLOSE(log(log(2.0L)), (ln_ln_two)(), 2); CHECK_ULP_CLOSE(sqrt(log(4.0L)), (root_ln_four)(), 2); CHECK_ULP_CLOSE(1/sqrt(2.0L), (one_div_root_two)(), 2); // pi. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L, (pi)(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/2, (half_pi)(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/4, (quarter_pi)(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/3, (third_pi)(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L/6, (sixth_pi)(), 2); CHECK_ULP_CLOSE(2 * 3.14159265358979323846264338327950288419716939937510L, (two_pi)(), 2); CHECK_ULP_CLOSE(3 * 3.14159265358979323846264338327950288419716939937510L / 4, (three_quarters_pi)(), 2); CHECK_ULP_CLOSE(4 * 3.14159265358979323846264338327950288419716939937510L / 3, (four_thirds_pi)(), 2); CHECK_ULP_CLOSE(1 / (3.14159265358979323846264338327950288419716939937510L), (one_div_pi)(), 2); CHECK_ULP_CLOSE(2 / (3.14159265358979323846264338327950288419716939937510L), (two_div_pi)(), 2); CHECK_ULP_CLOSE(1 / (2 * 3.14159265358979323846264338327950288419716939937510L), (one_div_two_pi)(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L), (root_pi)(), 2); CHECK_ULP_CLOSE(sqrt(3.14159265358979323846264338327950288419716939937510L / 2), (root_half_pi)(), 2); CHECK_ULP_CLOSE(sqrt(2 * 3.14159265358979323846264338327950288419716939937510L), (root_two_pi)(), 2); CHECK_ULP_CLOSE(1 / sqrt(3.14159265358979323846264338327950288419716939937510L), (one_div_root_pi)(), 2); CHECK_ULP_CLOSE(2 / sqrt(3.14159265358979323846264338327950288419716939937510L), (two_div_root_pi)(), 2); CHECK_ULP_CLOSE(1 / sqrt(2 * 3.14159265358979323846264338327950288419716939937510L), (one_div_root_two_pi)(), 2); CHECK_ULP_CLOSE(sqrt(1. / 3.14159265358979323846264338327950288419716939937510L), (root_one_div_pi)(), 2); CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L - 3.L, (pi_minus_three)(), 4 * 4 ); // 4 * 2 because of cancellation loss. CHECK_ULP_CLOSE(4.L - 3.14159265358979323846264338327950288419716939937510L, (four_minus_pi)(), 4 ); // CHECK_ULP_CLOSE(pow((3.14159265358979323846264338327950288419716939937510L), 2.71828182845904523536028747135266249775724709369995L), (pi_pow_e)(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, (pi_sqr)(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L/6, (pi_sqr_div_six)(), 2); // See above. CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, (pi_cubed)(), 2); // See above. // CHECK_ULP_CLOSE(3.14159265358979323846264338327950288419716939937510L * 3.14159265358979323846264338327950288419716939937510L, (cbrt_pi)(), 2); // See above. CHECK_ULP_CLOSE((cbrt_pi)() * (cbrt_pi)() * (cbrt_pi)(), (pi)(), 2); CHECK_ULP_CLOSE((1)/(cbrt_pi)(), (one_div_cbrt_pi)(), 2); // Euler CHECK_ULP_CLOSE(2.71828182845904523536028747135266249775724709369995L, (e)(), 2); //CHECK_ULP_CLOSE(exp(-0.5L), (exp_minus_half)(), 2); // See above. CHECK_ULP_CLOSE(pow(e(), (pi)()), (e_pow_pi)(), 2); // See also above. CHECK_ULP_CLOSE(sqrt(e()), (root_e)(), 2); CHECK_ULP_CLOSE(log10(e()), (log10_e)(), 2); CHECK_ULP_CLOSE(1/log10(e()), (one_div_log10_e)(), 2); CHECK_ULP_CLOSE((1/ln_two()), (log2_e)(), 2); // Trigonometric CHECK_ULP_CLOSE((pi)()/180, (degree)(), 2); CHECK_ULP_CLOSE(180 / (pi)(), (radian)(), 2); CHECK_ULP_CLOSE(sin(1.L), (sin_one)(), 2); CHECK_ULP_CLOSE(cos(1.L), (cos_one)(), 2); CHECK_ULP_CLOSE(sinh(1.L), (sinh_one)(), 2); CHECK_ULP_CLOSE(cosh(1.L), (cosh_one)(), 2); // Phi CHECK_ULP_CLOSE((1.L + sqrt(5.L)) /2, (phi)(), 2); CHECK_ULP_CLOSE(log((1.L + sqrt(5.L)) /2), (ln_phi)(), 2); CHECK_ULP_CLOSE(1.L / log((1.L + sqrt(5.L)) /2), (one_div_ln_phi)(), 2); //Euler's Gamma CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L, (euler)(), 2); // (sequence A001620 in OEIS). CHECK_ULP_CLOSE(1.L/ 0.57721566490153286060651209008240243104215933593992L, (one_div_euler)(), 2); // (from sequence A001620 in OEIS). CHECK_ULP_CLOSE(0.57721566490153286060651209008240243104215933593992L * 0.57721566490153286060651209008240243104215933593992L, (euler_sqr)(), 2); // (from sequence A001620 in OEIS). // Misc CHECK_ULP_CLOSE(1.644934066848226436472415166646025189218949901206L, (zeta_two)(), 2); // A013661 as a constant (usually base 10) in OEIS. CHECK_ULP_CLOSE(1.20205690315959428539973816151144999076498629234049888179227L, (zeta_three)(), 2); // (sequence A002117 in OEIS) CHECK_ULP_CLOSE(.91596559417721901505460351493238411077414937428167213L, (catalan)(), 2); // A006752 as a constant in OEIS. CHECK_ULP_CLOSE(1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150L, (extreme_value_skewness)(), 2); // Mathematica: N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] CHECK_ULP_CLOSE(0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067L, (rayleigh_skewness)(), 2); // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] CHECK_ULP_CLOSE(2.450893006876380628486604106197544154e-01L, (rayleigh_kurtosis_excess)(), 2); CHECK_ULP_CLOSE(2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515L, (khinchin)(), 4 ); // A002210 as a constant https://oeis.org/A002210/constant CHECK_ULP_CLOSE(1.2824271291006226368753425688697917277676889273250011L, (glaisher)(), 4 ); // https://oeis.org/A074962/constant // // Last of all come the test cases that behave differently if we're calculating the constants on the fly: // if(boost::math::tools::digits() > boost::math::constants::max_string_digits) { // This suffers from cancellation error, so increased 4: CHECK_ULP_CLOSE((static_cast(4. - 3.14159265358979323846264338327950288419716939937510L)), (four_minus_pi)(), 4 * 3); CHECK_ULP_CLOSE((static_cast(0.14159265358979323846264338327950288419716939937510L)), (pi_minus_three)(), 4 * 3); } else { CHECK_ULP_CLOSE((static_cast(4. - 3.14159265358979323846264338327950288419716939937510L)), (four_minus_pi)(), 2); CHECK_ULP_CLOSE((static_cast(0.14159265358979323846264338327950288419716939937510L)), (pi_minus_three)(), 2); } } // template void test_spots(boost::math::concepts::real_concept) #ifdef BOOST_MATH_HAS_FLOAT128 void test_float128() { __float128 p = boost::math::constants::pi<__float128>(); __float128 r = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651Q; CHECK_ULP_CLOSE(boost::multiprecision::float128(p), boost::multiprecision::float128(r), 2); } #endif void test_constexpr() { #ifndef BOOST_NO_CXX11_CONSTEXPR constexpr float f1 = boost::math::constants::pi(); constexpr double f2 = boost::math::constants::pi(); constexpr long double f3 = boost::math::constants::pi(); constexpr float fval2 = boost::math::float_constants::pi; constexpr double dval2 = boost::math::double_constants::pi; constexpr long double ldval2 = boost::math::long_double_constants::pi; (void)f1; (void)f2; (void)f3; (void) fval2; (void) dval2; (void) ldval2; #ifdef BOOST_MATH_USE_FLOAT128 constexpr __float128 f4 = boost::math::constants::pi<__float128>(); (void)f4; #endif #endif } #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) void test_feigenbaum() { // This constant takes weeks to calculate. // So if the requested precision > precomputed precision, we need an error message. using boost::multiprecision::cpp_bin_float; using boost::multiprecision::number; auto f64 = boost::math::constants::first_feigenbaum(); using Real100 = number>; auto f = boost::math::constants::first_feigenbaum(); CHECK_ULP_CLOSE(static_cast(f), f64, 0); Real100 g{"4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171659848551898151344086271420279325223124429888908908599449354632367134115324817142199474556443658237932020095610583305754586176522220703854106467494942849814533917262005687556659523398756038256372256480040951071283890611844702775854285419801113440175002428585382498335715522052236087250291678860362674527213399057131606875345083433934446103706309452019115876972432273589838903794946257251289097948986768334611626889116563123474460575179539122045562472807095202198199094558581946136877445617396074115614074243754435499204869180982648652368438702799649017397793425134723808737136211601860128186102056381818354097598477964173900328936171432159878240789776614391395764037760537119096932066998361984288981837003229412030210655743295550388845849737034727532121925706958414074661841981961006129640161487712944415901405467941800198133253378592493365883070459999938375411726563553016862529032210862320550634510679399023341675"}; CHECK_ULP_CLOSE(f, g, 0); } template void test_plastic() { Real P = boost::math::constants::plastic(); Real residual = P*P*P - P -1; using std::abs; CHECK_LE(abs(residual), 4*std::numeric_limits::epsilon()); } template void test_gauss() { using boost::math::tools::agm; using std::sqrt; Real G_computed = boost::math::constants::gauss(); Real G_expected = Real(1)/agm(sqrt(Real(2)), Real(1)); CHECK_ULP_CLOSE(G_expected, G_computed, 1); CHECK_LE(G_computed, Real(0.8347)); CHECK_LE(Real(0.8346), G_computed); } template void test_dottie() { using boost::math::constants::dottie; using std::cos; CHECK_ULP_CLOSE(dottie(), cos(dottie()), 1); } template void test_reciprocal_fibonacci() { using boost::math::constants::reciprocal_fibonacci; CHECK_LE(reciprocal_fibonacci(), Real(3.36)); CHECK_LE(Real(3.35), reciprocal_fibonacci()); } template void test_laplace_limit() { using std::exp; using std::sqrt; using boost::math::constants::laplace_limit; Real ll = laplace_limit(); Real tmp = sqrt(1+ll*ll); CHECK_ULP_CLOSE(ll*exp(tmp), 1 + tmp, 2); } #endif int main() { // Basic sanity-check spot values. test_float_spots(); // Test float_constants, like boost::math::float_constants::pi; test_double_spots(); // Test double_constants. test_long_double_spots(); // Test long_double_constants. #ifdef BOOST_MATH_HAS_FLOAT128 test_float128(); #endif test_constexpr(); // (Parameter value, arbitrarily zero, only communicates the floating-point type). test_spots(0.0F); // Test float. test_spots(0.0); // Test double. test_spots(0.0L); // Test long double. #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) test_feigenbaum(); test_plastic(); test_plastic(); test_plastic>>(); test_gauss(); test_gauss(); test_gauss(); test_gauss>>(); test_dottie(); test_dottie(); test_dottie(); test_dottie>>(); test_laplace_limit(); test_laplace_limit(); test_laplace_limit(); test_laplace_limit>>(); #endif return boost::math::test::report_errors(); }