diff options
Diffstat (limited to 'libs/math/test/test_ellint_3.hpp')
-rw-r--r-- | libs/math/test/test_ellint_3.hpp | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/libs/math/test/test_ellint_3.hpp b/libs/math/test/test_ellint_3.hpp index 7c5893c75..29178d64b 100644 --- a/libs/math/test/test_ellint_3.hpp +++ b/libs/math/test/test_ellint_3.hpp @@ -14,6 +14,7 @@ #include <boost/test/unit_test.hpp> #include <boost/test/floating_point_comparison.hpp> #include <boost/math/special_functions/math_fwd.hpp> +#include <boost/math/constants/constants.hpp> #include <boost/array.hpp> #include "functor.hpp" @@ -78,8 +79,9 @@ void do_test_ellint_pi2(T& data, const char* type_name, const char* test) template <typename T> void test_spots(T, const char* type_name) { + BOOST_MATH_STD_USING // function values calculated on http://functions.wolfram.com/ - static const boost::array<boost::array<T, 4>, 25> data1 = {{ + static const boost::array<boost::array<T, 4>, 65> data1 = {{ {{ SC_(1.0), SC_(-1.0), SC_(0.0), SC_(-1.557407724654902230506974807458360173087) }}, {{ SC_(0.0), SC_(-4.0), SC_(0.4), SC_(-4.153623371196831087495427530365430979011) }}, {{ SC_(0.0), SC_(8.0), SC_(-0.6), SC_(8.935930619078575123490612395578518914416) }}, @@ -105,7 +107,55 @@ void test_spots(T, const char* type_name) {{ SC_(1.125), SC_(3.0), SC_(0.25), SC_(-0.142697285116693775525461312178015106079842313950476205580178) }}, {{ T(257)/256, SC_(1.5), SC_(0.125), SC_(22.2699300473528164111357290313578126108398839810535700884237) }}, {{ T(257)/256, SC_(21.5), SC_(0.125), SC_(-0.535406081652313940727588125663856894154526187713506526799429) }}, - }}; + // Bug cases from Rocco Romeo: + { { SC_(-1E-170), boost::math::constants::pi<T>() / 4, SC_(1E-164), SC_(0.785398163397448309615660845819875721049292349843776455243736) } }, + { { SC_(-1E-170), boost::math::constants::pi<T>() / 4, SC_(-1E-164), SC_(0.785398163397448309615660845819875721049292349843776455243736) } }, + { { -ldexp(T(1.0), -52), boost::math::constants::pi<T>() / 4, SC_(0.9375), SC_(0.866032844934895872810905364370384153285798081574191920571016) } }, + { { -ldexp(T(1.0), -52), boost::math::constants::pi<T>() / 4, SC_(-0.9375), SC_(0.866032844934895872810905364370384153285798081574191920571016) } }, + { { std::numeric_limits<T>::max_exponent > 600 ? -ldexp(T(1), 604) : T(0), -ldexp(T(1), -816), ldexp(T(1), -510), std::numeric_limits<T>::max_exponent > 600 ? SC_(-2.28835573409367516299079046268930870596307631872422530813192e-246) : SC_(-2.28835573409367516299079046268930870596307631872422530813192e-246) } }, + { { std::numeric_limits<T>::max_exponent > 600 ? -ldexp(T(1), 604) : T(0), -ldexp(T(1), -816), -ldexp(T(1), -510), std::numeric_limits<T>::max_exponent > 600 ? SC_(-2.28835573409367516299079046268930870596307631872422530813192e-246) : SC_(-2.28835573409367516299079046268930870596307631872422530813192e-246) } }, + { { -ldexp(T(1), -622), -ldexp(T(1), -800), ldexp(T(1), -132), SC_(-1.49969681389563095481764443762806535353996169623910829793733e-241) } }, + { { -ldexp(T(1), -622), -ldexp(T(1), -800), -ldexp(T(1), -132), SC_(-1.49969681389563095481764443762806535353996169623910829793733e-241) } }, + { { -ldexp(T(1), -562), ldexp(T(1), -140), ldexp(T(1), -256), SC_(7.174648137343063403129495466444370592154941142407760751e-43) } }, + { { -ldexp(T(1), -562), -ldexp(T(1), -140), ldexp(T(1), -256), SC_(-7.17464813734306340312949546644437059215494114240776075e-43) } }, + { { ldexp(T(1), -688), -ldexp(T(1), -243), ldexp(T(1), -193), SC_(-7.07474928033336903711649944600608732865822749854620171e-74) } }, + { { -ldexp(T(1), -688), -ldexp(T(1), -243), ldexp(T(1), -193), SC_(-7.07474928033336903711649944600608732865822749854620171e-74) } }, + // Special cases where k = 0: + { { SC_(0.5), SC_(1.0), SC_(0.0), SC_(1.17881507892743738986863357869566288974084658835353613038547) } }, + { { SC_(-0.5), SC_(1.0), SC_(0.0), SC_(0.888286691263535380266337576823783210424994266596287990733270) } }, + { { SC_(0.5), SC_(-1.0), SC_(0.0), SC_(-1.17881507892743738986863357869566288974084658835353613038547) } }, + { { SC_(-0.5), SC_(-1.0), SC_(0.0), SC_(-0.888286691263535380266337576823783210424994266596287990733270) } }, + // k == 0 and phi > pi/2: + { { SC_(0.5), SC_(2.0), SC_(0.0), SC_(3.03379730757207227653600089552126882582809860566558143254794) } }, + { { SC_(-0.5), SC_(2.0), SC_(0.0), SC_(1.57453655812023739911111328195028658229986230310938753315640) } }, + { { SC_(0.5), SC_(-2.0), SC_(0.0), SC_(-3.03379730757207227653600089552126882582809860566558143254794) } }, + { { SC_(-0.5), SC_(-2.0), SC_(0.0), SC_(-1.57453655812023739911111328195028658229986230310938753315640) } }, + // Special cases where k = 1: + { { SC_(0.5), SC_(1.0), SC_(1.0), SC_(1.4830998734200773326887632776553375078936815318419194718912351) } }, + { { SC_(-0.5), SC_(1.0), SC_(1.0), SC_(1.07048347329000030842347009377117215811122412769516781788253) } }, + { { SC_(0.5), SC_(-1.0), SC_(1.0), SC_(-1.4830998734200773326887632776553375078936815318419194718912) } }, + { { SC_(-0.5), SC_(-1.0), SC_(1.0), SC_(-1.07048347329000030842347009377117215811122412769516781788253) } }, + // special cases where v = 1: + { { SC_(1.0), SC_(0.5), SC_(0.5), SC_(0.55225234291197632914658859230278152249148960801635386133501) } }, + { { SC_(1.0), SC_(-0.5), SC_(0.5), SC_(-0.55225234291197632914658859230278152249148960801635386133501) } }, + { { SC_(1.0), SC_(2.0), SC_(0.5), SC_(-2.87534521505997989921579168327307068134740792740155171368532) } }, + { { SC_(1.0), SC_(-2.0), SC_(0.5), SC_(2.87534521505997989921579168327307068134740792740155171368532) } }, + { { SC_(1.0), SC_(2.0), ldexp(T(1), -200), SC_(-2.18503986326151899164330610231368254343201774622766316456295) } }, + { { SC_(1.0), SC_(-2.0), ldexp(T(1), -200), SC_(2.18503986326151899164330610231368254343201774622766316456295) } }, + { { SC_(1.0), ldexp(T(1.0), -150), ldexp(T(1), -200), SC_(7.006492321624085354618647916449580656401309709382578858e-46) } }, + { { SC_(1.0), -ldexp(T(1.0), -150), ldexp(T(1), -200), SC_(-7.006492321624085354618647916449580656401309709382578858e-46) } }, + // Previously unsupported region with v > 1 and |phi| > PI/2, this is the only region + // with high-ish error rates caused by argument reduction by Pi: + { { SC_(20.0), ldexp(T(1647611), -19), SC_(0.5), SC_(0.000975940902692994840122139131147517258405256880370413541280) } }, + { { SC_(20.0), -ldexp(T(1647611), -19), SC_(0.5), SC_(-0.000975940902692994840122139131147517258405256880370413541280) } }, + { { SC_(1.0) + ldexp(T(1), -6), ldexp(T(889085), -19), SC_(0.5), SC_(-27.1647225624906589308619292363045712770651414487085887109197) } }, + { { SC_(1.0) + ldexp(T(1), -6), -ldexp(T(889085), -19), SC_(0.5), SC_(27.1647225624906589308619292363045712770651414487085887109197) } }, + // Phi = 0: + { { SC_(1.0), SC_(0.0), SC_(0.5), SC_(0.0) } }, + { { SC_(-1.0), SC_(0.0), SC_(0.5), SC_(0.0) } }, + { { SC_(100.0), SC_(0.0), SC_(0.5), SC_(0.0) } }, + { { SC_(-100.0), SC_(0.0), SC_(0.5), SC_(0.0) } }, + } }; do_test_ellint_pi3<T>(data1, type_name, "Elliptic Integral PI: Mathworld Data"); @@ -118,7 +168,7 @@ void test_spots(T, const char* type_name) do_test_ellint_pi3<T>(ellint_pi3_large_data, type_name, "Elliptic Integral PI: Large Random Data"); // function values calculated on http://functions.wolfram.com/ - static const boost::array<boost::array<T, 3>, 9> data2 = {{ + static const boost::array<boost::array<T, 3>, 17> data2 = {{ {{ SC_(0.0), SC_(0.2), SC_(1.586867847454166237308008033828114192951) }}, {{ SC_(0.0), SC_(0.4), SC_(1.639999865864511206865258329748601457626) }}, {{ SC_(0.0), SC_(0.0), SC_(1.57079632679489661923132169163975144209858469968755291048747) }}, @@ -128,7 +178,16 @@ void test_spots(T, const char* type_name) {{ SC_(-1e+10), SC_(-0.75), SC_(0.0000157080225184890546939710019277357161497407143903832703317801) }}, {{ T(1) / 1024, SC_(-0.875), SC_(2.18674503176462374414944618968850352696579451638002110619287) }}, {{ T(1023)/1024, SC_(-0.875), SC_(101.045289804941384100960063898569538919135722087486350366997) }}, - }}; + // Bug cases from Rocco Romeo: + { { SC_(1e-175), T(0), SC_(1.57079632679489661923132169163975144209858469968755291048747) } }, + { { SC_(1e-170), SC_(1E-164), SC_(1.57079632679489661923132169163975144209858469968755291048747) } }, + { { SC_(1e-170), SC_(-1E-164), SC_(1.57079632679489661923132169163975144209858469968755291048747) } }, + { { -1.5f * ldexp(T(1), -52), SC_(-0.9375), SC_(2.48840049140103464299631535211815755485846563527849342319632) } }, + { { -1.5f * ldexp(T(1), -52), SC_(0.9375), SC_(2.48840049140103464299631535211815755485846563527849342319632) } }, + { { ldexp(T(1), -560), ldexp(T(1), -165), SC_(1.57079632679489661923132169163975144209858469968756130722545) } }, + { { ldexp(T(1), -560), -ldexp(T(1), -165), SC_(1.57079632679489661923132169163975144209858469968754451374949) } }, + { { std::numeric_limits<T>::max_exponent > 600 ? -ldexp(T(1), 600) : 0, SC_(0.5), std::numeric_limits<T>::max_exponent > 600 ? SC_(7.71118598318249916481121898327895181916104121635240801895419e-91) : SC_(1.68575035481259604287120365779907698950080089414108904411995) } }, + } }; do_test_ellint_pi2<T>(data2, type_name, "Complete Elliptic Integral PI: Mathworld Data"); @@ -142,4 +201,7 @@ void test_spots(T, const char* type_name) BOOST_CHECK_THROW(boost::math::ellint_3(T(1.0001), T(-1)), std::domain_error); BOOST_CHECK_THROW(boost::math::ellint_3(T(0.5), T(1)), std::domain_error); BOOST_CHECK_THROW(boost::math::ellint_3(T(0.5), T(2)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_3(T(1), T(0.5), T(2)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_3(T(1), T(-0.5), T(2)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_3(T(1), T(-0.5), T(-2)), std::domain_error); } |