1 2 /////////////////////////////////////////////////////////////////////////////// 3 // Copyright 2019 John Maddock 4 // Distributed under the Boost 5 // Software License, Version 1.0. (See accompanying file 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #ifndef BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP 9 #define BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP 10 11 namespace boost { 12 namespace math { 13 namespace detail { 14 // 15 // hypergeometric_1F1_negative_b_recurrence_region maps out the domains over which 16 // forward and backwards recurrences are stable when b < 0. 17 // Returns -1, 0, or 1: 18 // -1: Backwards recurrence is stable. 19 // +1: Forwards recurrence is stable. 20 // 0: Neither recurrence is stable. 21 // 22 template <class T> hypergeometric_1F1_negative_b_recurrence_region(const T & a,const T & b,const T & z)23 int hypergeometric_1F1_negative_b_recurrence_region(const T& a, const T& b, const T& z) 24 { 25 BOOST_MATH_STD_USING 26 static const double domain[][4] = { 27 { 1e-300, -1000000.1, 278609.88983674475, 465687}, 28 { 1e-300, -400000.03999999998, 111530.83622048119, 111544}, 29 { 1e-300, -160000.016, 44699.113858309654, 44712}, 30 { 1e-300, -64000.006399999998, 17966.035866477272, 17980}, 31 { 1e-300, -25600.002560000001, 7273.793013139204, 7287}, 32 { 1e-300, -10240.001024000001, 2998.0791015625, 3012}, 33 { 1e-300, -4096.0004096000002, 1291.0461647727273, 1306}, 34 { 1e-300, -1638.40016384, 619.421875, 636}, 35 { 1e-300, -655.36006553599998, 374.62926136363637, 397}, 36 { 1e-300, -262.14402621440001, 335.29958677685943, 370}, 37 { 1e-300, -104.85761048576001, 412.83057851239664, 462}, 38 { 1e-300, -41.943044194304001, 513.00603693181824, 570}, 39 { 1e-300, -16.777217677721602, 584.14449896694214, 644}, 40 { 1e-300, -6.7108870710886404, 623.30417097107443, 684}, 41 { 1e-300, -2.6843548284354561, 642.31960227272725, 704}, 42 { 1e-300, -1.0737419313741825, 650.20738636363626, 711}, 43 { 1.0000000000000001e-275, -1000000.1, 278597.3203069513, 448872}, 44 { 1.0000000000000001e-275, -400000.03999999998, 111518.14741654831, 111531}, 45 { 1.0000000000000001e-275, -160000.016, 44686.621781782669, 44700}, 46 { 1.0000000000000001e-275, -64000.006399999998, 17953.944740988994, 17967}, 47 { 1.0000000000000001e-275, -25600.002560000001, 7261.1431107954559, 7274}, 48 { 1.0000000000000001e-275, -10240.001024000001, 2985.014559659091, 2999}, 49 { 1.0000000000000001e-275, -4096.0004096000002, 1277.4573863636363, 1292}, 50 { 1.0000000000000001e-275, -1638.40016384, 603.88778409090912, 620}, 51 { 1.0000000000000001e-275, -655.36006553599998, 354.10653409090912, 376}, 52 { 1.0000000000000001e-275, -262.14402621440001, 303.91367510330571, 337}, 53 { 1.0000000000000001e-275, -104.85761048576001, 367.0454545454545, 416}, 54 { 1.0000000000000001e-275, -41.943044194304001, 460.06028861053716, 516}, 55 { 1.0000000000000001e-275, -16.777217677721602, 528.36389462809916, 588}, 56 { 1.0000000000000001e-275, -6.7108870710886404, 566.33555010330565, 627}, 57 { 1.0000000000000001e-275, -2.6843548284354561, 585.32541322314046, 646}, 58 { 1.0000000000000001e-275, -1.0737419313741825, 593.0082967458676, 654}, 59 { 1.0000000000000002e-250, -1000000.1, 278584.75303113955, 431059}, 60 { 1.0000000000000002e-250, -400000.03999999998, 111505.53022349965, 111519}, 61 { 1.0000000000000002e-250, -160000.016, 44674.060190374199, 44687}, 62 { 1.0000000000000002e-250, -64000.006399999998, 17941.25452769886, 17954}, 63 { 1.0000000000000002e-250, -25600.002560000001, 7248.2002840909081, 7262}, 64 { 1.0000000000000002e-250, -10240.001024000001, 2972.017267400568, 2985}, 65 { 1.0000000000000002e-250, -4096.0004096000002, 1263.6363636363637, 1278}, 66 { 1.0000000000000002e-250, -1638.40016384, 588.35369318181824, 604}, 67 { 1.0000000000000002e-250, -655.36006553599998, 334.18039772727275, 355}, 68 { 1.0000000000000002e-250, -262.14402621440001, 273.7357954545455, 306}, 69 { 1.0000000000000002e-250, -104.85761048576001, 323.05010330578506, 370}, 70 { 1.0000000000000002e-250, -41.943044194304001, 407.41541838842977, 463}, 71 { 1.0000000000000002e-250, -16.777217677721602, 472.78376807851242, 532}, 72 { 1.0000000000000002e-250, -6.7108870710886404, 509.47443181818176, 570}, 73 { 1.0000000000000002e-250, -2.6843548284354561, 528.11466942148763, 589}, 74 { 1.0000000000000002e-250, -1.0737419313741825, 535.52815082644634, 596}, 75 { 1.0000000000000003e-225, -1000000.1, 278572.12184906006, 278585}, 76 { 1.0000000000000003e-225, -400000.03999999998, 111493.21068649805, 551165}, 77 { 1.0000000000000003e-225, -160000.016, 44661.126509232956, 44674}, 78 { 1.0000000000000003e-225, -64000.006399999998, 17928.069602272728, 17942}, 79 { 1.0000000000000003e-225, -25600.002560000001, 7235.550426136364, 7249}, 80 { 1.0000000000000003e-225, -10240.001024000001, 2959.153053977273, 2973}, 81 { 1.0000000000000003e-225, -4096.0004096000002, 1250.2649147727275, 1264}, 82 { 1.0000000000000003e-225, -1638.40016384, 573.37073863636363, 589}, 83 { 1.0000000000000003e-225, -655.36006553599998, 315.21946022727275, 335}, 84 { 1.0000000000000003e-225, -262.14402621440001, 245.11137654958674, 275}, 85 { 1.0000000000000003e-225, -104.85761048576001, 280.71022727272725, 326}, 86 { 1.0000000000000003e-225, -41.943044194304001, 355.45519111570246, 411}, 87 { 1.0000000000000003e-225, -16.777217677721602, 417.41670971074382, 476}, 88 { 1.0000000000000003e-225, -6.7108870710886404, 452.71984762396687, 513}, 89 { 1.0000000000000003e-225, -2.6843548284354561, 470.45648243801656, 532}, 90 { 1.0000000000000003e-225, -1.0737419313741825, 478.06438855888422, 539}, 91 { 1.0000000000000004e-200, -1000000.1, 278559.54284667969, 278573}, 92 { 1.0000000000000004e-200, -400000.03999999998, 111480.15247691762, 111493}, 93 { 1.0000000000000004e-200, -160000.016, 44648.944635564636, 44662}, 94 { 1.0000000000000004e-200, -64000.006399999998, 17916.076071999294, 17929}, 95 { 1.0000000000000004e-200, -25600.002560000001, 7223.06005859375, 7236}, 96 { 1.0000000000000004e-200, -10240.001024000001, 2946.222301136364, 2960}, 97 { 1.0000000000000004e-200, -4096.0004096000002, 1236.0916193181818, 1251}, 98 { 1.0000000000000004e-200, -1638.40016384, 558.40909090909076, 574}, 99 { 1.0000000000000004e-200, -655.36006553599998, 297.05220170454544, 316}, 100 { 1.0000000000000004e-200, -262.14402621440001, 218.16438533057845, 247}, 101 { 1.0000000000000004e-200, -104.85761048576001, 239.76949896694211, 283}, 102 { 1.0000000000000004e-200, -41.943044194304001, 304.40728305785115, 359}, 103 { 1.0000000000000004e-200, -16.777217677721602, 362.01349431818181, 421}, 104 { 1.0000000000000004e-200, -6.7108870710886404, 396.18123708677683, 456}, 105 { 1.0000000000000004e-200, -2.6843548284354561, 413.36518595041321, 474}, 106 { 1.0000000000000004e-200, -1.0737419313741825, 420.31249999999994, 482}, 107 { 1.0000000000000006e-175, -1000000.1, 278547.12638697342, 465687}, 108 { 1.0000000000000006e-175, -400000.03999999998, 111468.15407492899, 111481}, 109 { 1.0000000000000006e-175, -160000.016, 44636.134832208802, 44649}, 110 { 1.0000000000000006e-175, -64000.006399999998, 17903.091796875, 17917}, 111 { 1.0000000000000006e-175, -25600.002560000001, 7210.247247869318, 7223}, 112 { 1.0000000000000006e-175, -10240.001024000001, 2933.2915482954545, 2947}, 113 { 1.0000000000000006e-175, -4096.0004096000002, 1223.600497159091, 1237}, 114 { 1.0000000000000006e-175, -1638.40016384, 544.06640625, 559}, 115 { 1.0000000000000006e-175, -655.36006553599998, 279.11931818181813, 298}, 116 { 1.0000000000000006e-175, -262.14402621440001, 192.94921875, 220}, 117 { 1.0000000000000006e-175, -104.85761048576001, 200.78641528925618, 242}, 118 { 1.0000000000000006e-175, -41.943044194304001, 254.19679752066114, 308}, 119 { 1.0000000000000006e-175, -16.777217677721602, 307.10227272727263, 366}, 120 { 1.0000000000000006e-175, -6.7108870710886404, 339.36918904958679, 400}, 121 { 1.0000000000000006e-175, -2.6843548284354561, 356.1554106404958, 417}, 122 { 1.0000000000000006e-175, -1.0737419313741825, 363.13694473140492, 424}, 123 { 1.0000000000000007e-150, -1000000.1, 278534.48812689661, 448872}, 124 { 1.0000000000000007e-150, -400000.03999999998, 111455.15580610794, 111468}, 125 { 1.0000000000000007e-150, -160000.016, 44623.643454811798, 44637}, 126 { 1.0000000000000007e-150, -64000.006399999998, 17891.00373493541, 17904}, 127 { 1.0000000000000007e-150, -25600.002560000001, 7197.631392045454, 7211}, 128 { 1.0000000000000007e-150, -10240.001024000001, 2920.3607954545455, 2934}, 129 { 1.0000000000000007e-150, -4096.0004096000002, 1210.3267045454545, 1224}, 130 { 1.0000000000000007e-150, -1638.40016384, 530.0033735795455, 545}, 131 { 1.0000000000000007e-150, -655.36006553599998, 262.37215909090907, 280}, 132 { 1.0000000000000007e-150, -262.14402621440001, 169.07024793388427, 194}, 133 { 1.0000000000000007e-150, -104.85761048576001, 164.12706611570246, 203}, 134 { 1.0000000000000007e-150, -41.943044194304001, 206.02079028925615, 258}, 135 { 1.0000000000000007e-150, -16.777217677721602, 253.0191115702479, 311}, 136 { 1.0000000000000007e-150, -6.7108870710886404, 283.23056559917353, 343}, 137 { 1.0000000000000007e-150, -2.6843548284354561, 299.29041838842977, 360}, 138 { 1.0000000000000007e-150, -1.0737419313741825, 305.7925490702479, 367}, 139 { 1.0000000000000008e-125, -1000000.1, 278522.04145396838, 285024}, 140 { 1.0000000000000008e-125, -400000.03999999998, 111443.00279374557, 111456}, 141 { 1.0000000000000008e-125, -160000.016, 44611.143155184654, 44624}, 142 { 1.0000000000000008e-125, -64000.006399999998, 17878.306263316765, 17891}, 143 { 1.0000000000000008e-125, -25600.002560000001, 7185.1384943181802, 7198}, 144 { 1.0000000000000008e-125, -10240.001024000001, 2907.430042613636, 2921}, 145 { 1.0000000000000008e-125, -4096.0004096000002, 1197.0621448863635, 1211}, 146 { 1.0000000000000008e-125, -1638.40016384, 516.05983664772725, 531}, 147 { 1.0000000000000008e-125, -655.36006553599998, 246.17897727272725, 263}, 148 { 1.0000000000000008e-125, -262.14402621440001, 147.2197830578512, 171}, 149 { 1.0000000000000008e-125, -104.85761048576001, 130.599173553719, 166}, 150 { 1.0000000000000008e-125, -41.943044194304001, 159.12190082644628, 209}, 151 { 1.0000000000000008e-125, -16.777217677721602, 199.5635330578512, 256}, 152 { 1.0000000000000008e-125, -6.7108870710886404, 227.1807205578512, 287}, 153 { 1.0000000000000008e-125, -2.6843548284354561, 242.41670971074376, 303}, 154 { 1.0000000000000008e-125, -1.0737419313741825, 248.39036673553716, 309}, 155 { 1.0000000000000009e-100, -1000000.1, 278509.36086203833, 278546}, 156 { 1.0000000000000009e-100, -400000.03999999998, 111430.10303574696, 551165}, 157 { 1.0000000000000009e-100, -160000.016, 44598.652055220169, 44612}, 158 { 1.0000000000000009e-100, -64000.006399999998, 17865.125532670456, 17879}, 159 { 1.0000000000000009e-100, -25600.002560000001, 7172.046519886364, 7186}, 160 { 1.0000000000000009e-100, -10240.001024000001, 2895.015980113636, 2908}, 161 { 1.0000000000000009e-100, -4096.0004096000002, 1184.2329545454545, 1198}, 162 { 1.0000000000000009e-100, -1638.40016384, 502.04403409090901, 517}, 163 { 1.0000000000000009e-100, -655.36006553599998, 231.13849431818178, 247}, 164 { 1.0000000000000009e-100, -262.14402621440001, 128.02290482954544, 149}, 165 { 1.0000000000000009e-100, -104.85761048576001, 100.76188016528923, 133}, 166 { 1.0000000000000009e-100, -41.943044194304001, 115.10072314049584, 162}, 167 { 1.0000000000000009e-100, -16.777217677721602, 147.05255681818178, 203}, 168 { 1.0000000000000009e-100, -6.7108870710886404, 171.19963842975204, 231}, 169 { 1.0000000000000009e-100, -2.6843548284354561, 185.58367768595039, 246}, 170 { 1.0000000000000009e-100, -1.0737419313741825, 191.0575929752066, 252}, 171 { 1.0000000000000009e-75, -1000000.1, 278497.00512279174, 278510}, 172 { 1.0000000000000009e-75, -400000.03999999998, 111417.96751369131, 111431}, 173 { 1.0000000000000009e-75, -160000.016, 44586.151478160507, 44599}, 174 { 1.0000000000000009e-75, -64000.006399999998, 17853.128506747154, 17866}, 175 { 1.0000000000000009e-75, -25600.002560000001, 7160.0009918212891, 7173}, 176 { 1.0000000000000009e-75, -10240.001024000001, 2882.563210227273, 2896}, 177 { 1.0000000000000009e-75, -4096.0004096000002, 1171.4037642045455, 1185}, 178 { 1.0000000000000009e-75, -1638.40016384, 489.03941761363637, 503}, 179 { 1.0000000000000009e-75, -655.36006553599998, 216.05113636363637, 232}, 180 { 1.0000000000000009e-75, -262.14402621440001, 110.08296745867767, 129}, 181 { 1.0000000000000009e-75, -104.85761048576001, 74.400826446280988, 102}, 182 { 1.0000000000000009e-75, -41.943044194304001, 75.619834710743788, 118}, 183 { 1.0000000000000009e-75, -16.777217677721602, 96.373966942148741, 150}, 184 { 1.0000000000000009e-75, -6.7108870710886404, 116.33910123966942, 175}, 185 { 1.0000000000000009e-75, -2.6843548284354561, 129.00947507747935, 189}, 186 { 1.0000000000000009e-75, -1.0737419313741825, 134.06379132231399, 195}, 187 { 1.0000000000000011e-50, -1000000.1, 278484.14271457132, 465687}, 188 { 1.0000000000000011e-50, -400000.03999999998, 111405.16246448863, 111418}, 189 { 1.0000000000000011e-50, -160000.016, 44573.165838068184, 44587}, 190 { 1.0000000000000011e-50, -64000.006399999998, 17840.147727272728, 17854}, 191 { 1.0000000000000011e-50, -25600.002560000001, 7147.375887784091, 7160}, 192 { 1.0000000000000011e-50, -10240.001024000001, 2869.888583096591, 2883}, 193 { 1.0000000000000011e-50, -4096.0004096000002, 1158.1576704545455, 1172}, 194 { 1.0000000000000011e-50, -1638.40016384, 476.00257457386363, 490}, 195 { 1.0000000000000011e-50, -655.36006553599998, 202.20170454545453, 217}, 196 { 1.0000000000000011e-50, -262.14402621440001, 94.02682722107437, 111}, 197 { 1.0000000000000011e-50, -104.85761048576001, 53.0810950413223, 76}, 198 { 1.0000000000000011e-50, -41.943044194304001, 42.355371900826441, 78}, 199 { 1.0000000000000011e-50, -16.777217677721602, 50.051652892561975, 100}, 200 { 1.0000000000000011e-50, -6.7108870710886404, 63.174070247933884, 120}, 201 { 1.0000000000000011e-50, -2.6843548284354561, 72.956805268595033, 132}, 202 { 1.0000000000000011e-50, -1.0737419313741825, 77.104855371900811, 138}, 203 { 1.0000000000000012e-25, -1000000.1, 278471.90274041548, 448844}, 204 { 1.0000000000000012e-25, -400000.03999999998, 111392.85056374289, 111423}, 205 { 1.0000000000000012e-25, -160000.016, 44561.0361328125, 44574}, 206 { 1.0000000000000012e-25, -64000.006399999998, 17828.149314186794, 17841}, 207 { 1.0000000000000012e-25, -25600.002560000001, 7134.765625, 7148}, 208 { 1.0000000000000012e-25, -10240.001024000001, 2857.211647727273, 2870}, 209 { 1.0000000000000012e-25, -4096.0004096000002, 1146.1576704545453, 1159}, 210 { 1.0000000000000012e-25, -1638.40016384, 463.0625, 476}, 211 { 1.0000000000000012e-25, -655.36006553599998, 189.27556818181819, 203}, 212 { 1.0000000000000012e-25, -262.14402621440001, 79.163223140495859, 95}, 213 { 1.0000000000000012e-25, -104.85761048576001, 36.15702479338843, 54}, 214 { 1.0000000000000012e-25, -41.943044194304001, 19.008264462809912, 44}, 215 { 1.0000000000000012e-25, -16.777217677721602, 14.220686983471072, 53}, 216 { 1.0000000000000012e-25, -6.7108870710886404, 15.207081141998497, 66}, 217 { 1.0000000000000012e-25, -2.6843548284354561, 19.000046957175051, 76}, 218 { 1.0000000000000012e-25, -1.0737419313741825, 21.00738364892468, 81}, 219 { 1, -1000000.1, 278455, 285026}, 220 { 1, -400000.03999999998, 111376, 111392}, 221 { 1, -160000.016, 44544, 44561}, 222 { 1, -64000.006399999998, 17812, 17828}, 223 { 1, -25600.002560000001, 7119, 7135}, 224 { 1, -10240.001024000001, 2841, 2858}, 225 { 1, -4096.0004096000002, 1130, 1147}, 226 { 1, -1638.40016384, 447, 464}, 227 { 1, -655.36006553599998, 174, 190}, 228 { 1, -262.14402621440001, 64, 81}, 229 { 1, -104.85761048576001, 21, 37}, 230 { 1, -41.943044194304001, 5, 20}, 231 { 1, -16.777217677721602, 0, 16}, 232 { 1, -6.7108870710886404, 0, 17}, 233 { 1, -2.6843548284354561, 0, 20}, 234 { 1, -1.0737419313741825, 0, 21}, 235 { 2.5, -1000000.1, 278450, 278466}, 236 { 2.5, -400000.03999999998, 111372, 111388}, 237 { 2.5, -160000.016, 44540, 44557}, 238 { 2.5, -64000.006399999998, 17808, 17824}, 239 { 2.5, -25600.002560000001, 7115, 7131}, 240 { 2.5, -10240.001024000001, 2838, 2854}, 241 { 2.5, -4096.0004096000002, 1127, 1144}, 242 { 2.5, -1638.40016384, 445, 461}, 243 { 2.5, -655.36006553599998, 172, 188}, 244 { 2.5, -262.14402621440001, 63, 79}, 245 { 2.5, -104.85761048576001, 20, 35}, 246 { 2.5, -41.943044194304001, 4, 19}, 247 { 2.5, -16.777217677721602, 0, 13}, 248 { 2.5, -6.7108870710886404, 0, 13}, 249 { 2.5, -2.6843548284354561, 0, 15}, 250 { 2.5, -1.0737419313741825, 2, 16}, 251 { 6.25, -1000000.1, 278440, 278456}, 252 { 6.25, -400000.03999999998, 111362, 111378}, 253 { 6.25, -160000.016, 44531, 44548}, 254 { 6.25, -64000.006399999998, 17800, 17816}, 255 { 6.25, -25600.002560000001, 7108, 7124}, 256 { 6.25, -10240.001024000001, 2831, 2848}, 257 { 6.25, -4096.0004096000002, 1121, 1138}, 258 { 6.25, -1638.40016384, 440, 456}, 259 { 6.25, -655.36006553599998, 167, 183}, 260 { 6.25, -262.14402621440001, 59, 75}, 261 { 6.25, -104.85761048576001, 18, 32}, 262 { 6.25, -41.943044194304001, 3, 16}, 263 { 6.25, -16.777217677721602, 0, 10}, 264 { 6.25, -6.7108870710886404, 0, 9}, 265 { 6.25, -2.6843548284354561, 0, 9}, 266 { 6.25, -1.0737419313741825, 4, 9}, 267 { 15.625, -1000000.1, 278415, 278432}, 268 { 15.625, -400000.03999999998, 111339, 111425}, 269 { 15.625, -160000.016, 44510, 44527}, 270 { 15.625, -64000.006399999998, 17781, 17797}, 271 { 15.625, -25600.002560000001, 7091, 7107}, 272 { 15.625, -10240.001024000001, 2816, 2833}, 273 { 15.625, -4096.0004096000002, 1108, 1125}, 274 { 15.625, -1638.40016384, 429, 445}, 275 { 15.625, -655.36006553599998, 159, 174}, 276 { 15.625, -262.14402621440001, 53, 67}, 277 { 15.625, -104.85761048576001, 14, 27}, 278 { 15.625, -41.943044194304001, 2, 11}, 279 { 15.625, -16.777217677721602, 0, 7}, 280 { 15.625, -6.7108870710886404, 0, 5}, 281 { 15.625, -2.6843548284354561, 5, 5}, 282 { 15.625, -1.0737419313741825, 5, 5}, 283 { 39.0625, -1000000.1, 278359, 431061}, 284 { 39.0625, -400000.03999999998, 111287, 111304}, 285 { 39.0625, -160000.016, 44463, 44480}, 286 { 39.0625, -64000.006399999998, 17738, 17755}, 287 { 39.0625, -25600.002560000001, 7053, 7069}, 288 { 39.0625, -10240.001024000001, 2784, 2800}, 289 { 39.0625, -4096.0004096000002, 1081, 1097}, 290 { 39.0625, -1638.40016384, 407, 422}, 291 { 39.0625, -655.36006553599998, 143, 157}, 292 { 39.0625, -262.14402621440001, 43, 56}, 293 { 39.0625, -104.85761048576001, 10, 19}, 294 { 39.0625, -41.943044194304001, 0, 7}, 295 { 39.0625, -16.777217677721602, 0, 4}, 296 { 39.0625, -6.7108870710886404, 0, 3}, 297 { 39.0625, -2.6843548284354561, 3, 3}, 298 { 39.0625, -1.0737419313741825, 3, 3}, 299 { 97.65625, -1000000.1, 278230, 278277}, 300 { 97.65625, -400000.03999999998, 111170, 111425}, 301 { 97.65625, -160000.016, 44358, 44374}, 302 { 97.65625, -64000.006399999998, 17645, 17661}, 303 { 97.65625, -25600.002560000001, 6972, 6988}, 304 { 97.65625, -10240.001024000001, 2715, 2731}, 305 { 97.65625, -4096.0004096000002, 1026, 1041}, 306 { 97.65625, -1638.40016384, 366, 380}, 307 { 97.65625, -655.36006553599998, 117, 129}, 308 { 97.65625, -262.14402621440001, 30, 40}, 309 { 97.65625, -104.85761048576001, 5, 12}, 310 { 97.65625, -41.943044194304001, 0, 4}, 311 { 97.65625, -16.777217677721602, 0, 3}, 312 { 97.65625, -6.7108870710886404, 0, 1}, 313 { 97.65625, -2.6843548284354561, 0, 1}, 314 { 97.65625, -1.0737419313741825, 0, 1}, 315 { 244.140625, -1000000.1, 277936, 796691}, 316 { 244.140625, -400000.03999999998, 110906, 110923}, 317 { 244.140625, -160000.016, 44124, 44141}, 318 { 244.140625, -64000.006399999998, 17442, 17458}, 319 { 244.140625, -25600.002560000001, 6801, 6816}, 320 { 244.140625, -10240.001024000001, 2577, 2593}, 321 { 244.140625, -4096.0004096000002, 924, 938}, 322 { 244.140625, -1638.40016384, 300, 312}, 323 { 244.140625, -655.36006553599998, 82, 92}, 324 { 244.140625, -262.14402621440001, 17, 24}, 325 { 244.140625, -104.85761048576001, 2, 7}, 326 { 244.140625, -41.943044194304001, 0, 3}, 327 { 244.140625, -16.777217677721602, 0, 1}, 328 { 244.140625, -6.7108870710886404, 0, 1}, 329 { 244.140625, -2.6843548284354561, 0, 1}, 330 { 244.140625, -1.0737419313741825, 0, 1}, 331 { 610.3515625, -1000000.1, 277277, 277294}, 332 { 610.3515625, -400000.03999999998, 110322, 111647}, 333 { 610.3515625, -160000.016, 43617, 43633}, 334 { 610.3515625, -64000.006399999998, 17014, 17030}, 335 { 610.3515625, -25600.002560000001, 6456, 6471}, 336 { 610.3515625, -10240.001024000001, 2321, 2335}, 337 { 610.3515625, -4096.0004096000002, 757, 769}, 338 { 610.3515625, -1638.40016384, 212, 221}, 339 { 610.3515625, -655.36006553599998, 48, 55}, 340 { 610.3515625, -262.14402621440001, 8, 13}, 341 { 610.3515625, -104.85761048576001, 0, 4}, 342 { 610.3515625, -41.943044194304001, 0, 1}, 343 { 610.3515625, -16.777217677721602, 0, 1}, 344 { 610.3515625, -6.7108870710886404, 0, 1}, 345 { 610.3515625, -2.6843548284354561, 0, 1}, 346 { 610.3515625, -1.0737419313741825, 0, 1}, 347 { 1525.87890625, -1000000.1, 275817, 431061}, 348 { 1525.87890625, -400000.03999999998, 109054, 109070}, 349 { 1525.87890625, -160000.016, 42546, 42562}, 350 { 1525.87890625, -64000.006399999998, 16151, 16167}, 351 { 1525.87890625, -25600.002560000001, 5814, 5828}, 352 { 1525.87890625, -10240.001024000001, 1902, 1914}, 353 { 1525.87890625, -4096.0004096000002, 535, 545}, 354 { 1525.87890625, -1638.40016384, 125, 131}, 355 { 1525.87890625, -655.36006553599998, 23, 28}, 356 { 1525.87890625, -262.14402621440001, 3, 7}, 357 { 1525.87890625, -104.85761048576001, 0, 1}, 358 { 1525.87890625, -41.943044194304001, 0, 1}, 359 { 1525.87890625, -16.777217677721602, 0, 1}, 360 { 1525.87890625, -6.7108870710886404, 0, 1}, 361 { 1525.87890625, -2.6843548284354561, 0, 1}, 362 { 1525.87890625, -1.0737419313741825, 0, 1}, 363 { 3814.697265625, -1000000.1, 272645, 272661}, 364 { 3814.697265625, -400000.03999999998, 106377, 106393}, 365 { 3814.697265625, -160000.016, 40390, 40406}, 366 { 3814.697265625, -64000.006399999998, 14545, 14560}, 367 { 3814.697265625, -25600.002560000001, 4765, 4777}, 368 { 3814.697265625, -10240.001024000001, 1346, 1356}, 369 { 3814.697265625, -4096.0004096000002, 316, 323}, 370 { 3814.697265625, -1638.40016384, 61, 66}, 371 { 3814.697265625, -655.36006553599998, 9, 13}, 372 { 3814.697265625, -262.14402621440001, 0, 4}, 373 { 3814.697265625, -104.85761048576001, 0, 1}, 374 { 3814.697265625, -41.943044194304001, 0, 1}, 375 { 3814.697265625, -16.777217677721602, 0, 1}, 376 { 3814.697265625, -6.7108870710886404, 0, 1}, 377 { 3814.697265625, -2.6843548284354561, 0, 1}, 378 { 3814.697265625, -1.0737419313741825, 0, 1}, 379 { 9536.7431640625, -1000000.1, 265953, 266155}, 380 { 9536.7431640625, -400000.03999999998, 100987, 101002}, 381 { 9536.7431640625, -160000.016, 36374, 36388}, 382 { 9536.7431640625, -64000.006399999998, 11921, 11934}, 383 { 9536.7431640625, -25600.002560000001, 3374, 3384}, 384 { 9536.7431640625, -10240.001024000001, 795, 802}, 385 { 9536.7431640625, -4096.0004096000002, 157, 162}, 386 { 9536.7431640625, -1638.40016384, 27, 30}, 387 { 9536.7431640625, -655.36006553599998, 3, 6}, 388 { 9536.7431640625, -262.14402621440001, 0, 1}, 389 { 9536.7431640625, -104.85761048576001, 0, 1}, 390 { 9536.7431640625, -41.943044194304001, 0, 1}, 391 { 9536.7431640625, -16.777217677721602, 0, 1}, 392 { 9536.7431640625, -6.7108870710886404, 0, 1}, 393 { 9536.7431640625, -2.6843548284354561, 0, 1}, 394 { 9536.7431640625, -1.0737419313741825, 0, 1}, 395 }; 396 static const unsigned total_elements = sizeof(domain) / sizeof(domain[0]); 397 static const unsigned stride = 16; 398 //static const unsigned a_elements = total_elements / stride; 399 BOOST_ASSERT(total_elements % stride == 0); 400 401 static const double a_max = domain[total_elements - 1][0]; 402 static const double a_min = domain[0][0]; 403 static const double b_max = domain[stride - 1][1]; 404 static const double b_min = domain[0][1]; 405 406 if (a < a_min) 407 return 0; // TODO: Use series? 408 if (b < b_min) 409 { 410 // 411 // This is a general heuristic that's more or less correct, 412 // but a bit too safe in most cases. Checked OK with 413 // random testing. 414 // 415 if (z > -b) 416 return 1; 417 if (a < 100) 418 return z < -b / (4 - 5 * (log(a)) * a / b) ? -1 : 0; 419 else 420 return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; 421 } 422 if (a > a_max) 423 { 424 // 425 // Crossover point is decreasing with increasing a 426 // upper limit is fine, lower limit is not: 427 // 428 if (b > b_max) 429 return 0; // TODO: don't know what else to do??? 430 unsigned index = total_elements - stride; 431 BOOST_ASSERT(domain[index][0] == a_max); 432 while (domain[index][1] < b) 433 ++index; 434 double b0 = domain[index - 1][1]; 435 double b1 = domain[index][1]; 436 double z0 = domain[index - 1][3]; 437 double z1 = domain[index][3]; 438 T upper_z_limit = static_cast<T>((z0 * (b1 - b) + z1 * (b - b0)) / (b1 - b0)); 439 if (z > upper_z_limit) 440 return 1; 441 return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; 442 443 } 444 if (b > b_max) 445 { 446 return 0; // TODO: is there a better way??? 447 } 448 // 449 // Bi-linear interpolation case: 450 // 451 unsigned index = 0; 452 while (domain[index][0] < a) 453 index += stride; 454 while (domain[index][1] < b) 455 ++index; 456 // 457 // We now have 4 corners: 458 // 459 double x1 = domain[index - stride - 1][0]; 460 double x2 = domain[index][0]; 461 double y1 = domain[index - 1][1]; 462 double y2 = domain[index][1]; 463 double f11 = domain[index - stride - 1][2]; 464 BOOST_ASSERT(domain[index - stride - 1][0] == x1); 465 BOOST_ASSERT(domain[index - stride - 1][1] == y1); 466 double f12 = domain[index - stride][2]; 467 BOOST_ASSERT(domain[index - stride][0] == x1); 468 BOOST_ASSERT(domain[index - stride][1] == y2); 469 double f21 = domain[index - 1][2]; 470 BOOST_ASSERT(domain[index - 1][0] == x2); 471 BOOST_ASSERT(domain[index - 1][1] == y1); 472 double f22 = domain[index][2]; 473 BOOST_ASSERT(domain[index][0] == x2); 474 BOOST_ASSERT(domain[index][1] == y2); 475 // 476 // Interpolation is a crude tool and our corners have quite tight bounds, 477 // and the "impossible region" is bounded by convex planes. For the upper 478 // bound this is fine - bilinear interpolation will be over-conservative 479 // but safe. For the lower limit though we may calculate that the "safe" 480 // zone is in an unsafe place. To work around this we move our coordinates 481 // closer to the lowest corner of our bounding box by an amount 482 // proportional to the distance from the nearest corner. This has the effect 483 // of making our lower bound smaller than it would otherwise be, and more so nearer 484 // the centre of the bounding box. 485 // 486 T effective_x = static_cast<T>(a + (std::min)(T(a - x1), T(x2 - a)) * 0.25); 487 T effective_y = static_cast<T>(b + (std::min)(T(b - y1), T(y2 - b)) * 0.25); 488 489 T lower_limit = static_cast<T>(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - effective_x) * (y2 - effective_y) + f21 * (effective_x - x1) * (y2 - effective_y) + f12 * (x2 - effective_x) * (effective_y - y1) + f22 * (effective_x - x1) * (effective_y - y1))); 490 491 // 492 // If one f value was zero, take the whole box as zero: 493 // 494 double min_f = (std::min)((std::min)(f11, f12), (std::min)(f21, f22)); 495 if (min_f == 0) 496 lower_limit = 0; 497 // 498 // Now we can test! 499 // 500 if (z < lower_limit) 501 return -1; 502 503 BOOST_ASSERT(f11 <= domain[index - stride - 1][3]); 504 f11 = domain[index - stride - 1][3]; 505 BOOST_ASSERT(f12 <= domain[index - stride][3]); 506 f12 = domain[index - stride][3]; 507 BOOST_ASSERT(f21 <= domain[index - 1][3]); 508 f21 = domain[index - 1][3]; 509 BOOST_ASSERT(f22 <= domain[index][3]); 510 f22 = domain[index][3]; 511 512 T upper_limit = static_cast<T>(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - a) * (y2 - b) + f21 * (a - x1) * (y2 - b) + f12 * (x2 - a) * (b - y1) + f22 * (a - x1) * (b - y1))); 513 if (z > upper_limit) 514 return 1; 515 return 0; 516 } 517 518 } } } 519 520 521 #endif // BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP 522