xref: /dragonfly/contrib/mpfr/src/ai.c (revision d8082429)
1 /* mpfr_ai -- Airy function Ai
2 
3 Copyright 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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 static int
50 mpfr_ai1 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
51 {
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;
69 
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) );
74 
75   /* Special cases */
76   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
77     {
78       if (MPFR_IS_NAN (x))
79         {
80           MPFR_SET_NAN (y);
81           MPFR_RET_NAN;
82         }
83       else if (MPFR_IS_INF (x))
84         return mpfr_set_ui (y, 0, rnd);
85     }
86 
87 
88   /* Save current exponents range */
89   MPFR_SAVE_EXPO_MARK (expo);
90 
91   if (MPFR_UNLIKELY (MPFR_IS_ZERO (x)))
92     {
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);
98 
99       /* ZIV loop */
100       for (;;)
101         {
102           mpfr_gamma_one_and_two_third (y1, y2, prec); /* y2 = Gamma(2/3)(1 + delta1), |delta1| <= 2^{1-prec}. */
103 
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);
112         }
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);
119     }
120 
121   /* FIXME: underflow for large values of |x| ? */
122 
123 
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           */
129 
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,    ?????                                                   */
134 
135   /* We begin with 11 guard bits */
136   prec = MPFR_PREC (y)+11;
137   MPFR_ZIV_INIT (loop, prec);
138 
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 */
149 
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);
153 
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;
159 
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
166     {
167       if (MPFR_IS_POS (x))
168         {
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));
174         }
175       /* We do not know Ai (x) yet */
176       /* We cover the case when EXP (Ai (x))>=-10 */
177       else
178         assumed_exponent = 10;
179     }
180 
181   wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 5 + cond + assumed_exponent;
182 
183   mpfr_init (ti);
184   mpfr_init (tip1);
185   mpfr_init (temp1);
186   mpfr_init (temp2);
187   mpfr_init (x3);
188   mpfr_init (s);
189 
190   /* ZIV loop */
191   for (;;)
192     {
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);
198 
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);
206 
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) ) */
212 
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)) */
218 
219       mpfr_add (s, ti, tip1, MPFR_RNDN);
220 
221 
222       /* Evaluation of the series */
223       k = 2;
224       for (;;)
225         {
226           mpfr_mul (ti, ti, x3, MPFR_RNDN);
227           mpfr_mul (tip1, tip1, x3, MPFR_RNDN);
228 
229           mpfr_div_ui2 (ti, ti, k, (k+1), MPFR_RNDN);
230           mpfr_div_ui2 (tip1, tip1, (k+1), (k+2), MPFR_RNDN);
231 
232           k += 3;
233           mpfr_add (s, s, ti, MPFR_RNDN);
234           mpfr_add (s, s, tip1, MPFR_RNDN);
235 
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));
241 
242           if ( test1 && test2 && (x3u <= k*(k+1)/2) )
243             break; /* FIXME: if k*(k+1) overflows */
244         }
245 
246       MPFR_LOG_MSG (("Truncation rank: %lu\n", k));
247 
248       err = 4 + MPFR_INT_CEIL_LOG2 (k) + cond - MPFR_GET_EXP (s);
249 
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));
254 
255       if (wprec < err+1)
256         correct_bits=0;
257       else
258         {
259           if (wprec < err+prec+1)
260             correct_bits =  wprec - err - 1;
261           else
262             correct_bits = prec;
263         }
264 
265       if (MPFR_LIKELY (MPFR_CAN_ROUND (s, correct_bits, MPFR_PREC (y), rnd)))
266         break;
267 
268       if (correct_bits == 0)
269         {
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;
274         }
275       else
276         {
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;
282             }
283           else
284             { /* We are really in a bad case of the TMD */
285               MPFR_ZIV_NEXT (loop, prec);
286 
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);
291             }
292         }
293 
294     } /* End of ZIV loop */
295 
296   MPFR_ZIV_FREE (loop);
297 
298   r = mpfr_set (y, s, rnd);
299 
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);
308 
309   MPFR_SAVE_EXPO_FREE (expo);
310   return mpfr_check_range (y, r, rnd);
311 }
312 
313 
314 /* Airy function Ai evaluated by Smith algorithm */
315 static int
316 mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
317 {
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;
336 
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));
341 
342   /* Special cases */
343   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
344     {
345       if (MPFR_IS_NAN (x))
346         {
347           MPFR_SET_NAN (y);
348           MPFR_RET_NAN;
349         }
350       else if (MPFR_IS_INF (x))
351         return mpfr_set_ui (y, 0, rnd);
352     }
353 
354   /* Save current exponents range */
355   MPFR_SAVE_EXPO_MARK (expo);
356 
357   /* FIXME: underflow for large values of |x| */
358 
359 
360   /* Set initial precision */
361   /* See the analysis for the naive evaluation */
362 
363   /* We begin with 11 guard bits */
364   prec = MPFR_PREC (y) + 11;
365   MPFR_ZIV_INIT (loop, prec);
366 
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 */
372 
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);
376 
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;
382 
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
389     {
390       if (MPFR_IS_POS (x))
391         {
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));
397         }
398       /* We do not know Ai (x) yet */
399       /* We cover the case when EXP (Ai (x))>=-10 */
400       else
401         assumed_exponent = 10;
402     }
403 
404   wprec = prec + MPFR_INT_CEIL_LOG2 (prec) + 6 + cond + assumed_exponent;
405 
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));
409 
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]);
414 
415   mpfr_init (s);
416   mpfr_init (u0); mpfr_init (u1);
417   mpfr_init (result);
418   mpfr_init (temp1);
419   mpfr_init (temp2);
420 
421   /* ZIV loop */
422   for (;;)
423     {
424       MPFR_LOG_MSG (("working precision: %Pu\n", wprec));
425 
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);
431 
432       mpfr_set_ui (u0, 1, MPFR_RNDN);
433       mpfr_set (u1, x, MPFR_RNDN);
434 
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) );
438 
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]);
444 
445       for (j=2; j<=L ;j++)
446         {
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);
451         }
452 
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) ) */
458 
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)) */
464 
465       mpfr_set_ui (result, 0, MPFR_RNDN);
466       t = 0;
467 
468       /* Evaluation of the series by Smith' method    */
469       for (i=0; ; i++)
470         {
471           t += 3 * L;
472 
473           /* k = 0 */
474           t -= 3;
475           mpfr_set (s, z[L-1], MPFR_RNDN);
476           for (j=L-2; ; j--)
477             {
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;
483             }
484           mpfr_mul (s, s, u0, MPFR_RNDN);
485           mpfr_add (result, result, s, MPFR_RNDN);
486 
487           mpfr_mul (u0, u0, z[L], MPFR_RNDN);
488           for (j=0; j<=L-1; j++)
489             {
490               mpfr_div_ui2 (u0, u0, (t + 2), (t + 3), MPFR_RNDN);
491               t += 3;
492             }
493 
494           t++;
495 
496           /* k = 1 */
497           t -= 3;
498           mpfr_set (s, z[L-1], MPFR_RNDN);
499           for (j=L-2; ; j--)
500             {
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;
506             }
507           mpfr_mul (s, s, u1, MPFR_RNDN);
508           mpfr_add (result, result, s, MPFR_RNDN);
509 
510           mpfr_mul (u1, u1, z[L], MPFR_RNDN);
511           for (j=0; j<=L-1; j++)
512             {
513               mpfr_div_ui2 (u1, u1, (t + 2), (t + 3), MPFR_RNDN);
514               t += 3;
515             }
516 
517           t++;
518 
519           /* k = 2 */
520           t++;
521 
522           /* End of the loop over k */
523           t -= 3;
524 
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);
529 
530           if ( test0 && test1 && (x3u <= (t + 2) * (t + 3) / 2) )
531             break;
532         }
533 
534       MPFR_LOG_MSG (("Truncation rank: %lu\n", t));
535 
536       err = (5 + MPFR_INT_CEIL_LOG2 (L+1) + MPFR_INT_CEIL_LOG2 (i+1)
537              + cond - MPFR_GET_EXP (result));
538 
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));
543 
544       if (wprec < err+1)
545         correctBits = 0;
546       else
547         {
548           if (wprec < err+prec+1)
549             correctBits = wprec - err - 1;
550           else
551             correctBits = prec;
552         }
553 
554       if (MPFR_LIKELY (MPFR_CAN_ROUND (result, correctBits,
555                                        MPFR_PREC (y), rnd)))
556         break;
557 
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]);
567 
568       if (correctBits == 0)
569         {
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;
574         }
575     else
576       {
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;
582           }
583         else
584           { /* We are really in a bad case of the TMD */
585             MPFR_ZIV_NEXT (loop, prec);
586 
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));
591           }
592       }
593     } /* End of ZIV loop */
594 
595   MPFR_ZIV_FREE (loop);
596   MPFR_SAVE_EXPO_FREE (expo);
597 
598   r = mpfr_set (y, result, rnd);
599 
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));
605 
606   mpfr_clear (s);
607   mpfr_clear (u0); mpfr_clear (u1);
608   mpfr_clear (result);
609   mpfr_clear (temp1);
610   mpfr_clear (temp2);
611 
612   return r;
613 }
614 
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.
620 
621    More precisely,
622 
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.
628 */
629 
630 #define MPFR_AI_SCALE 1048576
631 
632 int
633 mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
634 {
635   mpfr_t temp1, temp2;
636   int use_ai2;
637   MPFR_SAVE_EXPO_DECL (expo);
638 
639   /* The exponent range must be large enough for the computation of temp1. */
640   MPFR_SAVE_EXPO_MARK (expo);
641 
642   mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
643   mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
644 
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);
649 
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);
654 
655   mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
656   mpfr_clear (temp2);
657 
658   use_ai2 = mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0;
659   mpfr_clear (temp1);
660 
661   MPFR_SAVE_EXPO_FREE (expo); /* Ignore all previous exceptions. */
662 
663   return use_ai2 ? mpfr_ai2 (y, x, rnd) : mpfr_ai1 (y, x, rnd);
664 }
665