xref: /netbsd-src/external/lgpl3/mpfr/dist/src/ai.c (revision f3cfa6f6ce31685c6c4a758bc430e69eb99f50a4)
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