iscontrol(8): Fix synopsis, sync usage() & improve markup
[dragonfly.git] / contrib / mpfr / li2.c
blob0efd2a39428490a443c9aa83e2122f50a18595cf
1 /* mpfr_li2 -- Dilogarithm.
3 Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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 2.1 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.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #define MPFR_NEED_LONGLONG_H
24 #include "mpfr-impl.h"
26 /* assuming B[0]...B[2(n-1)] are computed, computes and stores B[2n]*(2n+1)!
28 t/(exp(t)-1) = sum(B[j]*t^j/j!, j=0..infinity)
29 thus t = (exp(t)-1) * sum(B[j]*t^j/j!, n=0..infinity).
30 Taking the coefficient of degree n+1 > 1, we get:
31 0 = sum(1/(n+1-k)!*B[k]/k!, k=0..n)
32 which gives:
33 B[n] = -sum(binomial(n+1,k)*B[k], k=0..n-1)/(n+1).
35 Let C[n] = B[n]*(n+1)!.
36 Then C[n] = -sum(binomial(n+1,k)*C[k]*n!/(k+1)!, k=0..n-1),
37 which proves that the C[n] are integers.
39 static mpz_t *
40 bernoulli (mpz_t * b, unsigned long n)
42 if (n == 0)
44 b = (mpz_t *) (*__gmp_allocate_func) (sizeof (mpz_t));
45 mpz_init_set_ui (b[0], 1);
47 else
49 mpz_t t;
50 unsigned long k;
52 b = (mpz_t *) (*__gmp_reallocate_func)
53 (b, n * sizeof (mpz_t), (n + 1) * sizeof (mpz_t));
54 mpz_init (b[n]);
55 /* b[n] = -sum(binomial(2n+1,2k)*C[k]*(2n)!/(2k+1)!, k=0..n-1) */
56 mpz_init_set_ui (t, 2 * n + 1);
57 mpz_mul_ui (t, t, 2 * n - 1);
58 mpz_mul_ui (t, t, 2 * n);
59 mpz_mul_ui (t, t, n);
60 mpz_div_ui (t, t, 3); /* exact: t=binomial(2*n+1,2*k)*(2*n)!/(2*k+1)!
61 for k=n-1 */
62 mpz_mul (b[n], t, b[n - 1]);
63 for (k = n - 1; k-- > 0;)
65 mpz_mul_ui (t, t, 2 * k + 1);
66 mpz_mul_ui (t, t, 2 * k + 2);
67 mpz_mul_ui (t, t, 2 * k + 2);
68 mpz_mul_ui (t, t, 2 * k + 3);
69 mpz_div_ui (t, t, 2 * (n - k) + 1);
70 mpz_div_ui (t, t, 2 * (n - k));
71 mpz_addmul (b[n], t, b[k]);
73 /* take into account C[1] */
74 mpz_mul_ui (t, t, 2 * n + 1);
75 mpz_div_2exp (t, t, 1);
76 mpz_sub (b[n], b[n], t);
77 mpz_neg (b[n], b[n]);
78 mpz_clear (t);
80 return b;
83 /* Compute the alternating series
84 s = S(z) = \sum_{k=0}^infty B_{2k} (z))^{2k+1} / (2k+1)!
85 with 0 < z <= log(2) to the precision of s rounded in the direction
86 rnd_mode.
87 Return the maximum index of the truncature which is useful
88 for determinating the relative error.
90 static int
91 li2_series (mpfr_t sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
93 int i, Bm, Bmax;
94 mpfr_t s, u, v, w;
95 mpfr_prec_t sump, p;
96 mp_exp_t se, err;
97 mpz_t *B;
98 MPFR_ZIV_DECL (loop);
100 /* The series converges for |z| < 2 pi, but in mpfr_li2 the argument is
101 reduced so that 0 < z <= log(2). Here is additionnal check that z is
102 (nearly) correct */
103 MPFR_ASSERTD (MPFR_IS_STRICTPOS (z));
104 MPFR_ASSERTD (mpfr_cmp_d (z, 0.6953125) <= 0);
106 sump = MPFR_PREC (sum); /* target precision */
107 p = sump + MPFR_INT_CEIL_LOG2 (sump) + 4; /* the working precision */
108 mpfr_init2 (s, p);
109 mpfr_init2 (u, p);
110 mpfr_init2 (v, p);
111 mpfr_init2 (w, p);
113 B = bernoulli ((mpz_t *) 0, 0);
114 Bm = Bmax = 1;
116 MPFR_ZIV_INIT (loop, p);
117 for (;;)
119 mpfr_sqr (u, z, GMP_RNDU);
120 mpfr_set (v, z, GMP_RNDU);
121 mpfr_set (s, z, GMP_RNDU);
122 se = MPFR_GET_EXP (s);
123 err = 0;
125 for (i = 1;; i++)
127 if (i >= Bmax)
128 B = bernoulli (B, Bmax++); /* B_2i * (2i+1)!, exact */
130 mpfr_mul (v, u, v, GMP_RNDU);
131 mpfr_div_ui (v, v, 2 * i, GMP_RNDU);
132 mpfr_div_ui (v, v, 2 * i, GMP_RNDU);
133 mpfr_div_ui (v, v, 2 * i + 1, GMP_RNDU);
134 mpfr_div_ui (v, v, 2 * i + 1, GMP_RNDU);
135 /* here, v_2i = v_{2i-2} / (2i * (2i+1))^2 */
137 mpfr_mul_z (w, v, B[i], GMP_RNDN);
138 /* here, w_2i = v_2i * B_2i * (2i+1)! with
139 error(w_2i) < 2^(5 * i + 8) ulp(w_2i) (see algorithms.tex) */
141 mpfr_add (s, s, w, GMP_RNDN);
143 err = MAX (err + se, 5 * i + 8 + MPFR_GET_EXP (w))
144 - MPFR_GET_EXP (s);
145 err = 2 + MAX (-1, err);
146 se = MPFR_GET_EXP (s);
147 if (MPFR_GET_EXP (w) <= se - (mp_exp_t) p)
148 break;
151 /* the previous value of err is the rounding error,
152 the truncation error is less than EXP(z) - 6 * i - 5
153 (see algorithms.tex) */
154 err = MAX (err, MPFR_GET_EXP (z) - 6 * i - 5) + 1;
155 if (MPFR_CAN_ROUND (s, (mp_exp_t) p - err, sump, rnd_mode))
156 break;
158 MPFR_ZIV_NEXT (loop, p);
159 mpfr_set_prec (s, p);
160 mpfr_set_prec (u, p);
161 mpfr_set_prec (v, p);
162 mpfr_set_prec (w, p);
164 MPFR_ZIV_FREE (loop);
165 mpfr_set (sum, s, rnd_mode);
167 Bm = Bmax;
168 while (Bm--)
169 mpz_clear (B[Bm]);
170 (*__gmp_free_func) (B, Bmax * sizeof (mpz_t));
171 mpfr_clears (s, u, v, w, (mpfr_ptr) 0);
173 /* Let K be the returned value.
174 1. As we compute an alternating series, the truncation error has the same
175 sign as the next term w_{K+2} which is positive iff K%4 == 0.
176 2. Assume that error(z) <= (1+t) z', where z' is the actual value, then
177 error(s) <= 2 * (K+1) * t (see algorithms.tex).
179 return 2 * i;
182 /* try asymptotic expansion when x is large and positive:
183 Li2(x) = -log(x)^2/2 + Pi^2/3 - 1/x + O(1/x^2).
184 More precisely for x >= 2 we have for g(x) = -log(x)^2/2 + Pi^2/3:
185 -2 <= x * (Li2(x) - g(x)) <= -1
186 thus |Li2(x) - g(x)| <= 2/x.
187 Assumes x >= 38, which ensures log(x)^2/2 >= 2*Pi^2/3, and g(x) <= -3.3.
188 Return 0 if asymptotic expansion failed (unable to round), otherwise
189 returns correct ternary value.
191 static int
192 mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
194 mpfr_t g, h;
195 mp_prec_t w = MPFR_PREC (y) + 20;
196 int inex = 0;
198 MPFR_ASSERTN (mpfr_cmp_ui (x, 38) >= 0);
200 mpfr_init2 (g, w);
201 mpfr_init2 (h, w);
202 mpfr_log (g, x, GMP_RNDN); /* rel. error <= |(1 + theta) - 1| */
203 mpfr_sqr (g, g, GMP_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
204 mpfr_div_2ui (g, g, 1, GMP_RNDN); /* rel. error <= 2^(2-w) */
205 mpfr_const_pi (h, GMP_RNDN); /* error <= 2^(1-w) */
206 mpfr_sqr (h, h, GMP_RNDN); /* rel. error <= 2^(2-w) */
207 mpfr_div_ui (h, h, 3, GMP_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
208 <= 5 * 2^(-w) */
209 /* since x is chosen such that log(x)^2/2 >= 2 * (Pi^2/3), we should have
210 g >= 2*h, thus |g-h| >= |h|, and the relative error on g is at most
211 multiplied by 2 in the difference, and that by h is unchanged. */
212 MPFR_ASSERTN (MPFR_EXP (g) > MPFR_EXP (h));
213 mpfr_sub (g, h, g, GMP_RNDN); /* err <= ulp(g)/2 + g*2^(3-w) + g*5*2^(-w)
214 <= ulp(g) * (1/2 + 8 + 5) < 14 ulp(g).
216 If in addition 2/x <= 2 ulp(g), i.e.,
217 1/x <= ulp(g), then the total error is
218 bounded by 16 ulp(g). */
219 if ((MPFR_EXP (x) >= (mp_exp_t) w - MPFR_EXP (g)) &&
220 MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
221 inex = mpfr_set (y, g, rnd_mode);
223 mpfr_clear (g);
224 mpfr_clear (h);
226 return inex;
229 /* try asymptotic expansion when x is large and negative:
230 Li2(x) = -log(-x)^2/2 - Pi^2/6 - 1/x + O(1/x^2).
231 More precisely for x <= -2 we have for g(x) = -log(-x)^2/2 - Pi^2/6:
232 |Li2(x) - g(x)| <= 1/|x|.
233 Assumes x <= -7, which ensures |log(-x)^2/2| >= Pi^2/6, and g(x) <= -3.5.
234 Return 0 if asymptotic expansion failed (unable to round), otherwise
235 returns correct ternary value.
237 static int
238 mpfr_li2_asympt_neg (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
240 mpfr_t g, h;
241 mp_prec_t w = MPFR_PREC (y) + 20;
242 int inex = 0;
244 MPFR_ASSERTN (mpfr_cmp_si (x, -7) <= 0);
246 mpfr_init2 (g, w);
247 mpfr_init2 (h, w);
248 mpfr_neg (g, x, GMP_RNDN);
249 mpfr_log (g, g, GMP_RNDN); /* rel. error <= |(1 + theta) - 1| */
250 mpfr_sqr (g, g, GMP_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
251 mpfr_div_2ui (g, g, 1, GMP_RNDN); /* rel. error <= 2^(2-w) */
252 mpfr_const_pi (h, GMP_RNDN); /* error <= 2^(1-w) */
253 mpfr_sqr (h, h, GMP_RNDN); /* rel. error <= 2^(2-w) */
254 mpfr_div_ui (h, h, 6, GMP_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
255 <= 5 * 2^(-w) */
256 MPFR_ASSERTN (MPFR_EXP (g) >= MPFR_EXP (h));
257 mpfr_add (g, g, h, GMP_RNDN); /* err <= ulp(g)/2 + g*2^(2-w) + g*5*2^(-w)
258 <= ulp(g) * (1/2 + 4 + 5) < 10 ulp(g).
260 If in addition |1/x| <= 4 ulp(g), then the
261 total error is bounded by 16 ulp(g). */
262 if ((MPFR_EXP (x) >= (mp_exp_t) (w - 2) - MPFR_EXP (g)) &&
263 MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
264 inex = mpfr_neg (y, g, rnd_mode);
266 mpfr_clear (g);
267 mpfr_clear (h);
269 return inex;
272 /* Compute the real part of the dilogarithm defined by
273 Li2(x) = -\Int_{t=0}^x log(1-t)/t dt */
275 mpfr_li2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
277 int inexact;
278 mp_exp_t err;
279 mpfr_prec_t yp, m;
280 MPFR_ZIV_DECL (loop);
281 MPFR_SAVE_EXPO_DECL (expo);
283 MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", x, x, rnd_mode), ("y[%#R]=%R", y));
285 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
287 if (MPFR_IS_NAN (x))
289 MPFR_SET_NAN (y);
290 MPFR_RET_NAN;
292 else if (MPFR_IS_INF (x))
294 MPFR_SET_NEG (y);
295 MPFR_SET_INF (y);
296 MPFR_RET (0);
298 else /* x is zero */
300 MPFR_ASSERTD (MPFR_IS_ZERO (x));
301 MPFR_SET_SAME_SIGN (y, x);
302 MPFR_SET_ZERO (y);
303 MPFR_RET (0);
307 /* Li2(x) = x + x^2/4 + x^3/9 + ..., more precisely for 0 < x <= 1/2
308 we have |Li2(x) - x| < x^2/2 <= 2^(2EXP(x)-1) and for -1/2 <= x < 0
309 we have |Li2(x) - x| < x^2/4 <= 2^(2EXP(x)-2) */
310 if (MPFR_IS_POS (x))
311 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 1, 1, rnd_mode,
312 {});
313 else
314 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 2, 0, rnd_mode,
315 {});
317 MPFR_SAVE_EXPO_MARK (expo);
318 yp = MPFR_PREC (y);
319 m = yp + MPFR_INT_CEIL_LOG2 (yp) + 13;
321 if (MPFR_LIKELY ((mpfr_cmp_ui (x, 0) > 0) && (mpfr_cmp_d (x, 0.5) <= 0)))
322 /* 0 < x <= 1/2: Li2(x) = S(-log(1-x))-log^2(1-x)/4 */
324 mpfr_t s, u;
325 mp_exp_t expo_l;
326 int k;
328 mpfr_init2 (u, m);
329 mpfr_init2 (s, m);
331 MPFR_ZIV_INIT (loop, m);
332 for (;;)
334 mpfr_ui_sub (u, 1, x, GMP_RNDN);
335 mpfr_log (u, u, GMP_RNDU);
336 mpfr_neg (u, u, GMP_RNDN); /* u = -log(1-x) */
337 expo_l = MPFR_GET_EXP (u);
338 k = li2_series (s, u, GMP_RNDU);
339 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1);
341 mpfr_sqr (u, u, GMP_RNDU);
342 mpfr_div_2ui (u, u, 2, GMP_RNDU); /* u = log^2(1-x) / 4 */
343 mpfr_sub (s, s, u, GMP_RNDN);
345 /* error(s) <= (0.5 + 2^(d-EXP(s))
346 + 2^(3 + MAX(1, - expo_l) - EXP(s))) ulp(s) */
347 err = MAX (err, MAX (1, - expo_l) - 1) - MPFR_GET_EXP (s);
348 err = 2 + MAX (-1, err);
349 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
350 break;
352 MPFR_ZIV_NEXT (loop, m);
353 mpfr_set_prec (u, m);
354 mpfr_set_prec (s, m);
356 MPFR_ZIV_FREE (loop);
357 inexact = mpfr_set (y, s, rnd_mode);
359 mpfr_clear (u);
360 mpfr_clear (s);
361 MPFR_SAVE_EXPO_FREE (expo);
362 return mpfr_check_range (y, inexact, rnd_mode);
364 else if (!mpfr_cmp_ui (x, 1))
365 /* Li2(1)= pi^2 / 6 */
367 mpfr_t u;
368 mpfr_init2 (u, m);
370 MPFR_ZIV_INIT (loop, m);
371 for (;;)
373 mpfr_const_pi (u, GMP_RNDU);
374 mpfr_sqr (u, u, GMP_RNDN);
375 mpfr_div_ui (u, u, 6, GMP_RNDN);
377 err = m - 4; /* error(u) <= 19/2 ulp(u) */
378 if (MPFR_CAN_ROUND (u, err, yp, rnd_mode))
379 break;
381 MPFR_ZIV_NEXT (loop, m);
382 mpfr_set_prec (u, m);
384 MPFR_ZIV_FREE (loop);
385 inexact = mpfr_set (y, u, rnd_mode);
387 mpfr_clear (u);
388 MPFR_SAVE_EXPO_FREE (expo);
389 return mpfr_check_range (y, inexact, rnd_mode);
391 else if (mpfr_cmp_ui (x, 2) >= 0)
392 /* x >= 2: Li2(x) = -S(-log(1-1/x))-log^2(x)/2+log^2(1-1/x)/4+pi^2/3 */
394 int k;
395 mp_exp_t expo_l;
396 mpfr_t s, u, xx;
398 if (mpfr_cmp_ui (x, 38) >= 0)
400 inexact = mpfr_li2_asympt_pos (y, x, rnd_mode);
401 if (inexact != 0)
402 goto end_of_case_gt2;
405 mpfr_init2 (u, m);
406 mpfr_init2 (s, m);
407 mpfr_init2 (xx, m);
409 MPFR_ZIV_INIT (loop, m);
410 for (;;)
412 mpfr_ui_div (xx, 1, x, GMP_RNDN);
413 mpfr_neg (xx, xx, GMP_RNDN);
414 mpfr_log1p (u, xx, GMP_RNDD);
415 mpfr_neg (u, u, GMP_RNDU); /* u = -log(1-1/x) */
416 expo_l = MPFR_GET_EXP (u);
417 k = li2_series (s, u, GMP_RNDN);
418 mpfr_neg (s, s, GMP_RNDN);
419 err = MPFR_INT_CEIL_LOG2 (k + 1) + 1; /* error(s) <= 2^err ulp(s) */
421 mpfr_sqr (u, u, GMP_RNDN);
422 mpfr_div_2ui (u, u, 2, GMP_RNDN); /* u= log^2(1-1/x)/4 */
423 mpfr_add (s, s, u, GMP_RNDN);
424 err =
425 MAX (err,
426 3 + MAX (1, -expo_l) + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
427 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
428 err += MPFR_GET_EXP (s);
430 mpfr_log (u, x, GMP_RNDU);
431 mpfr_sqr (u, u, GMP_RNDN);
432 mpfr_div_2ui (u, u, 1, GMP_RNDN); /* u = log^2(x)/2 */
433 mpfr_sub (s, s, u, GMP_RNDN);
434 err = MAX (err, 3 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
435 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
436 err += MPFR_GET_EXP (s);
438 mpfr_const_pi (u, GMP_RNDU);
439 mpfr_sqr (u, u, GMP_RNDN);
440 mpfr_div_ui (u, u, 3, GMP_RNDN); /* u = pi^2/3 */
441 mpfr_add (s, s, u, GMP_RNDN);
442 err = MAX (err, 2) - MPFR_GET_EXP (s);
443 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
444 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
445 break;
447 MPFR_ZIV_NEXT (loop, m);
448 mpfr_set_prec (u, m);
449 mpfr_set_prec (s, m);
450 mpfr_set_prec (xx, m);
452 MPFR_ZIV_FREE (loop);
453 inexact = mpfr_set (y, s, rnd_mode);
454 mpfr_clears (s, u, xx, (mpfr_ptr) 0);
456 end_of_case_gt2:
457 MPFR_SAVE_EXPO_FREE (expo);
458 return mpfr_check_range (y, inexact, rnd_mode);
460 else if (mpfr_cmp_ui (x, 1) > 0)
461 /* 2 > x > 1: Li2(x) = S(log(x))+log^2(x)/4-log(x)log(x-1)+pi^2/6 */
463 int k;
464 mp_exp_t e1, e2;
465 mpfr_t s, u, v, xx;
466 mpfr_init2 (s, m);
467 mpfr_init2 (u, m);
468 mpfr_init2 (v, m);
469 mpfr_init2 (xx, m);
471 MPFR_ZIV_INIT (loop, m);
472 for (;;)
474 mpfr_log (v, x, GMP_RNDU);
475 k = li2_series (s, v, GMP_RNDN);
476 e1 = MPFR_GET_EXP (s);
478 mpfr_sqr (u, v, GMP_RNDN);
479 mpfr_div_2ui (u, u, 2, GMP_RNDN); /* u = log^2(x)/4 */
480 mpfr_add (s, s, u, GMP_RNDN);
482 mpfr_sub_ui (xx, x, 1, GMP_RNDN);
483 mpfr_log (u, xx, GMP_RNDU);
484 e2 = MPFR_GET_EXP (u);
485 mpfr_mul (u, v, u, GMP_RNDN); /* u = log(x) * log(x-1) */
486 mpfr_sub (s, s, u, GMP_RNDN);
488 mpfr_const_pi (u, GMP_RNDU);
489 mpfr_sqr (u, u, GMP_RNDN);
490 mpfr_div_ui (u, u, 6, GMP_RNDN); /* u = pi^2/6 */
491 mpfr_add (s, s, u, GMP_RNDN);
492 /* error(s) <= (31 + (k+1) * 2^(1-e1) + 2^(1-e2)) ulp(s)
493 see algorithms.tex */
494 err = MAX (MPFR_INT_CEIL_LOG2 (k + 1) + 1 - e1, 1 - e2);
495 err = 2 + MAX (5, err);
496 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
497 break;
499 MPFR_ZIV_NEXT (loop, m);
500 mpfr_set_prec (s, m);
501 mpfr_set_prec (u, m);
502 mpfr_set_prec (v, m);
503 mpfr_set_prec (xx, m);
505 MPFR_ZIV_FREE (loop);
506 inexact = mpfr_set (y, s, rnd_mode);
508 mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
509 MPFR_SAVE_EXPO_FREE (expo);
510 return mpfr_check_range (y, inexact, rnd_mode);
512 else if (mpfr_cmp_ui_2exp (x, 1, -1) > 0) /* 1/2 < x < 1 */
513 /* 1 > x > 1/2: Li2(x) = -S(-log(x))+log^2(x)/4-log(x)log(1-x)+pi^2/6 */
515 int k;
516 mpfr_t s, u, v, xx;
517 mpfr_init2 (s, m);
518 mpfr_init2 (u, m);
519 mpfr_init2 (v, m);
520 mpfr_init2 (xx, m);
523 MPFR_ZIV_INIT (loop, m);
524 for (;;)
526 mpfr_log (u, x, GMP_RNDD);
527 mpfr_neg (u, u, GMP_RNDN);
528 k = li2_series (s, u, GMP_RNDN);
529 mpfr_neg (s, s, GMP_RNDN);
530 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
532 mpfr_ui_sub (xx, 1, x, GMP_RNDN);
533 mpfr_log (v, xx, GMP_RNDU);
534 mpfr_mul (v, v, u, GMP_RNDN); /* v = - log(x) * log(1-x) */
535 mpfr_add (s, s, v, GMP_RNDN);
536 err = MAX (err, 1 - MPFR_GET_EXP (v));
537 err = 2 + MAX (3, err) - MPFR_GET_EXP (s);
539 mpfr_sqr (u, u, GMP_RNDN);
540 mpfr_div_2ui (u, u, 2, GMP_RNDN); /* u = log^2(x)/4 */
541 mpfr_add (s, s, u, GMP_RNDN);
542 err = MAX (err, 2 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
543 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
545 mpfr_const_pi (u, GMP_RNDU);
546 mpfr_sqr (u, u, GMP_RNDN);
547 mpfr_div_ui (u, u, 6, GMP_RNDN); /* u = pi^2/6 */
548 mpfr_add (s, s, u, GMP_RNDN);
549 err = MAX (err, 3) - MPFR_GET_EXP (s);
550 err = 2 + MAX (-1, err);
552 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
553 break;
555 MPFR_ZIV_NEXT (loop, m);
556 mpfr_set_prec (s, m);
557 mpfr_set_prec (u, m);
558 mpfr_set_prec (v, m);
559 mpfr_set_prec (xx, m);
561 MPFR_ZIV_FREE (loop);
562 inexact = mpfr_set (y, s, rnd_mode);
564 mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
565 MPFR_SAVE_EXPO_FREE (expo);
566 return mpfr_check_range (y, inexact, rnd_mode);
568 else if (mpfr_cmp_si (x, -1) >= 0)
569 /* 0 > x >= -1: Li2(x) = -S(log(1-x))-log^2(1-x)/4 */
571 int k;
572 mp_exp_t expo_l;
573 mpfr_t s, u, xx;
574 mpfr_init2 (s, m);
575 mpfr_init2 (u, m);
576 mpfr_init2 (xx, m);
578 MPFR_ZIV_INIT (loop, m);
579 for (;;)
581 mpfr_neg (xx, x, GMP_RNDN);
582 mpfr_log1p (u, xx, GMP_RNDN);
583 k = li2_series (s, u, GMP_RNDN);
584 mpfr_neg (s, s, GMP_RNDN);
585 expo_l = MPFR_GET_EXP (u);
586 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
588 mpfr_sqr (u, u, GMP_RNDN);
589 mpfr_div_2ui (u, u, 2, GMP_RNDN); /* u = log^2(1-x)/4 */
590 mpfr_sub (s, s, u, GMP_RNDN);
591 err = MAX (err, - expo_l);
592 err = 2 + MAX (err, 3);
593 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
594 break;
596 MPFR_ZIV_NEXT (loop, m);
597 mpfr_set_prec (s, m);
598 mpfr_set_prec (u, m);
599 mpfr_set_prec (xx, m);
601 MPFR_ZIV_FREE (loop);
602 inexact = mpfr_set (y, s, rnd_mode);
604 mpfr_clears (s, u, xx, (mpfr_ptr) 0);
605 MPFR_SAVE_EXPO_FREE (expo);
606 return mpfr_check_range (y, inexact, rnd_mode);
608 else
609 /* x < -1: Li2(x)
610 = S(log(1-1/x))-log^2(-x)/4-log(1-x)log(-x)/2+log^2(1-x)/4-pi^2/6 */
612 int k;
613 mpfr_t s, u, v, w, xx;
615 if (mpfr_cmp_si (x, -7) <= 0)
617 inexact = mpfr_li2_asympt_neg (y, x, rnd_mode);
618 if (inexact != 0)
619 goto end_of_case_ltm1;
622 mpfr_init2 (s, m);
623 mpfr_init2 (u, m);
624 mpfr_init2 (v, m);
625 mpfr_init2 (w, m);
626 mpfr_init2 (xx, m);
628 MPFR_ZIV_INIT (loop, m);
629 for (;;)
631 mpfr_ui_div (xx, 1, x, GMP_RNDN);
632 mpfr_neg (xx, xx, GMP_RNDN);
633 mpfr_log1p (u, xx, GMP_RNDN);
634 k = li2_series (s, u, GMP_RNDN);
636 mpfr_ui_sub (xx, 1, x, GMP_RNDN);
637 mpfr_log (u, xx, GMP_RNDU);
638 mpfr_neg (xx, x, GMP_RNDN);
639 mpfr_log (v, xx, GMP_RNDU);
640 mpfr_mul (w, v, u, GMP_RNDN);
641 mpfr_div_2ui (w, w, 1, GMP_RNDN); /* w = log(-x) * log(1-x) / 2 */
642 mpfr_sub (s, s, w, GMP_RNDN);
643 err = 1 + MAX (3, MPFR_INT_CEIL_LOG2 (k+1) + 1 - MPFR_GET_EXP (s))
644 + MPFR_GET_EXP (s);
646 mpfr_sqr (w, v, GMP_RNDN);
647 mpfr_div_2ui (w, w, 2, GMP_RNDN); /* w = log^2(-x) / 4 */
648 mpfr_sub (s, s, w, GMP_RNDN);
649 err = MAX (err, 3 + MPFR_GET_EXP(w)) - MPFR_GET_EXP (s);
650 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
652 mpfr_sqr (w, u, GMP_RNDN);
653 mpfr_div_2ui (w, w, 2, GMP_RNDN); /* w = log^2(1-x) / 4 */
654 mpfr_add (s, s, w, GMP_RNDN);
655 err = MAX (err, 3 + MPFR_GET_EXP (w)) - MPFR_GET_EXP (s);
656 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
658 mpfr_const_pi (w, GMP_RNDU);
659 mpfr_sqr (w, w, GMP_RNDN);
660 mpfr_div_ui (w, w, 6, GMP_RNDN); /* w = pi^2 / 6 */
661 mpfr_sub (s, s, w, GMP_RNDN);
662 err = MAX (err, 3) - MPFR_GET_EXP (s);
663 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
665 if (MPFR_CAN_ROUND (s, (mp_exp_t) m - err, yp, rnd_mode))
666 break;
668 MPFR_ZIV_NEXT (loop, m);
669 mpfr_set_prec (s, m);
670 mpfr_set_prec (u, m);
671 mpfr_set_prec (v, m);
672 mpfr_set_prec (w, m);
673 mpfr_set_prec (xx, m);
675 MPFR_ZIV_FREE (loop);
676 inexact = mpfr_set (y, s, rnd_mode);
677 mpfr_clears (s, u, v, w, xx, (mpfr_ptr) 0);
679 end_of_case_ltm1:
680 MPFR_SAVE_EXPO_FREE (expo);
681 return mpfr_check_range (y, inexact, rnd_mode);
684 MPFR_ASSERTN (0); /* should never reach this point */