beta-0.89.2
[luatex.git] / source / libs / mpfr / mpfr-3.1.3 / src / ai.c
blobcbab7cfcbe0997a7904db63d88b86263754fe154
1 /* mpfr_ai -- Airy function Ai
3 Copyright 2010-2015 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
6 This file is part of the GNU MPFR Library.
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.
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.
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. */
23 #define MPFR_NEED_LONGLONG_H
24 #include "mpfr-impl.h"
26 /* Reminder and notations:
27 -----------------------
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) )
34 Series development:
35 Ai(x) = sum (a_i*x^i)
36 = sum (t_i)
38 Recurrences:
39 a_(i+3) = a_i / ((i+2)*(i+3))
40 t_(i+3) = t_i * x^3 / ((i+2)*(i+3))
42 Values:
43 a_0 = Ai(0) ~ 0.355
44 a_1 = Ai'(0) ~ -0.259
48 /* Airy function Ai evaluated by the most naive algorithm */
49 static int
50 mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
52 MPFR_ZIV_DECL (loop);
53 MPFR_SAVE_EXPO_DECL (expo);
54 mpfr_prec_t wprec; /* working precision */
55 mpfr_prec_t prec; /* target precision */
56 mpfr_prec_t err; /* used to estimate the evaluation error */
57 mpfr_prec_t correct_bits; /* estimates the number of correct bits*/
58 unsigned long int k;
59 unsigned long int cond; /* condition number of the series */
60 unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */
61 int r;
62 mpfr_t s; /* used to store the partial sum */
63 mpfr_t ti, tip1; /* used to store successive values of t_i */
64 mpfr_t x3; /* used to store x^3 */
65 mpfr_t tmp_sp, tmp2_sp; /* small precision variables */
66 unsigned long int x3u; /* used to store ceil(x^3) */
67 mpfr_t temp1, temp2;
68 int test1, test2;
70 /* Logging */
71 MPFR_LOG_FUNC (
72 ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
73 ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y) );
75 /* Special cases */
76 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
78 if (MPFR_IS_NAN (x))
80 MPFR_SET_NAN (y);
81 MPFR_RET_NAN;
83 else if (MPFR_IS_INF (x))
84 return mpfr_set_ui (y, 0, rnd);
88 /* Save current exponents range */
89 MPFR_SAVE_EXPO_MARK (expo);
91 if (MPFR_UNLIKELY (MPFR_IS_ZERO (x)))
93 mpfr_t y1, y2;
94 prec = MPFR_PREC (y) + 3;
95 mpfr_init2 (y1, prec);
96 mpfr_init2 (y2, prec);
97 MPFR_ZIV_INIT (loop, prec);
99 /* ZIV loop */
100 for (;;)
102 mpfr_gamma_one_and_two_third (y1, y2, prec); /* y2 = Gamma(2/3)(1 + delta1), |delta1| <= 2^{1-prec}. */
104 r = mpfr_set_ui (y1, 9, MPFR_RNDN);
105 MPFR_ASSERTD (r == 0);
106 mpfr_cbrt (y1, y1, MPFR_RNDN); /* y1 = cbrt(9)(1 + delta2), |delta2| <= 2^{-prec}. */
107 mpfr_mul (y1, y1, y2, MPFR_RNDN);
108 mpfr_ui_div (y1, 1, y1, MPFR_RNDN);
109 if (MPFR_LIKELY (MPFR_CAN_ROUND (y1, prec - 3, MPFR_PREC (y), rnd)))
110 break;
111 MPFR_ZIV_NEXT (loop, prec);
113 r = mpfr_set (y, y1, rnd);
114 MPFR_ZIV_FREE (loop);
115 MPFR_SAVE_EXPO_FREE (expo);
116 mpfr_clear (y1);
117 mpfr_clear (y2);
118 return mpfr_check_range (y, r, rnd);
121 /* FIXME: underflow for large values of |x| ? */
124 /* Set initial precision */
125 /* If we compute sum(i=0, N-1, t_i), the relative error is bounded by */
126 /* 2*(4N)*2^(1-wprec)*C(|x|)/Ai(x) */
127 /* where C(|x|) = 1 if 0<=x<=1 */
128 /* and C(|x|) = (1/2)*x^(-1/4)*exp(2/3 x^(3/2)) if x >= 1 */
130 /* A priori, we do not know N, so we estimate it to ~ prec */
131 /* If 0<=x<=1, we estimate Ai(x) ~ 1/8 */
132 /* if 1<=x, we estimate Ai(x) ~ (1/4)*x^(-1/4)*exp(-2/3 * x^(3/2)) */
133 /* if x<=0, ????? */
135 /* We begin with 11 guard bits */
136 prec = MPFR_PREC (y)+11;
137 MPFR_ZIV_INIT (loop, prec);
139 /* The working precision is heuristically chosen in order to obtain */
140 /* approximately prec correct bits in the sum. To sum up: the sum */
141 /* is stopped when the *exact* sum gives ~ prec correct bit. And */
142 /* when it is stopped, the accuracy of the computed sum, with respect*/
143 /* to the exact one should be ~prec bits. */
144 mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
145 mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
146 mpfr_abs (tmp_sp, x, MPFR_RNDU);
147 mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
148 mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */
150 /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
151 mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
152 mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
154 /* cond represents the number of lost bits in the evaluation of the sum */
155 if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) )
156 cond = 0;
157 else
158 cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x)-1)/4 - 1;
160 /* The variable assumed_exponent is used to store the maximal assumed */
161 /* exponent of Ai(x). More precisely, we assume that |Ai(x)| will be */
162 /* greater than 2^{-assumed_exponent}. */
163 if (MPFR_IS_ZERO (x))
164 assumed_exponent = 2;
165 else
167 if (MPFR_IS_POS (x))
169 if (MPFR_GET_EXP (x) <= 0)
170 assumed_exponent = 3;
171 else
172 assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1)
173 + mpfr_get_ui (tmp2_sp, MPFR_RNDU));
175 /* We do not know Ai (x) yet */
176 /* We cover the case when EXP (Ai (x))>=-10 */
177 else
178 assumed_exponent = 10;
181 wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent;
183 mpfr_init (ti);
184 mpfr_init (tip1);
185 mpfr_init (temp1);
186 mpfr_init (temp2);
187 mpfr_init (x3);
188 mpfr_init (s);
190 /* ZIV loop */
191 for (;;)
193 MPFR_LOG_MSG (("Working precision: %Pu\n", wprec));
194 mpfr_set_prec (ti, wprec);
195 mpfr_set_prec (tip1, wprec);
196 mpfr_set_prec (x3, wprec);
197 mpfr_set_prec (s, wprec);
199 mpfr_sqr (x3, x, MPFR_RNDU);
200 mpfr_mul (x3, x3, x, (MPFR_IS_POS (x)?MPFR_RNDU:MPFR_RNDD)); /* x3=x^3 */
201 if (MPFR_IS_NEG (x))
202 MPFR_CHANGE_SIGN (x3);
203 x3u = mpfr_get_ui (x3, MPFR_RNDU); /* x3u >= ceil(x^3) */
204 if (MPFR_IS_NEG (x))
205 MPFR_CHANGE_SIGN (x3);
207 mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
208 mpfr_set_ui (ti, 9, MPFR_RNDN);
209 mpfr_cbrt (ti, ti, MPFR_RNDN);
210 mpfr_mul (ti, ti, temp2, MPFR_RNDN);
211 mpfr_ui_div (ti, 1, ti , MPFR_RNDN); /* ti = 1/( Gamma (2/3)*9^(1/3) ) */
213 mpfr_set_ui (tip1, 3, MPFR_RNDN);
214 mpfr_cbrt (tip1, tip1, MPFR_RNDN);
215 mpfr_mul (tip1, tip1, temp1, MPFR_RNDN);
216 mpfr_neg (tip1, tip1, MPFR_RNDN);
217 mpfr_div (tip1, x, tip1, MPFR_RNDN); /* tip1 = -x/(Gamma (1/3)*3^(1/3)) */
219 mpfr_add (s, ti, tip1, MPFR_RNDN);
222 /* Evaluation of the series */
223 k = 2;
224 for (;;)
226 mpfr_mul (ti, ti, x3, MPFR_RNDN);
227 mpfr_mul (tip1, tip1, x3, MPFR_RNDN);
229 mpfr_div_ui2 (ti, ti, k, (k+1), MPFR_RNDN);
230 mpfr_div_ui2 (tip1, tip1, (k+1), (k+2), MPFR_RNDN);
232 k += 3;
233 mpfr_add (s, s, ti, MPFR_RNDN);
234 mpfr_add (s, s, tip1, MPFR_RNDN);
236 /* FIXME: if s==0 */
237 test1 = MPFR_IS_ZERO (ti)
238 || (MPFR_GET_EXP (ti) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
239 test2 = MPFR_IS_ZERO (tip1)
240 || (MPFR_GET_EXP (tip1) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
242 if ( test1 && test2 && (x3u <= k*(k+1)/2) )
243 break; /* FIXME: if k*(k+1) overflows */
246 MPFR_LOG_MSG (("Truncation rank: %lu\n", k));
248 err = 4 + MPFR_INT_CEIL_LOG2 (k) + cond - MPFR_GET_EXP (s);
250 /* err is the number of bits lost due to the evaluation error */
251 /* wprec-(prec+1): number of bits lost due to the approximation error */
252 MPFR_LOG_MSG (("Roundoff error: %Pu\n", err));
253 MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec-prec-1));
255 if (wprec < err+1)
256 correct_bits=0;
257 else
259 if (wprec < err+prec+1)
260 correct_bits = wprec - err - 1;
261 else
262 correct_bits = prec;
265 if (MPFR_LIKELY (MPFR_CAN_ROUND (s, correct_bits, MPFR_PREC (y), rnd)))
266 break;
268 if (correct_bits == 0)
270 assumed_exponent *= 2;
271 MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
272 assumed_exponent));
273 wprec = prec + 5 + MPFR_INT_CEIL_LOG2 (k) + cond + assumed_exponent;
275 else
277 if (correct_bits < prec)
278 { /* The precision was badly chosen */
279 MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)", 0));
280 MPFR_LOG_MSG ((" (E=%ld)\n", (long) MPFR_GET_EXP (s)));
281 wprec = prec + err + 1;
283 else
284 { /* We are really in a bad case of the TMD */
285 MPFR_ZIV_NEXT (loop, prec);
287 /* We update wprec */
288 /* We assume that K will not be multiplied by more than 4 */
289 wprec = prec + (MPFR_INT_CEIL_LOG2 (k)+2) + 5 + cond
290 - MPFR_GET_EXP (s);
294 } /* End of ZIV loop */
296 MPFR_ZIV_FREE (loop);
298 r = mpfr_set (y, s, rnd);
300 mpfr_clear (ti);
301 mpfr_clear (tip1);
302 mpfr_clear (temp1);
303 mpfr_clear (temp2);
304 mpfr_clear (x3);
305 mpfr_clear (s);
306 mpfr_clear (tmp_sp);
307 mpfr_clear (tmp2_sp);
309 MPFR_SAVE_EXPO_FREE (expo);
310 return mpfr_check_range (y, r, rnd);
314 /* Airy function Ai evaluated by Smith algorithm */
315 static int
316 mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
318 MPFR_ZIV_DECL (loop);
319 MPFR_SAVE_EXPO_DECL (expo);
320 mpfr_prec_t wprec; /* working precision */
321 mpfr_prec_t prec; /* target precision */
322 mpfr_prec_t err; /* used to estimate the evaluation error */
323 mpfr_prec_t correctBits; /* estimates the number of correct bits*/
324 unsigned long int i, j, L, t;
325 unsigned long int cond; /* condition number of the series */
326 unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */
327 int r; /* returned ternary value */
328 mpfr_t s; /* used to store the partial sum */
329 mpfr_t u0, u1;
330 mpfr_t *z; /* used to store the (x^3j) */
331 mpfr_t result;
332 mpfr_t tmp_sp, tmp2_sp; /* small precision variables */
333 unsigned long int x3u; /* used to store ceil (x^3) */
334 mpfr_t temp1, temp2;
335 int test0, test1;
337 /* Logging */
338 MPFR_LOG_FUNC (
339 ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
340 ("y[%Pu]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
342 /* Special cases */
343 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
345 if (MPFR_IS_NAN (x))
347 MPFR_SET_NAN (y);
348 MPFR_RET_NAN;
350 else if (MPFR_IS_INF (x))
351 return mpfr_set_ui (y, 0, rnd);
354 /* Save current exponents range */
355 MPFR_SAVE_EXPO_MARK (expo);
357 /* FIXME: underflow for large values of |x| */
360 /* Set initial precision */
361 /* See the analysis for the naive evaluation */
363 /* We begin with 11 guard bits */
364 prec = MPFR_PREC (y) + 11;
365 MPFR_ZIV_INIT (loop, prec);
367 mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
368 mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
369 mpfr_abs (tmp_sp, x, MPFR_RNDU);
370 mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
371 mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ x^3/2 */
373 /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
374 mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
375 mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
377 /* cond represents the number of lost bits in the evaluation of the sum */
378 if ( (MPFR_IS_ZERO (x)) || (MPFR_GET_EXP (x) <= 0) )
379 cond = 0;
380 else
381 cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU) - (MPFR_GET_EXP (x) - 1)/4 - 1;
383 /* This variable is used to store the maximal assumed exponent of */
384 /* Ai (x). More precisely, we assume that |Ai (x)| will be greater than */
385 /* 2^{-assumedExp}. */
386 if (MPFR_IS_ZERO (x))
387 assumed_exponent = 2;
388 else
390 if (MPFR_IS_POS (x))
392 if (MPFR_GET_EXP (x) <= 0)
393 assumed_exponent = 3;
394 else
395 assumed_exponent = (2 + (MPFR_GET_EXP (x)/4 + 1)
396 + mpfr_get_ui (tmp2_sp, MPFR_RNDU));
398 /* We do not know Ai (x) yet */
399 /* We cover the case when EXP (Ai (x))>=-10 */
400 else
401 assumed_exponent = 10;
404 wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 6 + cond + assumed_exponent;
406 /* We assume that the truncation rank will be ~ prec */
407 L = __gmpfr_isqrt (prec);
408 MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
410 z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t) );
411 MPFR_ASSERTN (z != NULL);
412 for (j=0; j<=L; j++)
413 mpfr_init (z[j]);
415 mpfr_init (s);
416 mpfr_init (u0); mpfr_init (u1);
417 mpfr_init (result);
418 mpfr_init (temp1);
419 mpfr_init (temp2);
421 /* ZIV loop */
422 for (;;)
424 MPFR_LOG_MSG (("working precision: %Pu\n", wprec));
426 for (j=0; j<=L; j++)
427 mpfr_set_prec (z[j], wprec);
428 mpfr_set_prec (s, wprec);
429 mpfr_set_prec (u0, wprec); mpfr_set_prec (u1, wprec);
430 mpfr_set_prec (result, wprec);
432 mpfr_set_ui (u0, 1, MPFR_RNDN);
433 mpfr_set (u1, x, MPFR_RNDN);
435 mpfr_set_ui (z[0], 1, MPFR_RNDU);
436 mpfr_sqr (z[1], u1, MPFR_RNDU);
437 mpfr_mul (z[1], z[1], x, (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD) );
439 if (MPFR_IS_NEG (x))
440 MPFR_CHANGE_SIGN (z[1]);
441 x3u = mpfr_get_ui (z[1], MPFR_RNDU); /* x3u >= ceil (x^3) */
442 if (MPFR_IS_NEG (x))
443 MPFR_CHANGE_SIGN (z[1]);
445 for (j=2; j<=L ;j++)
447 if (j%2 == 0)
448 mpfr_sqr (z[j], z[j/2], MPFR_RNDN);
449 else
450 mpfr_mul (z[j], z[j-1], z[1], MPFR_RNDN);
453 mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
454 mpfr_set_ui (u0, 9, MPFR_RNDN);
455 mpfr_cbrt (u0, u0, MPFR_RNDN);
456 mpfr_mul (u0, u0, temp2, MPFR_RNDN);
457 mpfr_ui_div (u0, 1, u0 , MPFR_RNDN); /* u0 = 1/( Gamma (2/3)*9^(1/3) ) */
459 mpfr_set_ui (u1, 3, MPFR_RNDN);
460 mpfr_cbrt (u1, u1, MPFR_RNDN);
461 mpfr_mul (u1, u1, temp1, MPFR_RNDN);
462 mpfr_neg (u1, u1, MPFR_RNDN);
463 mpfr_div (u1, x, u1, MPFR_RNDN); /* u1 = -x/(Gamma (1/3)*3^(1/3)) */
465 mpfr_set_ui (result, 0, MPFR_RNDN);
466 t = 0;
468 /* Evaluation of the series by Smith' method */
469 for (i=0; ; i++)
471 t += 3 * L;
473 /* k = 0 */
474 t -= 3;
475 mpfr_set (s, z[L-1], MPFR_RNDN);
476 for (j=L-2; ; j--)
478 t -= 3;
479 mpfr_div_ui2 (s, s, (t+2), (t+3), MPFR_RNDN);
480 mpfr_add (s, s, z[j], MPFR_RNDN);
481 if (j==0)
482 break;
484 mpfr_mul (s, s, u0, MPFR_RNDN);
485 mpfr_add (result, result, s, MPFR_RNDN);
487 mpfr_mul (u0, u0, z[L], MPFR_RNDN);
488 for (j=0; j<=L-1; j++)
490 mpfr_div_ui2 (u0, u0, (t + 2), (t + 3), MPFR_RNDN);
491 t += 3;
494 t++;
496 /* k = 1 */
497 t -= 3;
498 mpfr_set (s, z[L-1], MPFR_RNDN);
499 for (j=L-2; ; j--)
501 t -= 3;
502 mpfr_div_ui2 (s, s, (t + 2), (t + 3), MPFR_RNDN);
503 mpfr_add (s, s, z[j], MPFR_RNDN);
504 if (j==0)
505 break;
507 mpfr_mul (s, s, u1, MPFR_RNDN);
508 mpfr_add (result, result, s, MPFR_RNDN);
510 mpfr_mul (u1, u1, z[L], MPFR_RNDN);
511 for (j=0; j<=L-1; j++)
513 mpfr_div_ui2 (u1, u1, (t + 2), (t + 3), MPFR_RNDN);
514 t += 3;
517 t++;
519 /* k = 2 */
520 t++;
522 /* End of the loop over k */
523 t -= 3;
525 test0 = MPFR_IS_ZERO (u0) ||
526 MPFR_GET_EXP (u0) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
527 test1 = MPFR_IS_ZERO (u1) ||
528 MPFR_GET_EXP (u1) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
530 if ( test0 && test1 && (x3u <= (t + 2) * (t + 3) / 2) )
531 break;
534 MPFR_LOG_MSG (("Truncation rank: %lu\n", t));
536 err = (5 + MPFR_INT_CEIL_LOG2 (L+1) + MPFR_INT_CEIL_LOG2 (i+1)
537 + cond - MPFR_GET_EXP (result));
539 /* err is the number of bits lost due to the evaluation error */
540 /* wprec-(prec+1): number of bits lost due to the approximation error */
541 MPFR_LOG_MSG (("Roundoff error: %Pu\n", err));
542 MPFR_LOG_MSG (("Approxim error: %Pu\n", wprec - prec - 1));
544 if (wprec < err+1)
545 correctBits = 0;
546 else
548 if (wprec < err+prec+1)
549 correctBits = wprec - err - 1;
550 else
551 correctBits = prec;
554 if (MPFR_LIKELY (MPFR_CAN_ROUND (result, correctBits,
555 MPFR_PREC (y), rnd)))
556 break;
558 for (j=0; j<=L; j++)
559 mpfr_clear (z[j]);
560 (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
561 L = __gmpfr_isqrt (t);
562 MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
563 z = (mpfr_t *) (*__gmp_allocate_func) ( (L + 1) * sizeof (mpfr_t));
564 MPFR_ASSERTN (z != NULL);
565 for (j=0; j<=L; j++)
566 mpfr_init (z[j]);
568 if (correctBits == 0)
570 assumed_exponent *= 2;
571 MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
572 assumed_exponent));
573 wprec = prec + 6 + MPFR_INT_CEIL_LOG2 (t) + cond + assumed_exponent;
575 else
577 if (correctBits < prec)
578 { /* The precision was badly chosen */
579 MPFR_LOG_MSG (("Bad assumption on the exponent of Ai (x)", 0));
580 MPFR_LOG_MSG ((" (E=%ld)\n", (long) (MPFR_GET_EXP (result))));
581 wprec = prec + err + 1;
583 else
584 { /* We are really in a bad case of the TMD */
585 MPFR_ZIV_NEXT (loop, prec);
587 /* We update wprec */
588 /* We assume that t will not be multiplied by more than 4 */
589 wprec = (prec + (MPFR_INT_CEIL_LOG2 (t) + 2) + 6 + cond
590 - MPFR_GET_EXP (result));
593 } /* End of ZIV loop */
595 MPFR_ZIV_FREE (loop);
596 MPFR_SAVE_EXPO_FREE (expo);
598 r = mpfr_set (y, result, rnd);
600 mpfr_clear (tmp_sp);
601 mpfr_clear (tmp2_sp);
602 for (j=0; j<=L; j++)
603 mpfr_clear (z[j]);
604 (*__gmp_free_func) (z, (L + 1) * sizeof (mpfr_t));
606 mpfr_clear (s);
607 mpfr_clear (u0); mpfr_clear (u1);
608 mpfr_clear (result);
609 mpfr_clear (temp1);
610 mpfr_clear (temp2);
612 return r;
615 /* We consider that the boundary between the area where the naive method
616 should preferably be used and the area where Smith' method should preferably
617 be used has the following form:
618 it is a triangle defined by two lines (one for the negative values of x, and
619 one for the positive values of x) crossing at x=0.
621 More precisely,
623 * If x<0 and MPFR_AI_THRESHOLD1*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
624 use Smith' algorithm;
625 * If x>0 and MPFR_AI_THRESHOLD3*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
626 use Smith' algorithm;
627 * otherwise, use the naive method.
630 #define MPFR_AI_SCALE 1048576
633 mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
635 mpfr_t temp1, temp2;
636 int use_ai2;
637 MPFR_SAVE_EXPO_DECL (expo);
639 /* The exponent range must be large enough for the computation of temp1. */
640 MPFR_SAVE_EXPO_MARK (expo);
642 mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
643 mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
645 mpfr_set (temp1, x, MPFR_RNDN);
646 mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN);
647 mpfr_mul_ui (temp2, temp2, MPFR_PREC (y) > ULONG_MAX ?
648 ULONG_MAX : (unsigned long) MPFR_PREC (y), MPFR_RNDN);
650 if (MPFR_IS_NEG (x))
651 mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN);
652 else
653 mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN);
655 mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
656 mpfr_clear (temp2);
658 use_ai2 = mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0;
659 mpfr_clear (temp1);
661 MPFR_SAVE_EXPO_FREE (expo); /* Ignore all previous exceptions. */
663 return use_ai2 ? mpfr_ai2 (y, x, rnd) : mpfr_ai1 (y, x, rnd);