From a033166f7fc3963e4282b475501bd753f68f7ebf Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 18 May 2019 19:36:22 +0100 Subject: [PATCH] Elliptic Integrals: extend range of ellint_1/2/3. See https://github.com/boostorg/math/issues/183. --- doc/sf/ellint_legendre.qbk | 12 ++++++------ .../boost/math/special_functions/ellint_1.hpp | 11 +++++------ .../boost/math/special_functions/ellint_2.hpp | 13 ++++++++----- .../boost/math/special_functions/ellint_3.hpp | 12 ++++++------ test/test_ellint_1.hpp | 16 +++++++++++++++- test/test_ellint_2.hpp | 11 ++++++++++- test/test_ellint_3.hpp | 10 ++++++++-- 7 files changed, 58 insertions(+), 27 deletions(-) diff --git a/doc/sf/ellint_legendre.qbk b/doc/sf/ellint_legendre.qbk index 38ff3bcb3..2fb8299bb 100644 --- a/doc/sf/ellint_legendre.qbk +++ b/doc/sf/ellint_legendre.qbk @@ -51,7 +51,7 @@ Returns the incomplete elliptic integral of the first kind ['F([phi], k)]: [equation ellint2] -Requires -1 <= k <= 1, otherwise returns the result of __domain_error. +Requires k[super 2]sin[super 2](phi) < 1, otherwise returns the result of __domain_error. [optional_policy] @@ -65,7 +65,7 @@ Returns the complete elliptic integral of the first kind ['K(k)]: [equation ellint6] -Requires -1 <= k <= 1, otherwise returns the result of __domain_error. +Requires |k| < 1, otherwise returns the result of __domain_error. [optional_policy] @@ -154,7 +154,7 @@ Returns the incomplete elliptic integral of the second kind ['E([phi], k)]: [equation ellint3] -Requires -1 <= k <= 1, otherwise returns the result of __domain_error. +Requires k[super 2]sin[super 2](phi) < 1, otherwise returns the result of __domain_error. [optional_policy] @@ -168,7 +168,7 @@ Returns the complete elliptic integral of the second kind ['E(k)]: [equation ellint7] -Requires -1 <= k <= 1, otherwise returns the result of __domain_error. +Requires |k| < 1, otherwise returns the result of __domain_error. [optional_policy] @@ -257,7 +257,7 @@ Returns the incomplete elliptic integral of the third kind ['[Pi](n, [phi], k)]: [equation ellint4] -Requires ['-1 <= k <= 1] and ['n < 1/sin[super 2]([phi])], otherwise +Requires ['k[super 2]sin[super 2](phi) < 1] and ['n < 1/sin[super 2]([phi])], otherwise returns the result of __domain_error (outside this range the result would be complex). @@ -273,7 +273,7 @@ Returns the complete elliptic integral of the first kind ['[Pi](n, k)]: [equation ellint8] -Requires ['-1 <= k <= 1] and ['n < 1], otherwise returns the +Requires ['|k| < 1] and ['n < 1], otherwise returns the result of __domain_error (outside this range the result would be complex). [optional_policy] diff --git a/include/boost/math/special_functions/ellint_1.hpp b/include/boost/math/special_functions/ellint_1.hpp index 2f7d6ac3d..334c0ad80 100644 --- a/include/boost/math/special_functions/ellint_1.hpp +++ b/include/boost/math/special_functions/ellint_1.hpp @@ -51,12 +51,6 @@ T ellint_f_imp(T phi, T k, const Policy& pol) BOOST_MATH_INSTRUMENT_VARIABLE(k); BOOST_MATH_INSTRUMENT_VARIABLE(function); - if (abs(k) > 1) - { - return policies::raise_domain_error(function, - "Got k = %1%, function requires |k| <= 1", k, pol); - } - bool invert = false; if(phi < 0) { @@ -104,6 +98,11 @@ T ellint_f_imp(T phi, T k, const Policy& pol) } T sinp = sin(rphi); sinp *= sinp; + if (sinp * k * k >= 1) + { + return policies::raise_domain_error(function, + "Got k^2 * sin^2(phi) = %1%, but the function requires this < 1", sinp * k * k, pol); + } T cosp = cos(rphi); cosp *= cosp; BOOST_MATH_INSTRUMENT_VARIABLE(sinp); diff --git a/include/boost/math/special_functions/ellint_2.hpp b/include/boost/math/special_functions/ellint_2.hpp index 9ee6b6382..2687e9c8c 100644 --- a/include/boost/math/special_functions/ellint_2.hpp +++ b/include/boost/math/special_functions/ellint_2.hpp @@ -49,6 +49,9 @@ T ellint_e_imp(T phi, T k, const Policy& pol) using namespace boost::math::constants; bool invert = false; + if (phi == 0) + return 0; + if(phi < 0) { phi = fabs(phi); @@ -95,11 +98,7 @@ T ellint_e_imp(T phi, T k, const Policy& pol) rphi = constants::half_pi() - rphi; } T k2 = k * k; - if(k2 > 1) - { - return policies::raise_domain_error("boost::math::ellint_2<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); - } - else if(rphi < tools::root_epsilon()) + if(boost::math::pow<3>(rphi) * k2 / 6 < tools::epsilon() * fabs(rphi)) { // See http://functions.wolfram.com/EllipticIntegrals/EllipticE2/06/01/03/0001/ result = s * rphi; @@ -108,6 +107,10 @@ T ellint_e_imp(T phi, T k, const Policy& pol) { // http://dlmf.nist.gov/19.25#E10 T sinp = sin(rphi); + if (k2 * sinp * sinp >= 1) + { + return policies::raise_domain_error("boost::math::ellint_2<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); + } T cosp = cos(rphi); T c = 1 / (sinp * sinp); T cm1 = cosp * cosp / (sinp * sinp); // c - 1 diff --git a/include/boost/math/special_functions/ellint_3.hpp b/include/boost/math/special_functions/ellint_3.hpp index 22563d5d6..dfc104514 100644 --- a/include/boost/math/special_functions/ellint_3.hpp +++ b/include/boost/math/special_functions/ellint_3.hpp @@ -49,15 +49,15 @@ T ellint_pi_imp(T v, T phi, T k, T vc, const Policy& pol) static const char* function = "boost::math::ellint_3<%1%>(%1%,%1%,%1%)"; - if(abs(k) > 1) - { - return policies::raise_domain_error(function, - "Got k = %1%, function requires |k| <= 1", k, pol); - } T sphi = sin(fabs(phi)); T result = 0; + if (k * k * sphi * sphi > 1) + { + return policies::raise_domain_error(function, + "Got k = %1%, function requires |k| <= 1", k, pol); + } // Special cases first: if(v == 0) { @@ -154,7 +154,7 @@ T ellint_pi_imp(T v, T phi, T k, T vc, const Policy& pol) return (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * vcr); } } - if(v < 0) + if((v < 0) && fabs(k) <= 1) { // // If we don't shift to 0 <= v <= 1 we get diff --git a/test/test_ellint_1.hpp b/test/test_ellint_1.hpp index b03d0583d..0e94b324b 100644 --- a/test/test_ellint_1.hpp +++ b/test/test_ellint_1.hpp @@ -84,7 +84,7 @@ void test_spots(T, const char* type_name) { // Function values calculated on http://functions.wolfram.com/ // Note that Mathematica's EllipticF accepts k^2 as the second parameter. - static const boost::array::type, 3>, 19> data1 = {{ + static const boost::array::type, 3>, 22> data1 = {{ {{ SC_(0.0), SC_(0.0), SC_(0.0) }}, {{ SC_(-10.0), SC_(0.0), SC_(-10.0) }}, {{ SC_(-1.0), SC_(-1.0), SC_(-1.2261911708835170708130609674719067527242483502207) }}, @@ -104,6 +104,10 @@ void test_spots(T, const char* type_name) {{ SC_(-4.0), SC_(0.5), SC_(-4.2543274975235836861894752787874633017836785640477) }}, {{ SC_(-6.0), SC_(0.5), SC_(-6.4588766202317746302999080620490579800463614807916) }}, {{ SC_(-10.0), SC_(0.5), SC_(-10.697409951222544858346795279378531495869386960090) }}, + // Some values where k is > 1: + {{ static_cast::type>(2)/13, static_cast::type>(15)/13, SC_(0.154661869446904722070471580919758948531148566762183486996920)}}, + {{ static_cast::type>(2)/13, static_cast::type>(19)/13, SC_(0.155166467455029577314314021156113481657713115640002027219)}}, + {{ static_cast::type>(2)/13, static_cast::type>(32)/13, SC_(0.15776272074094290829870142225970052217542486917945444918)}}, }}; do_test_ellint_f(data1, type_name, "Elliptic Integral F: Mathworld Data"); @@ -131,5 +135,15 @@ void test_spots(T, const char* type_name) #include "ellint_k_data.ipp" do_test_ellint_k(ellint_k_data, type_name, "Elliptic Integral K: Random Data"); + + // + // Test error handling: + // + BOOST_CHECK_GE(boost::math::ellint_1(T(1)), boost::math::tools::max_value()); + BOOST_CHECK_GE(boost::math::ellint_1(T(-1)), boost::math::tools::max_value()); + BOOST_CHECK_THROW(boost::math::ellint_1(T(1.0001)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_1(T(-1.0001)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_1(T(2.2), T(0.5)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_1(T(-2.2), T(0.5)), std::domain_error); } diff --git a/test/test_ellint_2.hpp b/test/test_ellint_2.hpp index 2de80fcaf..a48e4cecb 100644 --- a/test/test_ellint_2.hpp +++ b/test/test_ellint_2.hpp @@ -84,7 +84,7 @@ void test_spots(T, const char* type_name) BOOST_MATH_STD_USING // Function values calculated on http://functions.wolfram.com/ // Note that Mathematica's EllipticE accepts k^2 as the second parameter. - static const boost::array::type, 3>, 10> data1 = {{ + static const boost::array::type, 3>, 12> data1 = {{ {{ SC_(0.0), SC_(0.0), SC_(0.0) }}, {{ SC_(-10.0), SC_(0.0), SC_(-10.0) }}, {{ SC_(-1.0), SC_(-1.0), SC_(-0.84147098480789650665250232163029899962256306079837) }}, @@ -95,6 +95,8 @@ void test_spots(T, const char* type_name) {{ SC_(1e+10), SC_(-0.5), SC_(9.3421545766487137036576748555295222252286528414669e9) }}, {{ SC_(7.3786976294838206464e19) /*static_cast(ldexp(T(1), 66))*/, SC_(0.390625) /*T(400) / 1024*/, SC_(7.0886102721911705466476846969992069994308167515242e19) }}, {{ SC_(9.3536104789177786765035829293842113257979682750464e49) /*static_cast(ldexp(T(1), 166))*/, SC_(0.87890625) /*T(900) / 1024*/, SC_(7.1259011068364515942912094521783688927118026465790e49) }}, + {{ SC_(0.25), SC_(1.5), SC_(0.244087118441983436818717707617920319373286836562840) }}, + {{ SC_(0.125), SC_(4.5), SC_(0.118076756678411098995742003403224531993649663256045) }}, }}; do_test_ellint_e2(data1, type_name, "Elliptic Integral E: Mathworld Data"); @@ -128,5 +130,12 @@ void test_spots(T, const char* type_name) {{ SC_(0.00097656250000000000000000000000000000000000000000000), SC_(0.5), SC_(0.00097656246119489873806295171767681128826061680891539) }},{{ SC_(0.00048828125000000000000000000000000000000000000000000), SC_(0.5), SC_(0.00048828124514936177847275804383491089917731651869089) }},{{ SC_(0.00024414062500000000000000000000000000000000000000000), SC_(0.5), SC_(0.00024414062439367020469080959924292294147407037569089) }},{{ SC_(0.00012207031250000000000000000000000000000000000000000), SC_(0.5), SC_(0.00012207031242420877503577978533579671450656676021144) }},{{ SC_(0.000061035156250000000000000000000000000000000000000000), SC_(0.5), SC_(0.000061035156240526096862267116434822602398026203555135) }},{{ SC_(0.000030517578125000000000000000000000000000000000000000), SC_(0.5), SC_(0.000030517578123815762107245722156263286910312978330942) }},{{ SC_(0.000015258789062500000000000000000000000000000000000000), SC_(0.5), SC_(0.000015258789062351970263388913163340973814136929083865) }},{{ SC_(7.6293945312500000000000000000000000000000000000000e-6), SC_(0.5), SC_(7.6293945312314962829230890795991108894734462126936e-6) }},{{ SC_(3.8146972656250000000000000000000000000000000000000e-6), SC_(0.5), SC_(3.8146972656226870353653697266430602974836595561218e-6) }},{{ SC_(1.9073486328125000000000000000000000000000000000000e-6), SC_(0.5), SC_(1.9073486328122108794206707030707941437882919842603e-6) }},{{ SC_(9.5367431640625000000000000000000000000000000000000e-7), SC_(0.5), SC_(9.5367431640621385992758382186011213067376941980499e-7) }},{{ SC_(4.7683715820312500000000000000000000000000000000000e-7), SC_(0.5), SC_(4.7683715820312048249094797723177223079355575583105e-7) }},{{ SC_(2.3841857910156250000000000000000000000000000000000e-7), SC_(0.5), SC_(2.3841857910156193531136849713832334805104830239272e-7) }},{{ SC_(1.1920928955078125000000000000000000000000000000000e-7), SC_(0.5), SC_(1.1920928955078117941392106214180141285643896716624e-7) }},{{ SC_(5.9604644775390625000000000000000000000000000000000e-8), SC_(0.5), SC_(5.9604644775390616176740132767709895180494181165759e-8) }},{{ SC_(2.9802322387695312500000000000000000000000000000000e-8), SC_(0.5), SC_(2.9802322387695311397092516595963259352981751091479e-8) }},{{ SC_(1.4901161193847656250000000000000000000000000000000e-8), SC_(0.5), SC_(1.4901161193847656112136564574495392495854593212863e-8) }},{{ SC_(7.4505805969238281250000000000000000000000000000000e-9), SC_(0.5), SC_(7.4505805969238281077670705718119235956296952243088e-9) }},{{ SC_(3.7252902984619140625000000000000000000000000000000e-9), SC_(0.5), SC_(3.7252902984619140603458838214764904348802078740605e-9) }},{{ SC_(1.8626451492309570312500000000000000000000000000000e-9), SC_(0.5), SC_(1.8626451492309570309807354776845613039046039833520e-9) }},{{ SC_(9.3132257461547851562500000000000000000000000000000e-10), SC_(0.5), SC_(9.3132257461547851559134193471057016297384356039070e-10) }},{{ SC_(4.6566128730773925781250000000000000000000000000000e-10), SC_(0.5), SC_(4.6566128730773925780829274183882127037128569700108e-10) }},{{ SC_(2.3283064365386962890625000000000000000000000000000e-10), SC_(0.5), SC_(2.3283064365386962890572409272985265879639681374864e-10) }},{{ SC_(1.1641532182693481445312500000000000000000000000000e-10), SC_(0.5), SC_(1.1641532182693481445305926159123158234954916739431e-10) }},{{ SC_(5.8207660913467407226562500000000000000000000000000e-11), SC_(0.5), SC_(5.8207660913467407226554282698903947793693632351656e-11) }},{{ SC_(2.9103830456733703613281250000000000000000000000000e-11), SC_(0.5), SC_(2.9103830456733703613280222837362993474211703619812e-11) }},{{ SC_(1.4551915228366851806640625000000000000000000000000e-11), SC_(0.5), SC_(1.4551915228366851806640496604670374184276462939222e-11) }},{{ SC_(7.2759576141834259033203125000000000000000000000000e-12), SC_(0.5), SC_(7.2759576141834259033202964505837967730345578669885e-12) }},{{ SC_(3.6379788070917129516601562500000000000000000000000e-12), SC_(0.5), SC_(3.6379788070917129516601542438229745966293197333606e-12) }},{{ SC_(1.8189894035458564758300781250000000000000000000000e-12), SC_(0.5), SC_(1.8189894035458564758300778742278718245786649666697e-12) }},{{ SC_(9.0949470177292823791503906250000000000000000000000e-13), SC_(0.5), SC_(9.0949470177292823791503903115348397807233312083370e-13) }},{{ SC_(4.5474735088646411895751953125000000000000000000000e-13), SC_(0.5), SC_(4.5474735088646411895751952733168549725904164010421e-13) }},{{ SC_(2.2737367544323205947875976562500000000000000000000e-13), SC_(0.5), SC_(2.2737367544323205947875976513521068715738020501303e-13) }},{{ SC_(1.1368683772161602973937988281250000000000000000000e-13), SC_(0.5), SC_(1.1368683772161602973937988275127633589467252562663e-13) }},{{ SC_(5.6843418860808014869689941406250000000000000000000e-14), SC_(0.5), SC_(5.6843418860808014869689941398597041986834065703329e-14) }},{{ SC_(2.8421709430404007434844970703125000000000000000000e-14), SC_(0.5), SC_(2.8421709430404007434844970702168380248354258212916e-14) }},{{ SC_(1.4210854715202003717422485351562500000000000000000e-14), SC_(0.5), SC_(1.4210854715202003717422485351442922531044282276615e-14) }},{{ SC_(7.1054273576010018587112426757812500000000000000000e-15), SC_(0.5), SC_(7.1054273576010018587112426757663028163805352845768e-15) }},{{ SC_(3.5527136788005009293556213378906250000000000000000e-15), SC_(0.5), SC_(3.5527136788005009293556213378887566020475669105721e-15) }},{{ SC_(1.7763568394002504646778106689453125000000000000000e-15), SC_(0.5), SC_(1.7763568394002504646778106689450789502559458638215e-15) }},{{ SC_(8.8817841970012523233890533447265625000000000000000e-16), SC_(0.5), SC_(8.8817841970012523233890533447262705628199323297769e-16) }},{{ SC_(4.4408920985006261616945266723632812500000000000000e-16), SC_(0.5), SC_(4.4408920985006261616945266723632447578524915412221e-16) }},{{ SC_(2.2204460492503130808472633361816406250000000000000e-16), SC_(0.5), SC_(2.2204460492503130808472633361816360634815614426528e-16) }},{{ SC_(1.1102230246251565404236316680908203125000000000000e-16), SC_(0.5), SC_(1.1102230246251565404236316680908197423101951803316e-16) }},{{ SC_(5.5511151231257827021181583404541015625000000000000e-17), SC_(0.5), SC_(5.5511151231257827021181583404541008497627439754145e-17) }},{{ SC_(2.7755575615628913510590791702270507812500000000000e-17), SC_(0.5), SC_(2.7755575615628913510590791702270506921578429969268e-17) }},{{ SC_(1.3877787807814456755295395851135253906250000000000e-17), SC_(0.5), SC_(1.3877787807814456755295395851135253794884803746159e-17) }},{{ SC_(6.9388939039072283776476979255676269531250000000000e-18), SC_(0.5), SC_(6.9388939039072283776476979255676269392043504682698e-18) }},{{ SC_(3.4694469519536141888238489627838134765625000000000e-18), SC_(0.5), SC_(3.4694469519536141888238489627838134748224188085337e-18) }},{{ SC_(1.7347234759768070944119244813919067382812500000000e-18), SC_(0.5), SC_(1.7347234759768070944119244813919067380637398510667e-18) }},{{ SC_(8.6736173798840354720596224069595336914062500000000e-19), SC_(0.5), SC_(8.6736173798840354720596224069595336911343623138334e-19) }},{{ SC_(4.3368086899420177360298112034797668457031250000000e-19), SC_(0.5), SC_(4.3368086899420177360298112034797668456691390392292e-19) }},{{ SC_(2.1684043449710088680149056017398834228515625000000e-19), SC_(0.5), SC_(2.1684043449710088680149056017398834228473142549036e-19) }},{{ SC_(1.0842021724855044340074528008699417114257812500000e-19), SC_(0.5), SC_(1.0842021724855044340074528008699417114252502193630e-19) }},{{ SC_(5.4210108624275221700372640043497085571289062500000e-20), SC_(0.5), SC_(5.4210108624275221700372640043497085571282424617037e-20) }},{{ SC_(2.7105054312137610850186320021748542785644531250000e-20), SC_(0.5), SC_(2.7105054312137610850186320021748542785643701514630e-20) }},{{ SC_(1.3552527156068805425093160010874271392822265625000e-20), SC_(0.5), SC_(1.3552527156068805425093160010874271392822161908079e-20) }},{{ SC_(6.7762635780344027125465800054371356964111328125000e-21), SC_(0.5), SC_(6.7762635780344027125465800054371356964111198478848e-21) }},{{ SC_(3.3881317890172013562732900027185678482055664062500e-21), SC_(0.5), SC_(3.3881317890172013562732900027185678482055647856731e-21) }},{{ SC_(1.6940658945086006781366450013592839241027832031250e-21), SC_(0.5), SC_(1.6940658945086006781366450013592839241027830005529e-21) }},{{ SC_(8.4703294725430033906832250067964196205139160156250e-22), SC_(0.5), SC_(8.4703294725430033906832250067964196205139157624099e-22) }},{{ SC_(4.2351647362715016953416125033982098102569580078125e-22), SC_(0.5), SC_(4.2351647362715016953416125033982098102569579761606e-22) }},{{ SC_(2.1175823681357508476708062516991049051284790039062e-22), SC_(0.5), SC_(2.1175823681357508476708062516991049051284789999498e-22) }},{{ SC_(1.0587911840678754238354031258495524525642395019531e-22), SC_(0.5), SC_(1.0587911840678754238354031258495524525642395014586e-22) }},{{ SC_(5.2939559203393771191770156292477622628211975097656e-23), SC_(0.5), SC_(5.2939559203393771191770156292477622628211975091474e-23) }},{{ SC_(2.6469779601696885595885078146238811314105987548828e-23), SC_(0.5), SC_(2.6469779601696885595885078146238811314105987548055e-23) }},{{ SC_(1.3234889800848442797942539073119405657052993774414e-23), SC_(0.5), SC_(1.3234889800848442797942539073119405657052993774317e-23) }},{{ SC_(6.6174449004242213989712695365597028285264968872070e-24), SC_(0.5), SC_(6.6174449004242213989712695365597028285264968871950e-24) }},{{ SC_(3.3087224502121106994856347682798514142632484436035e-24), SC_(0.5), SC_(3.3087224502121106994856347682798514142632484436020e-24) }},{{ SC_(1.6543612251060553497428173841399257071316242218018e-24), SC_(0.5), SC_(1.6543612251060553497428173841399257071316242218016e-24) }},{{ SC_(8.2718061255302767487140869206996285356581211090088e-25), SC_(0.5), SC_(8.2718061255302767487140869206996285356581211090086e-25) }},{{ SC_(4.1359030627651383743570434603498142678290605545044e-25), SC_(0.5), SC_(4.1359030627651383743570434603498142678290605545044e-25) }} } }; do_test_ellint_e2(small_angles, type_name, "Elliptic Integral E: Small Angles"); + // + // Test error handling: + // + BOOST_CHECK_EQUAL(boost::math::ellint_2(T(1)), T(1)); + BOOST_CHECK_EQUAL(boost::math::ellint_2(T(-1)), T(1)); + BOOST_CHECK_THROW(boost::math::ellint_2(T(1.5)), std::domain_error); + BOOST_CHECK_THROW(boost::math::ellint_2(T(-1.5)), std::domain_error); } diff --git a/test/test_ellint_3.hpp b/test/test_ellint_3.hpp index bac105844..770b08cdc 100644 --- a/test/test_ellint_3.hpp +++ b/test/test_ellint_3.hpp @@ -87,7 +87,7 @@ void test_spots(T, const char* type_name) { BOOST_MATH_STD_USING // function values calculated on http://functions.wolfram.com/ - static const boost::array::type, 4>, 65> data1 = {{ + static const boost::array::type, 4>, 70> 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) }}, @@ -166,6 +166,12 @@ void test_spots(T, const char* type_name) { { 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) } }, + // cases where |k| > 1: + {{ SC_(1.015625), SC_(0.125), SC_(2.5), SC_(0.12780840244950364924992513047014683502850891674019968726)}}, + {{ SC_(1.015625), SC_(0.125), SC_(4.5), SC_(0.133468341825478826487248053944106425799790398297092314041)}}, + {{ SC_(-1.015625), SC_(0.125), SC_(4.5), SC_(0.131998693459801470974303284674812630138938285546080214149)}}, + {{ SC_(-1.015625), SC_(-0.125), SC_(4.5), SC_(-0.13199869345980147097430328467481263013893828554608021414)}}, + {{ SC_(-1.015625), SC_(-0.125), SC_(1.5), SC_(-0.12508193549646497011359938978158598001227028251706394704)}}, } }; do_test_ellint_pi3(data1, type_name, "Elliptic Integral PI: Mathworld Data"); @@ -207,7 +213,7 @@ void test_spots(T, const char* type_name) do_test_ellint_pi2(ellint_pi2_data, type_name, "Complete Elliptic Integral PI: Random Data"); // Special cases, exceptions etc: - BOOST_MATH_CHECK_THROW(boost::math::ellint_3(T(1.0001), T(-1), T(0)), std::domain_error); + BOOST_MATH_CHECK_THROW(boost::math::ellint_3(T(2.1), T(-1), T(0.5)), std::domain_error); BOOST_MATH_CHECK_THROW(boost::math::ellint_3(T(0.5), T(20), T(1.5)), std::domain_error); BOOST_MATH_CHECK_THROW(boost::math::ellint_3(T(1.0001), T(-1)), std::domain_error); BOOST_MATH_CHECK_THROW(boost::math::ellint_3(T(0.5), T(1)), std::domain_error);