1 /* mpfr_ai -- Airy function Ai 2 3 Copyright 2010-2018 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramba projects, INRIA. 5 6 This file is part of the GNU MPFR Library. 7 8 The GNU MPFR Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU Lesser General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or (at your 11 option) any later version. 12 13 The GNU MPFR Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License for more details. 17 18 You should have received a copy of the GNU Lesser General Public License 19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23 #define MPFR_NEED_LONGLONG_H 24 #include "mpfr-impl.h" 25 26 /* Reminder and notations: 27 ----------------------- 28 29 Ai is the solution of: 30 / y'' - x*y = 0 31 { Ai(0) = 1/ ( 9^(1/3)*Gamma(2/3) ) 32 \ Ai'(0) = -1/ ( 3^(1/3)*Gamma(1/3) ) 33 34 Series development: 35 Ai(x) = sum (a_i*x^i) 36 = sum (t_i) 37 38 Recurrences: 39 a_(i+3) = a_i / ((i+2)*(i+3)) 40 t_(i+3) = t_i * x^3 / ((i+2)*(i+3)) 41 42 Values: 43 a_0 = Ai(0) ~ 0.355 44 a_1 = Ai'(0) ~ -0.259 45 */ 46 47 48 /* Airy function Ai evaluated by the most naive algorithm. 49 Assume that x is a finite number. */ 50 static int 51 mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) 52 { 53 MPFR_ZIV_DECL (loop); 54 MPFR_SAVE_EXPO_DECL (expo); 55 mpfr_prec_t wprec; /* working precision */ 56 mpfr_prec_t prec; /* target precision */ 57 mpfr_prec_t err; /* used to estimate the evaluation error */ 58 mpfr_prec_t correct_bits; /* estimates the number of correct bits*/ 59 unsigned long int k; 60 unsigned long int cond; /* condition number of the series */ 61 unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */ 62 int r; 63 mpfr_t s; /* used to store the partial sum */ 64 mpfr_t ti, tip1; /* used to store successive values of t_i */ 65 mpfr_t x3; /* used to store x^3 */ 66 mpfr_t tmp_sp, tmp2_sp; /* small precision variables */ 67 unsigned long int x3u; /* used to store ceil(x^3) */ 68 mpfr_t temp1, temp2; 69 int test1, test2; 70 71 /* Logging */ 72 MPFR_LOG_FUNC ( 73 ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd), 74 ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y) ); 75 76 /* Save current exponents range */ 77 MPFR_SAVE_EXPO_MARK (expo); 78 79 if (MPFR_UNLIKELY (MPFR_IS_ZERO (x))) 80 { 81 mpfr_t y1, y2; 82 prec = MPFR_ADD_PREC (MPFR_PREC (y), 3); 83 mpfr_init2 (y1, prec); 84 mpfr_init2 (y2, prec); 85 MPFR_ZIV_INIT (loop, prec); 86 87 /* ZIV loop */ 88 for (;;) 89 { 90 mpfr_gamma_one_and_two_third (y1, y2, prec); /* y2 = Gamma(2/3)(1 + delta1), |delta1| <= 2^{1-prec}. */ 91 92 r = mpfr_set_ui (y1, 9, MPFR_RNDN); 93 MPFR_ASSERTD (r == 0); 94 mpfr_cbrt (y1, y1, MPFR_RNDN); /* y1 = cbrt(9)(1 + delta2), |delta2| <= 2^{-prec}. */ 95 mpfr_mul (y1, y1, y2, MPFR_RNDN); 96 mpfr_ui_div (y1, 1, y1, MPFR_RNDN); 97 if (MPFR_LIKELY (MPFR_CAN_ROUND (y1, prec - 3, MPFR_PREC (y), rnd))) 98 break; 99 MPFR_ZIV_NEXT (loop, prec); 100 } 101 r = mpfr_set (y, y1, rnd); 102 MPFR_ZIV_FREE (loop); 103 MPFR_SAVE_EXPO_FREE (expo); 104 mpfr_clear (y1); 105 mpfr_clear (y2); 106 return mpfr_check_range (y, r, rnd); 107 } 108 109 /* FIXME: underflow for large values of |x| ? */ 110 111 112 /* Set initial precision */ 113 /* If we compute sum(i=0, N-1, t_i), the relative error is bounded by */ 114 /* 2*(4N)*2^(1-wprec)*C(|x|)/Ai(x) */ 115 /* where C(|x|) = 1 if 0<=x<=1 */ 116 /* and C(|x|) = (1/2)*x^(-1/4)*exp(2/3 x^(3/2)) if x >= 1 */ 117 118 /* A priori, we do not know N, so we estimate it to ~ prec */ 119 /* If 0<=x<=1, we estimate Ai(x) ~ 1/8 */ 120 /* if 1<=x, we estimate Ai(x) ~ (1/4)*x^(-1/4)*exp(-2/3 * x^(3/2)) */ 121 /* if x<=0, ????? */ 122 123 /* We begin with 11 guard bits */ 124 prec = MPFR_ADD_PREC (MPFR_PREC (y), 11); 125 MPFR_ZIV_INIT (loop, prec); 126 127 /* The working precision is heuristically chosen in order to obtain */ 128 /* approximately prec correct bits in the sum. To sum up: the sum */ 129 /* is stopped when the *exact* sum gives ~ prec correct bit. And */ 130 /* when it is stopped, the accuracy of the computed sum, with respect*/ 131 /* to the exact one should be ~prec bits. */ 132 mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION); 133 mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION); 134 mpfr_abs (tmp_sp, x, MPFR_RNDU); 135 mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU); 136 mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */ 137 138 /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */ 139 mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU); 140 mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU); 141 142 /* cond represents the number of lost bits in the evaluation of the sum */ 143 if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) ) 144 cond = 0; 145 else 146 cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x)-1)/4 - 1; 147 148 /* The variable assumed_exponent is used to store the maximal assumed */ 149 /* exponent of Ai(x). More precisely, we assume that |Ai(x)| will be */ 150 /* greater than 2^{-assumed_exponent}. */ 151 if (MPFR_IS_ZERO (x)) 152 assumed_exponent = 2; 153 else 154 { 155 if (MPFR_IS_POS (x)) 156 { 157 if (MPFR_GET_EXP (x) <= 0) 158 assumed_exponent = 3; 159 else 160 assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1) 161 + mpfr_get_ui (tmp2_sp, MPFR_RNDU)); 162 } 163 /* We do not know Ai (x) yet */ 164 /* We cover the case when EXP (Ai (x))>=-10 */ 165 else 166 assumed_exponent = 10; 167 } 168 169 { 170 mpfr_prec_t incr = 171 MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent; 172 wprec = MPFR_ADD_PREC (prec, incr); 173 } 174 175 mpfr_init (ti); 176 mpfr_init (tip1); 177 mpfr_init (temp1); 178 mpfr_init (temp2); 179 mpfr_init (x3); 180 mpfr_init (s); 181 182 /* ZIV loop */ 183 for (;;) 184 { 185 MPFR_LOG_MSG (("Working precision: %Pu\n", wprec)); 186 mpfr_set_prec (ti, wprec); 187 mpfr_set_prec (tip1, wprec); 188 mpfr_set_prec (x3, wprec); 189 mpfr_set_prec (s, wprec); 190 191 mpfr_sqr (x3, x, MPFR_RNDU); 192 mpfr_mul (x3, x3, x, (MPFR_IS_POS (x)?MPFR_RNDU:MPFR_RNDD)); /* x3=x^3 */ 193 if (MPFR_IS_NEG (x)) 194 MPFR_CHANGE_SIGN (x3); 195 x3u = mpfr_get_ui (x3, MPFR_RNDU); /* x3u >= ceil(x^3) */ 196 if (MPFR_IS_NEG (x)) 197 MPFR_CHANGE_SIGN (x3); 198 199 mpfr_gamma_one_and_two_third (temp1, temp2, wprec); 200 mpfr_set_ui (ti, 9, MPFR_RNDN); 201 mpfr_cbrt (ti, ti, MPFR_RNDN); 202 mpfr_mul (ti, ti, temp2, MPFR_RNDN); 203 mpfr_ui_div (ti, 1, ti , MPFR_RNDN); /* ti = 1/( Gamma (2/3)*9^(1/3) ) */ 204 205 mpfr_set_ui (tip1, 3, MPFR_RNDN); 206 mpfr_cbrt (tip1, tip1, MPFR_RNDN); 207 mpfr_mul (tip1, tip1, temp1, MPFR_RNDN); 208 mpfr_neg (tip1, tip1, MPFR_RNDN); 209 mpfr_div (tip1, x, tip1, MPFR_RNDN); /* tip1 = -x/(Gamma (1/3)*3^(1/3)) */ 210 211 mpfr_add (s, ti, tip1, MPFR_RNDN); 212 213 214 /* Evaluation of the series */ 215 k = 2; 216 for (;;) 217 { 218 mpfr_mul (ti, ti, x3, MPFR_RNDN); 219 mpfr_mul (tip1, tip1, x3, MPFR_RNDN); 220 221 mpfr_div_ui2 (ti, ti, k, (k+1), MPFR_RNDN); 222 mpfr_div_ui2 (tip1, tip1, (k+1), (k+2), MPFR_RNDN); 223 224 k += 3; 225 mpfr_add (s, s, ti, MPFR_RNDN); 226 mpfr_add (s, s, tip1, MPFR_RNDN); 227 228 /* FIXME: if s==0 */ 229 test1 = MPFR_IS_ZERO (ti) 230 || (MPFR_GET_EXP (ti) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s)); 231 test2 = MPFR_IS_ZERO (tip1) 232 || (MPFR_GET_EXP (tip1) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s)); 233 234 if ( test1 && test2 && (x3u <= k*(k+1)/2) ) 235 break; /* FIXME: if k*(k+1) overflows */ 236 } 237 238 MPFR_LOG_MSG (("Truncation rank: %lu\n", k)); 239 240 err = 4 + MPFR_INT_CEIL_LOG2 (k) + cond - MPFR_GET_EXP (s); 241 242 /* err is the number of bits lost due to the evaluation error */ 243 /* wprec-(prec+1): number of bits lost due to the approximation error */ 244 MPFR_LOG_MSG (("Roundoff error: %Pu\n", err)); 245 MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec-prec-1)); 246 247 if (wprec < err+1) 248 correct_bits=0; 249 else 250 { 251 if (wprec < err+prec+1) 252 correct_bits = wprec - err - 1; 253 else 254 correct_bits = prec; 255 } 256 257 if (MPFR_LIKELY (MPFR_CAN_ROUND (s, correct_bits, MPFR_PREC (y), rnd))) 258 break; 259 260 if (correct_bits == 0) 261 { 262 assumed_exponent *= 2; 263 MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n", 264 assumed_exponent)); 265 wprec = prec + 5 + MPFR_INT_CEIL_LOG2 (k) + cond + assumed_exponent; 266 } 267 else 268 { 269 if (correct_bits < prec) 270 { /* The precision was badly chosen */ 271 MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)" 272 " (E=%" MPFR_EXP_FSPEC "d)\n", 273 (mpfr_eexp_t) MPFR_GET_EXP (s))); 274 wprec = prec + err + 1; 275 } 276 else 277 { /* We are really in a bad case of the TMD */ 278 MPFR_ZIV_NEXT (loop, prec); 279 280 /* We update wprec */ 281 /* We assume that K will not be multiplied by more than 4 */ 282 wprec = prec + (MPFR_INT_CEIL_LOG2 (k)+2) + 5 + cond 283 - MPFR_GET_EXP (s); 284 } 285 } 286 287 } /* End of ZIV loop */ 288 289 MPFR_ZIV_FREE (loop); 290 291 r = mpfr_set (y, s, rnd); 292 293 mpfr_clear (ti); 294 mpfr_clear (tip1); 295 mpfr_clear (temp1); 296 mpfr_clear (temp2); 297 mpfr_clear (x3); 298 mpfr_clear (s); 299 mpfr_clear (tmp_sp); 300 mpfr_clear (tmp2_sp); 301 302 MPFR_SAVE_EXPO_FREE (expo); 303 return mpfr_check_range (y, r, rnd); 304 } 305 306 307 /* Airy function Ai evaluated by Smith algorithm. 308 Assume that x is a finite number. */ 309 static int 310 mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) 311 { 312 MPFR_ZIV_DECL (loop); 313 MPFR_SAVE_EXPO_DECL (expo); 314 mpfr_prec_t wprec; /* working precision */ 315 mpfr_prec_t prec; /* target precision */ 316 mpfr_prec_t err; /* used to estimate the evaluation error */ 317 mpfr_prec_t correctBits; /* estimates the number of correct bits*/ 318 unsigned long int i, j, L, t; 319 unsigned long int cond; /* condition number of the series */ 320 unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */ 321 int r; /* returned ternary value */ 322 mpfr_t s; /* used to store the partial sum */ 323 mpfr_t u0, u1; 324 mpfr_t *z; /* used to store the (x^3j) */ 325 mpfr_t result; 326 mpfr_t tmp_sp, tmp2_sp; /* small precision variables */ 327 unsigned long int x3u; /* used to store ceil (x^3) */ 328 mpfr_t temp1, temp2; 329 int test0, test1; 330 331 /* Logging */ 332 MPFR_LOG_FUNC ( 333 ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd), 334 ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y)); 335 336 /* Save current exponents range */ 337 MPFR_SAVE_EXPO_MARK (expo); 338 339 /* FIXME: underflow for large values of |x| */ 340 341 342 /* Set initial precision */ 343 /* See the analysis for the naive evaluation */ 344 345 /* We begin with 11 guard bits */ 346 prec = MPFR_PREC (y) + 11; 347 MPFR_ZIV_INIT (loop, prec); 348 349 mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION); 350 mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION); 351 mpfr_abs (tmp_sp, x, MPFR_RNDU); 352 mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU); 353 mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */ 354 355 /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */ 356 mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU); 357 mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU); 358 359 /* cond represents the number of lost bits in the evaluation of the sum */ 360 if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) ) 361 cond = 0; 362 else 363 cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x) - 1)/4 - 1; 364 365 /* This variable is used to store the maximal assumed exponent of */ 366 /* Ai (x). More precisely, we assume that |Ai (x)| will be greater than */ 367 /* 2^{-assumedExp}. */ 368 if (MPFR_IS_ZERO (x)) 369 assumed_exponent = 2; 370 else 371 { 372 if (MPFR_IS_POS (x)) 373 { 374 if (MPFR_GET_EXP (x) <= 0) 375 assumed_exponent = 3; 376 else 377 assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1) 378 + mpfr_get_ui (tmp2_sp, MPFR_RNDU)); 379 } 380 /* We do not know Ai (x) yet */ 381 /* We cover the case when EXP (Ai (x))>=-10 */ 382 else 383 assumed_exponent = 10; 384 } 385 386 wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 6 + cond + assumed_exponent; 387 388 /* We assume that the truncation rank will be ~ prec */ 389 L = __gmpfr_isqrt (prec); 390 MPFR_LOG_MSG (("size of blocks L = %lu\n", L)); 391 392 z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t) ); 393 MPFR_ASSERTN (z != NULL); 394 for (j=0; j<=L; j++) 395 mpfr_init (z[j]); 396 397 mpfr_init (s); 398 mpfr_init (u0); mpfr_init (u1); 399 mpfr_init (result); 400 mpfr_init (temp1); 401 mpfr_init (temp2); 402 403 /* ZIV loop */ 404 for (;;) 405 { 406 MPFR_LOG_MSG (("working precision: %Pu\n", wprec)); 407 408 for (j=0; j<=L; j++) 409 mpfr_set_prec (z[j], wprec); 410 mpfr_set_prec (s, wprec); 411 mpfr_set_prec (u0, wprec); mpfr_set_prec (u1, wprec); 412 mpfr_set_prec (result, wprec); 413 414 mpfr_set_ui (u0, 1, MPFR_RNDN); 415 mpfr_set (u1, x, MPFR_RNDN); 416 417 mpfr_set_ui (z[0], 1, MPFR_RNDU); 418 mpfr_sqr (z[1], u1, MPFR_RNDU); 419 mpfr_mul (z[1], z[1], x, (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD) ); 420 421 if (MPFR_IS_NEG (x)) 422 MPFR_CHANGE_SIGN (z[1]); 423 x3u = mpfr_get_ui (z[1], MPFR_RNDU); /* x3u >= ceil (x^3) */ 424 if (MPFR_IS_NEG (x)) 425 MPFR_CHANGE_SIGN (z[1]); 426 427 for (j=2; j<=L ;j++) 428 { 429 if (j%2 == 0) 430 mpfr_sqr (z[j], z[j/2], MPFR_RNDN); 431 else 432 mpfr_mul (z[j], z[j-1], z[1], MPFR_RNDN); 433 } 434 435 mpfr_gamma_one_and_two_third (temp1, temp2, wprec); 436 mpfr_set_ui (u0, 9, MPFR_RNDN); 437 mpfr_cbrt (u0, u0, MPFR_RNDN); 438 mpfr_mul (u0, u0, temp2, MPFR_RNDN); 439 mpfr_ui_div (u0, 1, u0 , MPFR_RNDN); /* u0 = 1/( Gamma (2/3)*9^(1/3) ) */ 440 441 mpfr_set_ui (u1, 3, MPFR_RNDN); 442 mpfr_cbrt (u1, u1, MPFR_RNDN); 443 mpfr_mul (u1, u1, temp1, MPFR_RNDN); 444 mpfr_neg (u1, u1, MPFR_RNDN); 445 mpfr_div (u1, x, u1, MPFR_RNDN); /* u1 = -x/(Gamma (1/3)*3^(1/3)) */ 446 447 mpfr_set_ui (result, 0, MPFR_RNDN); 448 t = 0; 449 450 /* Evaluation of the series by Smith' method */ 451 for (i=0; ; i++) 452 { 453 t += 3 * L; 454 455 /* k = 0 */ 456 t -= 3; 457 mpfr_set (s, z[L-1], MPFR_RNDN); 458 for (j=L-2; ; j--) 459 { 460 t -= 3; 461 mpfr_div_ui2 (s, s, (t+2), (t+3), MPFR_RNDN); 462 mpfr_add (s, s, z[j], MPFR_RNDN); 463 if (j==0) 464 break; 465 } 466 mpfr_mul (s, s, u0, MPFR_RNDN); 467 mpfr_add (result, result, s, MPFR_RNDN); 468 469 mpfr_mul (u0, u0, z[L], MPFR_RNDN); 470 for (j=0; j<=L-1; j++) 471 { 472 mpfr_div_ui2 (u0, u0, (t + 2), (t + 3), MPFR_RNDN); 473 t += 3; 474 } 475 476 t++; 477 478 /* k = 1 */ 479 t -= 3; 480 mpfr_set (s, z[L-1], MPFR_RNDN); 481 for (j=L-2; ; j--) 482 { 483 t -= 3; 484 mpfr_div_ui2 (s, s, (t + 2), (t + 3), MPFR_RNDN); 485 mpfr_add (s, s, z[j], MPFR_RNDN); 486 if (j==0) 487 break; 488 } 489 mpfr_mul (s, s, u1, MPFR_RNDN); 490 mpfr_add (result, result, s, MPFR_RNDN); 491 492 mpfr_mul (u1, u1, z[L], MPFR_RNDN); 493 for (j=0; j<=L-1; j++) 494 { 495 mpfr_div_ui2 (u1, u1, (t + 2), (t + 3), MPFR_RNDN); 496 t += 3; 497 } 498 499 t++; 500 501 /* k = 2 */ 502 t++; 503 504 /* End of the loop over k */ 505 t -= 3; 506 507 test0 = MPFR_IS_ZERO (u0) || 508 MPFR_GET_EXP (u0) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result); 509 test1 = MPFR_IS_ZERO (u1) || 510 MPFR_GET_EXP (u1) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result); 511 512 if ( test0 && test1 && (x3u <= (t + 2) * (t + 3) / 2) ) 513 break; 514 } 515 516 MPFR_LOG_MSG (("Truncation rank: %lu\n", t)); 517 518 err = (5 + MPFR_INT_CEIL_LOG2 (L+1) + MPFR_INT_CEIL_LOG2 (i+1) 519 + cond - MPFR_GET_EXP (result)); 520 521 /* err is the number of bits lost due to the evaluation error */ 522 /* wprec-(prec+1): number of bits lost due to the approximation error */ 523 MPFR_LOG_MSG (("Roundoff error: %Pu\n", err)); 524 MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec - prec - 1)); 525 526 if (wprec < err+1) 527 correctBits = 0; 528 else 529 { 530 if (wprec < err+prec+1) 531 correctBits = wprec - err - 1; 532 else 533 correctBits = prec; 534 } 535 536 if (MPFR_LIKELY (MPFR_CAN_ROUND (result, correctBits, 537 MPFR_PREC (y), rnd))) 538 break; 539 540 for (j=0; j<=L; j++) 541 mpfr_clear (z[j]); 542 mpfr_free_func (z, (L + 1) * sizeof (mpfr_t)); 543 L = __gmpfr_isqrt (t); 544 MPFR_LOG_MSG (("size of blocks L = %lu\n", L)); 545 z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t)); 546 MPFR_ASSERTN (z != NULL); 547 for (j=0; j<=L; j++) 548 mpfr_init (z[j]); 549 550 if (correctBits == 0) 551 { 552 assumed_exponent *= 2; 553 MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n", 554 assumed_exponent)); 555 wprec = prec + 6 + MPFR_INT_CEIL_LOG2 (t) + cond + assumed_exponent; 556 } 557 else 558 { 559 if (correctBits < prec) 560 { /* The precision was badly chosen */ 561 MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)" 562 " (E=%" MPFR_EXP_FSPEC "d)\n", 563 (mpfr_eexp_t) MPFR_GET_EXP (result))); 564 wprec = prec + err + 1; 565 } 566 else 567 { /* We are really in a bad case of the TMD */ 568 MPFR_ZIV_NEXT (loop, prec); 569 570 /* We update wprec */ 571 /* We assume that t will not be multiplied by more than 4 */ 572 wprec = (prec + (MPFR_INT_CEIL_LOG2 (t) + 2) + 6 + cond 573 - MPFR_GET_EXP (result)); 574 } 575 } 576 } /* End of ZIV loop */ 577 578 MPFR_ZIV_FREE (loop); 579 580 r = mpfr_set (y, result, rnd); 581 582 mpfr_clear (tmp_sp); 583 mpfr_clear (tmp2_sp); 584 for (j=0; j<=L; j++) 585 mpfr_clear (z[j]); 586 mpfr_free_func (z, (L + 1) * sizeof (mpfr_t)); 587 588 mpfr_clear (s); 589 mpfr_clear (u0); mpfr_clear (u1); 590 mpfr_clear (result); 591 mpfr_clear (temp1); 592 mpfr_clear (temp2); 593 594 MPFR_SAVE_EXPO_FREE (expo); 595 return mpfr_check_range (y, r, rnd); 596 } 597 598 /* We consider that the boundary between the area where the naive method 599 should preferably be used and the area where Smith' method should preferably 600 be used has the following form: 601 it is a triangle defined by two lines (one for the negative values of x, and 602 one for the positive values of x) crossing at x=0. 603 604 More precisely, 605 606 * If x<0 and MPFR_AI_THRESHOLD1*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE, 607 use Smith' algorithm; 608 * If x>0 and MPFR_AI_THRESHOLD3*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE, 609 use Smith' algorithm; 610 * otherwise, use the naive method. 611 */ 612 613 #define MPFR_AI_SCALE 1048576 614 615 int 616 mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd) 617 { 618 mpfr_t temp1, temp2; 619 int use_ai2; 620 MPFR_SAVE_EXPO_DECL (expo); 621 622 /* Special cases */ 623 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x))) 624 { 625 if (MPFR_IS_NAN (x)) 626 { 627 MPFR_SET_NAN (y); 628 MPFR_RET_NAN; 629 } 630 else if (MPFR_IS_INF (x)) 631 return mpfr_set_ui (y, 0, rnd); 632 } 633 634 /* The exponent range must be large enough for the computation of temp1. */ 635 MPFR_SAVE_EXPO_MARK (expo); 636 637 mpfr_init2 (temp1, MPFR_SMALL_PRECISION); 638 mpfr_init2 (temp2, MPFR_SMALL_PRECISION); 639 640 mpfr_set (temp1, x, MPFR_RNDN); 641 mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN); 642 mpfr_mul_ui (temp2, temp2, MPFR_PREC (y) > ULONG_MAX ? 643 ULONG_MAX : (unsigned long) MPFR_PREC (y), MPFR_RNDN); 644 645 if (MPFR_IS_NEG (x)) 646 mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN); 647 else 648 mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN); 649 650 mpfr_add (temp1, temp1, temp2, MPFR_RNDN); 651 mpfr_clear (temp2); 652 653 use_ai2 = mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0; 654 mpfr_clear (temp1); 655 656 MPFR_SAVE_EXPO_FREE (expo); /* Ignore all previous exceptions. */ 657 658 return use_ai2 ? mpfr_ai2 (y, x, rnd) : mpfr_ai1 (y, x, rnd); 659 } 660