xref: /netbsd-src/external/lgpl3/mpfr/dist/src/ai.c (revision ec6772edaf0cdcb5f52a48f4aca5e33a8fb8ecfd)
1 /* mpfr_ai -- Airy function Ai
2 
3 Copyright 2010-2023 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 https://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
mpfr_ai1(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd)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[%Pd]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd),
74     ("y[%Pd]=%.*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   /* now x is not zero */
110   MPFR_ASSERTD(!MPFR_IS_ZERO(x));
111 
112   /* FIXME: underflow for large values of |x| ? */
113 
114 
115   /* Set initial precision */
116   /* If we compute sum(i=0, N-1, t_i), the relative error is bounded by  */
117   /*       2*(4N)*2^(1-wprec)*C(|x|)/Ai(x)                               */
118   /* where C(|x|) = 1 if 0<=x<=1                                         */
119   /*   and C(|x|) = (1/2)*x^(-1/4)*exp(2/3 x^(3/2))  if x >= 1           */
120 
121   /* A priori, we do not know N, so we estimate it to ~ prec             */
122   /* If 0<=x<=1, we estimate Ai(x) ~ 1/8                                 */
123   /* if 1<=x,    we estimate Ai(x) ~ (1/4)*x^(-1/4)*exp(-2/3 * x^(3/2))  */
124   /* if x<=0,    ?????                                                   */
125 
126   /* We begin with 11 guard bits */
127   prec = MPFR_ADD_PREC (MPFR_PREC (y), 11);
128   MPFR_ZIV_INIT (loop, prec);
129 
130   /* The working precision is heuristically chosen in order to obtain  */
131   /* approximately prec correct bits in the sum. To sum up: the sum    */
132   /* is stopped when the *exact* sum gives ~ prec correct bit. And     */
133   /* when it is stopped, the accuracy of the computed sum, with respect*/
134   /* to the exact one should be ~prec bits.                            */
135   mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
136   mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
137   mpfr_abs (tmp_sp, x, MPFR_RNDU);
138   mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
139   mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ |x|^(3/2) */
140 
141   /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
142   mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
143   mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
144 
145   /* cond represents the number of lost bits in the evaluation of the sum */
146   if (MPFR_GET_EXP (x) <= 0)
147     cond = 0;
148   else
149     {
150       MPFR_BLOCK_DECL (flags);
151 
152       MPFR_BLOCK (flags, cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU));
153       MPFR_ASSERTN (! MPFR_ERANGEFLAG (flags));
154       cond -= (MPFR_GET_EXP (x) - 1) / 4 + 1;
155     }
156 
157   /* The variable assumed_exponent is used to store the maximal assumed */
158   /* exponent of Ai(x). More precisely, we assume that |Ai(x)| will be  */
159   /* greater than 2^{-assumed_exponent}.                                */
160   if (MPFR_IS_POS (x))
161     {
162       if (MPFR_GET_EXP (x) <= 0)
163         assumed_exponent = 3;
164       else
165         {
166           unsigned long int t;
167           MPFR_BLOCK_DECL (flags);
168 
169           MPFR_BLOCK (flags, t = mpfr_get_ui (tmp2_sp, MPFR_RNDU));
170           MPFR_ASSERTN (! MPFR_ERANGEFLAG (flags));
171           assumed_exponent = t + 2 + (MPFR_GET_EXP (x) / 4 + 1);
172           MPFR_ASSERTN (assumed_exponent > t);
173         }
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     unsigned long int t, u;
182 
183     t = assumed_exponent + cond;
184     MPFR_ASSERTN (t >= cond);
185     u = MPFR_INT_CEIL_LOG2 (prec) + 5;
186     t += u;
187     MPFR_ASSERTN (t >= u);
188     wprec = MPFR_ADD_PREC (prec, t);
189   }
190 
191   mpfr_init2 (ti, wprec);
192   mpfr_init2 (tip1, wprec);
193   mpfr_init2 (temp1, wprec);
194   mpfr_init2 (temp2, wprec);
195   mpfr_init2 (x3, wprec);
196   mpfr_init2 (s, wprec);
197 
198   /* ZIV loop */
199   for (;;)
200     {
201       MPFR_LOG_MSG (("Working precision: %Pd\n", wprec));
202       mpfr_set_prec (ti, wprec);
203       mpfr_set_prec (tip1, wprec);
204       mpfr_set_prec (x3, wprec);
205       mpfr_set_prec (s, wprec);
206 
207       mpfr_sqr (x3, x, MPFR_RNDU);
208       mpfr_mul (x3, x3, x, (MPFR_IS_POS (x)?MPFR_RNDU:MPFR_RNDD));  /* x3=x^3 */
209       if (MPFR_IS_NEG (x))
210         MPFR_CHANGE_SIGN (x3);
211       x3u = mpfr_get_ui (x3, MPFR_RNDU);   /* x3u >= ceil(x^3) */
212       if (MPFR_IS_NEG (x))
213         MPFR_CHANGE_SIGN (x3);
214 
215       mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
216       mpfr_set_ui (ti, 9, MPFR_RNDN);
217       mpfr_cbrt (ti, ti, MPFR_RNDN);
218       mpfr_mul (ti, ti, temp2, MPFR_RNDN);
219       mpfr_ui_div (ti, 1, ti, MPFR_RNDN); /* ti = 1/( Gamma (2/3)*9^(1/3) ) */
220 
221       mpfr_set_ui (tip1, 3, MPFR_RNDN);
222       mpfr_cbrt (tip1, tip1, MPFR_RNDN);
223       mpfr_mul (tip1, tip1, temp1, MPFR_RNDN);
224       mpfr_neg (tip1, tip1, MPFR_RNDN);
225       mpfr_div (tip1, x, tip1, MPFR_RNDN); /* tip1 = -x/(Gamma (1/3)*3^(1/3)) */
226 
227       mpfr_add (s, ti, tip1, MPFR_RNDN);
228 
229 
230       /* Evaluation of the series */
231       k = 2;
232       for (;;)
233         {
234           mpfr_mul (ti, ti, x3, MPFR_RNDN);
235           mpfr_mul (tip1, tip1, x3, MPFR_RNDN);
236 
237           mpfr_div_ui2 (ti, ti, k, (k+1), MPFR_RNDN);
238           mpfr_div_ui2 (tip1, tip1, (k+1), (k+2), MPFR_RNDN);
239 
240           k += 3;
241           mpfr_add (s, s, ti, MPFR_RNDN);
242           mpfr_add (s, s, tip1, MPFR_RNDN);
243 
244           /* FIXME: if s==0 */
245           test1 = MPFR_IS_ZERO (ti)
246             || (MPFR_GET_EXP (ti) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
247           test2 = MPFR_IS_ZERO (tip1)
248             || (MPFR_GET_EXP (tip1) + (mpfr_exp_t)prec + 3 <= MPFR_GET_EXP (s));
249 
250           if ( test1 && test2 && (x3u <= k*(k+1)/2) )
251             break; /* FIXME: if k*(k+1) overflows */
252         }
253 
254       MPFR_LOG_MSG (("Truncation rank: %lu\n", k));
255 
256       err = 4 + MPFR_INT_CEIL_LOG2 (k) + cond - MPFR_GET_EXP (s);
257 
258       /* err is the number of bits lost due to the evaluation error */
259       /* wprec-(prec+1): number of bits lost due to the approximation error */
260       MPFR_LOG_MSG (("Roundoff error: %Pd\n", err));
261       MPFR_LOG_MSG (("Approxim error: %Pd\n", wprec-prec-1));
262 
263       if (wprec < err + 1)
264         correct_bits = 0;
265       else if (wprec < err + prec +1)
266         correct_bits =  wprec - err - 1; /* since wprec > err + 1,
267                                             correct_bits > 0 */
268       else
269         correct_bits = prec;
270 
271       if (MPFR_LIKELY (MPFR_CAN_ROUND (s, correct_bits, MPFR_PREC (y), rnd)))
272         break;
273 
274       if (correct_bits == 0)
275         {
276           assumed_exponent *= 2;
277           MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
278                          assumed_exponent));
279           wprec = prec + 5 + MPFR_INT_CEIL_LOG2 (prec) + cond +
280             assumed_exponent;
281         }
282       else if (correct_bits < prec)
283         { /* The precision was badly chosen */
284           MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)"
285                          " (E=%" MPFR_EXP_FSPEC "d)\n",
286                          (mpfr_eexp_t) MPFR_GET_EXP (s)));
287           wprec = prec + err + 1;
288         }
289       else
290         { /* We are really in a bad case of the TMD */
291           MPFR_ZIV_NEXT (loop, prec);
292 
293           /* We update wprec */
294           /* We assume that K will not be multiplied by more than 4 */
295           wprec = prec + (MPFR_INT_CEIL_LOG2 (k) + 2) + 5 + cond
296             - MPFR_GET_EXP (s);
297         }
298 
299     } /* End of ZIV loop */
300 
301   MPFR_ZIV_FREE (loop);
302 
303   r = mpfr_set (y, s, rnd);
304 
305   mpfr_clear (ti);
306   mpfr_clear (tip1);
307   mpfr_clear (temp1);
308   mpfr_clear (temp2);
309   mpfr_clear (x3);
310   mpfr_clear (s);
311   mpfr_clear (tmp_sp);
312   mpfr_clear (tmp2_sp);
313 
314   MPFR_SAVE_EXPO_FREE (expo);
315   return mpfr_check_range (y, r, rnd);
316 }
317 
318 
319 /* Airy function Ai evaluated by Smith algorithm.
320    Assume that x is a finite non-zero number. */
321 static int
mpfr_ai2(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd)322 mpfr_ai2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
323 {
324   MPFR_ZIV_DECL (loop);
325   MPFR_SAVE_EXPO_DECL (expo);
326   mpfr_prec_t wprec;             /* working precision */
327   mpfr_prec_t prec;              /* target precision */
328   mpfr_prec_t err;               /* used to estimate the evaluation error */
329   mpfr_prec_t correctBits;       /* estimates the number of correct bits*/
330   unsigned long int i, j, L, t;
331   unsigned long int cond;        /* condition number of the series */
332   unsigned long int assumed_exponent; /* used as a lowerbound of |EXP(Ai(x))| */
333   int r;                         /* returned ternary value */
334   mpfr_t s;                      /* used to store the partial sum */
335   mpfr_t u0, u1;
336   mpfr_t *z;                     /* used to store the (x^3j) */
337   mpfr_t result;
338   mpfr_t tmp_sp, tmp2_sp;        /* small precision variables */
339   unsigned long int x3u;         /* used to store ceil (x^3) */
340   mpfr_t temp1, temp2;
341   int test0, test1;
342 
343   /* Logging */
344   MPFR_LOG_FUNC (
345     ("x[%Pd]=%.*Rg rnd=%d", mpfr_get_prec (x),  mpfr_log_prec, x, rnd),
346     ("y[%Pd]=%.*Rg", mpfr_get_prec (y), mpfr_log_prec, y));
347 
348   /* Save current exponents range */
349   MPFR_SAVE_EXPO_MARK (expo);
350 
351   /* FIXME: underflow for large values of |x| */
352 
353   /* Set initial precision */
354   /* See the analysis for the naive evaluation */
355 
356   /* We begin with 11 guard bits */
357   prec = MPFR_PREC (y) + 11;
358   MPFR_ZIV_INIT (loop, prec);
359 
360   mpfr_init2 (tmp_sp, MPFR_SMALL_PRECISION);
361   mpfr_init2 (tmp2_sp, MPFR_SMALL_PRECISION);
362   mpfr_abs (tmp_sp, x, MPFR_RNDU);
363   mpfr_pow_ui (tmp_sp, tmp_sp, 3, MPFR_RNDU);
364   mpfr_sqrt (tmp_sp, tmp_sp, MPFR_RNDU); /* tmp_sp ~ |x|^(3/2) */
365 
366   /* 0.96179669392597567 >~ 2/3 * log2(e). See algorithms.tex */
367   mpfr_set_str (tmp2_sp, "0.96179669392597567", 10, MPFR_RNDU);
368   mpfr_mul (tmp2_sp, tmp_sp, tmp2_sp, MPFR_RNDU);
369 
370   /* cond represents the number of lost bits in the evaluation of the sum */
371   if (MPFR_GET_EXP (x) <= 0)
372     cond = 0;
373   else
374     {
375       MPFR_BLOCK_DECL (flags);
376 
377       MPFR_BLOCK (flags, cond = mpfr_get_ui (tmp2_sp, MPFR_RNDU));
378       MPFR_ASSERTN (! MPFR_ERANGEFLAG (flags));
379       cond -= (MPFR_GET_EXP (x) - 1) / 4 + 1;
380     }
381 
382   /* This variable is used to store the maximal assumed exponent of       */
383   /* Ai(x). More precisely, we assume that |Ai(x)| will be greater than   */
384   /* 2^{-assumed_exponent}.                                               */
385   if (MPFR_IS_POS (x))
386     {
387       if (MPFR_GET_EXP (x) <= 0)
388         assumed_exponent = 3;
389       else
390         {
391           unsigned long int t;
392           MPFR_BLOCK_DECL (flags);
393 
394           MPFR_BLOCK (flags, t = mpfr_get_ui (tmp2_sp, MPFR_RNDU));
395           MPFR_ASSERTN (! MPFR_ERANGEFLAG (flags));
396           assumed_exponent = t + 2 + (MPFR_GET_EXP (x) / 4 + 1);
397           MPFR_ASSERTN (assumed_exponent > t);
398         }
399     }
400   /* We do not know Ai(x) yet */
401   /* We cover the case when EXP(Ai(x))>=-10 */
402   else
403     assumed_exponent = 10;
404 
405   {
406     unsigned long int t, u;
407 
408     t = assumed_exponent + cond;
409     MPFR_ASSERTN (t >= cond);
410     u = MPFR_INT_CEIL_LOG2 (prec) + 6;
411     t += u;
412     MPFR_ASSERTN (t >= u);
413     wprec = MPFR_ADD_PREC (prec, t);
414   }
415 
416   /* We assume that the truncation rank will be ~ prec */
417   L = __gmpfr_isqrt (prec);
418   MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
419 
420   z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t) );
421   MPFR_ASSERTN (z != NULL);
422   for (j=0; j<=L; j++)
423     mpfr_init2 (z[j], wprec);
424 
425   mpfr_init2 (s, wprec);
426   mpfr_init2 (u0, wprec); mpfr_init2 (u1, wprec);
427   mpfr_init2 (result, wprec);
428   mpfr_init2 (temp1, wprec);
429   mpfr_init2 (temp2, wprec);
430 
431   /* ZIV loop */
432   for (;;)
433     {
434       MPFR_LOG_MSG (("working precision: %Pd\n", wprec));
435 
436       for (j=0; j<=L; j++)
437         mpfr_set_prec (z[j], wprec);
438       mpfr_set_prec (s, wprec);
439       mpfr_set_prec (u0, wprec); mpfr_set_prec (u1, wprec);
440       mpfr_set_prec (result, wprec);
441 
442       mpfr_set_ui (u0, 1, MPFR_RNDN);
443       mpfr_set (u1, x, MPFR_RNDN);
444 
445       mpfr_set_ui (z[0], 1, MPFR_RNDU);
446       mpfr_sqr (z[1], u1, MPFR_RNDU);
447       mpfr_mul (z[1], z[1], x, (MPFR_IS_POS (x) ? MPFR_RNDU : MPFR_RNDD) );
448 
449       if (MPFR_IS_NEG (x))
450         MPFR_CHANGE_SIGN (z[1]);
451       x3u = mpfr_get_ui (z[1], MPFR_RNDU);   /* x3u >= ceil (x^3) */
452       if (MPFR_IS_NEG (x))
453         MPFR_CHANGE_SIGN (z[1]);
454 
455       for (j=2; j<=L ;j++)
456         {
457           if (j%2 == 0)
458             mpfr_sqr (z[j], z[j/2], MPFR_RNDN);
459           else
460             mpfr_mul (z[j], z[j-1], z[1], MPFR_RNDN);
461         }
462 
463       mpfr_gamma_one_and_two_third (temp1, temp2, wprec);
464       mpfr_set_ui (u0, 9, MPFR_RNDN);
465       mpfr_cbrt (u0, u0, MPFR_RNDN);
466       mpfr_mul (u0, u0, temp2, MPFR_RNDN);
467       mpfr_ui_div (u0, 1, u0, MPFR_RNDN); /* u0 = 1/( Gamma (2/3)*9^(1/3) ) */
468 
469       mpfr_set_ui (u1, 3, MPFR_RNDN);
470       mpfr_cbrt (u1, u1, MPFR_RNDN);
471       mpfr_mul (u1, u1, temp1, MPFR_RNDN);
472       mpfr_neg (u1, u1, MPFR_RNDN);
473       mpfr_div (u1, x, u1, MPFR_RNDN); /* u1 = -x/(Gamma (1/3)*3^(1/3)) */
474 
475       mpfr_set_ui (result, 0, MPFR_RNDN);
476       t = 0;
477 
478       /* Evaluation of the series by Smith' method    */
479       for (i=0; ; i++)
480         {
481           t += 3 * L;
482 
483           /* k = 0 */
484           t -= 3;
485           mpfr_set (s, z[L-1], MPFR_RNDN);
486           for (j=L-2; ; j--)
487             {
488               t -= 3;
489               mpfr_div_ui2 (s, s, (t+2), (t+3), MPFR_RNDN);
490               mpfr_add (s, s, z[j], MPFR_RNDN);
491               if (j==0)
492                 break;
493             }
494           mpfr_mul (s, s, u0, MPFR_RNDN);
495           mpfr_add (result, result, s, MPFR_RNDN);
496 
497           mpfr_mul (u0, u0, z[L], MPFR_RNDN);
498           for (j=0; j<=L-1; j++)
499             {
500               mpfr_div_ui2 (u0, u0, (t + 2), (t + 3), MPFR_RNDN);
501               t += 3;
502             }
503 
504           t++;
505 
506           /* k = 1 */
507           t -= 3;
508           mpfr_set (s, z[L-1], MPFR_RNDN);
509           for (j=L-2; ; j--)
510             {
511               t -= 3;
512               mpfr_div_ui2 (s, s, (t + 2), (t + 3), MPFR_RNDN);
513               mpfr_add (s, s, z[j], MPFR_RNDN);
514               if (j==0)
515                 break;
516             }
517           mpfr_mul (s, s, u1, MPFR_RNDN);
518           mpfr_add (result, result, s, MPFR_RNDN);
519 
520           mpfr_mul (u1, u1, z[L], MPFR_RNDN);
521           for (j=0; j<=L-1; j++)
522             {
523               mpfr_div_ui2 (u1, u1, (t + 2), (t + 3), MPFR_RNDN);
524               t += 3;
525             }
526 
527           t++;
528 
529           /* k = 2 */
530           t++;
531 
532           /* End of the loop over k */
533           t -= 3;
534 
535           test0 = MPFR_IS_ZERO (u0) ||
536             MPFR_GET_EXP (u0) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
537           test1 = MPFR_IS_ZERO (u1) ||
538             MPFR_GET_EXP (u1) + (mpfr_exp_t)prec + 4 <= MPFR_GET_EXP (result);
539 
540           if ( test0 && test1 && (x3u <= (t + 2) * (t + 3) / 2) )
541             break;
542         }
543 
544       MPFR_LOG_MSG (("Truncation rank: %lu\n", t));
545 
546       err = (5 + MPFR_INT_CEIL_LOG2 (L+1) + MPFR_INT_CEIL_LOG2 (i+1)
547              + cond - MPFR_GET_EXP (result));
548 
549       /* err is the number of bits lost due to the evaluation error */
550       /* wprec-(prec+1): number of bits lost due to the approximation error */
551       MPFR_LOG_MSG (("Roundoff error: %Pd\n", err));
552       MPFR_LOG_MSG (("Approxim error: %Pd\n", wprec - prec - 1));
553 
554       if (wprec < err+1)
555         correctBits = 0;
556       else
557         {
558           if (wprec < err+prec+1)
559             correctBits = wprec - err - 1;
560           else
561             correctBits = prec;
562         }
563 
564       if (MPFR_LIKELY (MPFR_CAN_ROUND (result, correctBits,
565                                        MPFR_PREC (y), rnd)))
566         break;
567 
568       for (j=0; j<=L; j++)
569         mpfr_clear (z[j]);
570       mpfr_free_func (z, (L + 1) * sizeof (mpfr_t));
571       L = __gmpfr_isqrt (t);
572       MPFR_LOG_MSG (("size of blocks L = %lu\n", L));
573       z = (mpfr_t *) mpfr_allocate_func ( (L + 1) * sizeof (mpfr_t));
574       MPFR_ASSERTN (z != NULL);
575       for (j=0; j<=L; j++)
576         mpfr_init2 (z[j], wprec);
577 
578       if (correctBits == 0)
579         {
580           assumed_exponent *= 2;
581           MPFR_LOG_MSG (("Not a single bit correct (assumed_exponent=%lu)\n",
582                          assumed_exponent));
583           wprec = prec + 6 + MPFR_INT_CEIL_LOG2 (t) + cond + assumed_exponent;
584         }
585     else
586       {
587         if (correctBits < prec)
588           { /* The precision was badly chosen */
589             MPFR_LOG_MSG (("Bad assumption on the exponent of Ai(x)"
590                            " (E=%" MPFR_EXP_FSPEC "d)\n",
591                            (mpfr_eexp_t) MPFR_GET_EXP (result)));
592             wprec = prec + err + 1;
593           }
594         else
595           { /* We are really in a bad case of the TMD */
596             MPFR_ZIV_NEXT (loop, prec);
597 
598             /* We update wprec */
599             /* We assume that t will not be multiplied by more than 4 */
600             wprec = (prec + (MPFR_INT_CEIL_LOG2 (t) + 2) + 6 + cond
601                      - MPFR_GET_EXP (result));
602           }
603       }
604     } /* End of ZIV loop */
605 
606   MPFR_ZIV_FREE (loop);
607 
608   r = mpfr_set (y, result, rnd);
609 
610   mpfr_clear (tmp_sp);
611   mpfr_clear (tmp2_sp);
612   for (j=0; j<=L; j++)
613     mpfr_clear (z[j]);
614   mpfr_free_func (z, (L + 1) * sizeof (mpfr_t));
615 
616   mpfr_clear (s);
617   mpfr_clear (u0); mpfr_clear (u1);
618   mpfr_clear (result);
619   mpfr_clear (temp1);
620   mpfr_clear (temp2);
621 
622   MPFR_SAVE_EXPO_FREE (expo);
623   return mpfr_check_range (y, r, rnd);
624 }
625 
626 /* We consider that the boundary between the area where the naive method
627    should preferably be used and the area where Smith' method should preferably
628    be used has the following form:
629    it is a triangle defined by two lines (one for the negative values of x, and
630    one for the positive values of x) crossing at x=0.
631 
632    More precisely,
633 
634    * If x<0 and MPFR_AI_THRESHOLD1*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
635    use Smith' algorithm;
636    * If x>0 and MPFR_AI_THRESHOLD3*x + MPFR_AI_THRESHOLD2*prec > MPFR_AI_SCALE,
637    use Smith' algorithm;
638    * otherwise, use the naive method.
639 */
640 
641 #define MPFR_AI_SCALE 1048576
642 
643 int
mpfr_ai(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd)644 mpfr_ai (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd)
645 {
646   mpfr_t temp1, temp2;
647   int use_ai2;
648   MPFR_SAVE_EXPO_DECL (expo);
649 
650   /* Special cases */
651   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
652     {
653       if (MPFR_IS_NAN (x))
654         {
655           MPFR_SET_NAN (y);
656           MPFR_RET_NAN;
657         }
658       else if (MPFR_IS_INF (x))
659         return mpfr_set_ui (y, 0, rnd);
660       /* the cases x = +0 or -0 will be treated below */
661     }
662 
663   /* The exponent range must be large enough for the computation of temp1. */
664   MPFR_SAVE_EXPO_MARK (expo);
665 
666   mpfr_init2 (temp1, MPFR_SMALL_PRECISION);
667   mpfr_init2 (temp2, MPFR_SMALL_PRECISION);
668 
669   mpfr_set (temp1, x, MPFR_RNDN);
670   mpfr_set_si (temp2, MPFR_AI_THRESHOLD2, MPFR_RNDN);
671   mpfr_mul_ui (temp2, temp2, MPFR_PREC (y) > ULONG_MAX ?
672                ULONG_MAX : (unsigned long) MPFR_PREC (y), MPFR_RNDN);
673 
674   if (MPFR_IS_NEG (x))
675       mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD1, MPFR_RNDN);
676   else
677       mpfr_mul_si (temp1, temp1, MPFR_AI_THRESHOLD3, MPFR_RNDN);
678 
679   mpfr_add (temp1, temp1, temp2, MPFR_RNDN);
680   mpfr_clear (temp2);
681 
682   use_ai2 = mpfr_cmp_si (temp1, MPFR_AI_SCALE) > 0;
683   mpfr_clear (temp1);
684 
685   MPFR_SAVE_EXPO_FREE (expo); /* Ignore all previous exceptions. */
686 
687   /* we use ai2 if |x|*AI_THRESHOLD1/3 + PREC(y)*AI_THRESHOLD2 > AI_SCALE,
688      which means x cannot be zero in mpfr_ai2 */
689   return use_ai2 ? mpfr_ai2 (y, x, rnd) : mpfr_ai1 (y, x, rnd);
690 }
691