@@ -160,7 +160,7 @@ void test_spots5(T, const char* type_name) | |||
| 160 | 160 | template <class T> | |
| 161 | 161 | void test_spots6(T, const char* type_name) | |
| 162 | 162 | { | |
| 163 | - static const boost::array<boost::array<T, 4>, 75> hypergeometric_1F1_bugs = { { | ||
| 163 | + static const boost::array<boost::array<T, 4>, 91> hypergeometric_1F1_bugs = { { | ||
| 164 | 164 | { { static_cast<double>(17955.561660766602), static_cast<double>(9.6968994205831605e-09), static_cast<double>(-82.406154185533524), SC_(6.98056008378736714088730927132364938220428678e-11) }}, | |
| 165 | 165 | { { static_cast<double>(17955.561660766602), static_cast<double>(-9.6968994205831605e-09), static_cast<double>(-82.406154185533524), SC_(-6.98055306629610746072607353939306734740549551e-11) }}, | |
| 166 | 166 | { { static_cast<double>(-17955.561660766602), static_cast<double>(-9.6968994205831605e-09), static_cast<double>(82.406154185533524), SC_(-42897094853118832762870100.8669248353530950866) }} , | |
@@ -267,6 +267,24 @@ void test_spots6(T, const char* type_name) | |||
| 267 | 267 | { { std::ldexp((double)10485122560373760, -40), std::ldexp((double)-11098279821997376, -39), std::ldexp((double)16925852270592000, -45), SC_(9.77378642649349178995585980824930703376759021e-98) } }, | |
| 268 | 268 | { { std::ldexp((double)10485292967829248, -40), std::ldexp((double)-14859721380002656, -35), std::ldexp((double)13729956970496000, -44), SC_(3.41094899910311302761937103011397882987669395e-08) } }, | |
| 269 | 269 | { { std::ldexp((double)10485037389193216, -40), std::ldexp((double)-10840488483391544, -35), std::ldexp((double)17577061875712000, -45), SC_(2.8030884395368690164859926372380406504460219e-07) } }, | |
| 270 | + // | ||
| 271 | + // Negative a and b worst cases: | ||
| 272 | + { { std::ldexp((double)-9281686323200000, -44), std::ldexp((double)-14062138056704000, -44), std::ldexp((double)13563284652032000, -44), SC_(2.83381029611748905436564183928049453625733389e+265) } }, | ||
| 273 | + { { std::ldexp((double)-17049048150016000, -44), std::ldexp((double)-16971363917824000, -45), std::ldexp((double)11759598960640000, -49), SC_(4636596575297708282.15391199523219256661832333) }}, | ||
| 274 | + { { std::ldexp((double)-14233964060672000, -45), std::ldexp((double)-12648356216832000, -47), std::ldexp((double)9597206757376000, -46), SC_(-1.29952965544474451915331906705211320124261355e+104) }}, | ||
| 275 | + { { std::ldexp((double)-16705334214656000, -45), std::ldexp((double)-15447756718080000, -46), std::ldexp((double)16395884134400000, -47), SC_(5.40680141346616359293013198457674276017117348e+113) }}, | ||
| 276 | + { { std::ldexp((double)-13991530405888000, -45), std::ldexp((double)-10196587347968000, -46), std::ldexp((double)13331347734528000, -46), SC_(1.28612752976615347819085089716937824474111365e+138) }}, | ||
| 277 | + { { std::ldexp((double)-15134950760448000, -45), std::ldexp((double)-14587193786368000, -48), std::ldexp((double)17022855921664000, -46), SC_(-8.81689040877580073465185463207591010592963947e+115) }}, | ||
| 278 | + { { std::ldexp((double)-14854672039936000, -45), std::ldexp((double)-10436558200832000, -45), std::ldexp((double)11370918969344000, -47), SC_(8.85535247272534117445528460568920680343270651e+54) } }, | ||
| 279 | + { { std::ldexp((double)-16711069286400000, -46), std::ldexp((double)-14809815056384000, -46), std::ldexp((double)10469312954368000, -47), SC_(50343352353398198766339890377962553344.0) } }, | ||
| 280 | + { { std::ldexp((double)-15026786402304000, -45), std::ldexp((double)-16687356968960000, -46), std::ldexp((double)14895621603328000, -47), SC_(2.85329560424602656900599696665580727040444839e+95) } }, | ||
| 281 | + { { std::ldexp((double)-15519073435648000, -45), std::ldexp((double)-14162009718784000, -45), std::ldexp((double)9997818855424000, -48), SC_(95767987018108517.7639995774279100260173436254) } }, | ||
| 282 | + { { std::ldexp((double)-15317481275392000, -46), std::ldexp((double)-16531865931776000, -44), std::ldexp((double)17586268880896000, -45), SC_(1.47012480470837240834700634331053708005164679e+104) }}, | ||
| 283 | + { { std::ldexp((double)-11335669673984000, -44), std::ldexp((double)-13146047094784000, -44), std::ldexp((double)13671437864960000, -44), SC_(-2.18876072849870893180776779453843962111085257e+288) }}, | ||
| 284 | + { { std::ldexp((double)-16877985234944000, -46), std::ldexp((double)-14384006086656000, -46), std::ldexp((double)9074349342720000, -47), SC_(15376193613462463541358751744655360.0) }}, | ||
| 285 | + { { std::ldexp((double)-9751199809536000, -45), std::ldexp((double)-17654191685632000, -47), std::ldexp((double)10587451850752000, -47), SC_(-1.9601415510439595625538337964298353914980331e+68) }}, | ||
| 286 | + { { std::ldexp((double)-15233620754432000, -45), std::ldexp((double)-12708283072512000, -46), std::ldexp((double)10255461007360000, -46), SC_(-5.43441063616790758618595678580168066778261756e+125) }}, | ||
| 287 | + { { std::ldexp((double)-11241354149888000, -45), std::ldexp((double)-9580579905536000, -45), std::ldexp((double)12224976846848000, -47), SC_(1.20468565484700674058707264904280026536015299e+46) }}, | ||
| 270 | 288 | } }; | |
| 271 | 289 | static const boost::array<boost::array<T, 4>, 2> hypergeometric_1F1_big_bugs = { { | |
| 272 | 290 | #if DBL_MAX_EXP == LDBL_MAX_EXP | |
@@ -122,7 +122,7 @@ int main() | |||
| 122 | 122 | mpfr_float mp_expected; | |
| 123 | 123 | ||
| 124 | 124 | try { | |
| 125 | - mp_expected = boost::math::hypergeometric_pFq_precision({ mpfr_float(a) }, { mpfr_float(b) }, mpfr_float(z), 25, 3.0); | ||
| 125 | + mp_expected = boost::math::hypergeometric_pFq_precision({ mpfr_float(a) }, { mpfr_float(b) }, mpfr_float(z), 25, 200.0); | ||
| 126 | 126 | expected = (test_type)mp_expected; | |
| 127 | 127 | } | |
| 128 | 128 | catch (const std::exception&) | |
@@ -56,7 +56,7 @@ int main() | |||
| 56 | 56 | std::cin >> b_mult; | |
| 57 | 57 | ||
| 58 | 58 | double error_limit = 200; | |
| 59 | - double time_limit = 100.0; | ||
| 59 | + double time_limit = 10.0; | ||
| 60 | 60 | ||
| 61 | 61 | for (test_type a = a_start; a < a_end; a_start < 0 ? a /= a_mult : a *= a_mult) | |
| 62 | 62 | { | |
@@ -65,9 +65,10 @@ int main() | |||
| 65 | 65 | test_type z_mult = 2; | |
| 66 | 66 | test_type last_good = 0; | |
| 67 | 67 | test_type bad = 0; | |
| 68 | - for (test_type z = 1; z < 1e10; z *= z_mult, z_mult *= 2) | ||
| 69 | - { | ||
| 70 | - try { | ||
| 68 | + try { | ||
| 69 | + for (test_type z = 1; z < 1e10; z *= z_mult, z_mult *= 2) | ||
| 70 | + { | ||
| 71 | + // std::cout << "z = " << z << std::endl; | ||
| 71 | 72 | boost::uintmax_t max_iter = 1000; | |
| 72 | 73 | test_type calc = boost::math::tools::function_ratio_from_forwards_recurrence(boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients<test_type>(a, b, z), std::numeric_limits<test_type>::epsilon() * 2, max_iter); | |
| 73 | 74 | test_type reference = (test_type)(boost::math::hypergeometric_pFq_precision({ mpfr_float(a) }, { mpfr_float(b) }, mpfr_float(z), 50, time_limit) / boost::math::hypergeometric_pFq_precision({ mpfr_float(a + 1) }, { mpfr_float(b + 1) }, mpfr_float(z), std::numeric_limits<test_type>::digits10 * 2, time_limit)); | |
@@ -83,11 +84,11 @@ int main() | |||
| 83 | 84 | bad = z; | |
| 84 | 85 | } | |
| 85 | 86 | } | |
| 86 | - catch (const std::exception& e) | ||
| 87 | - { | ||
| 88 | - std::cout << "Unexpected exception: " << e.what() << std::endl; | ||
| 89 | - std::cout << "For a = " << a << " b = " << b << " z = " << z << std::endl; | ||
| 90 | - } | ||
| 87 | + } | ||
| 88 | + catch (const std::exception& e) | ||
| 89 | + { | ||
| 90 | + std::cout << "Unexpected exception: " << e.what() << std::endl; | ||
| 91 | + std::cout << "For a = " << a << " b = " << b << " z = " << bad * z_mult / 2 << std::endl; | ||
| 91 | 92 | } | |
| 92 | 93 | test_type z_limit; | |
| 93 | 94 | if (0 == bad) | |
@@ -109,14 +110,16 @@ int main() | |||
| 109 | 110 | }, bad, last_good, boost::math::tools::equal_floor()).first; | |
| 110 | 111 | z_limit = floor(z_limit + 2); // Give ourselves some headroom! | |
| 111 | 112 | } | |
| 113 | + // std::cout << "z_limit = " << z_limit << std::endl; | ||
| 112 | 114 | // | |
| 113 | 115 | // Now over again for backwards recurrence domain at the same points: | |
| 114 | 116 | // | |
| 115 | - bad = z_limit; | ||
| 117 | + bad = z_limit > 1e10 ? 1e10 : z_limit; | ||
| 116 | 118 | last_good = 0; | |
| 117 | 119 | z_mult = 1.1; | |
| 118 | - for (test_type z = z_limit; z > 1; z /= z_mult, z_mult *= 2) | ||
| 120 | + for (test_type z = bad; z > 1; z /= z_mult, z_mult *= 2) | ||
| 119 | 121 | { | |
| 122 | + // std::cout << "z = " << z << std::endl; | ||
| 120 | 123 | try { | |
| 121 | 124 | boost::uintmax_t max_iter = 1000; | |
| 122 | 125 | test_type calc = boost::math::tools::function_ratio_from_backwards_recurrence(boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients<test_type>(a, b, z), std::numeric_limits<test_type>::epsilon() * 2, max_iter); | |
@@ -135,6 +138,7 @@ int main() | |||
| 135 | 138 | } | |
| 136 | 139 | catch (const std::exception& e) | |
| 137 | 140 | { | |
| 141 | + bad = z; | ||
| 138 | 142 | std::cout << "Unexpected exception: " << e.what() << std::endl; | |
| 139 | 143 | std::cout << "For a = " << a << " b = " << b << " z = " << z << std::endl; | |
| 140 | 144 | } | |
0 commit comments