1 /* mpfr_atan -- arc-tangent of a floating-point number
3 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 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, and was contributed by Mathieu Dutour.
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 /* If x = p/2^r, put in y an approximation of atan(x)/x using 2^m terms
27 for the series expansion, with an error of at most 1 ulp.
30 If X=x^2, we want 1 - X/3 + X^2/5 - ... + (-1)^k*X^k/(2k+1) + ...
35 mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab)
38 unsigned long n, i, k, j, l;
41 mp_prec_t mult, *accu, *log2_nb_terms;
42 mp_prec_t precy = MPFR_PREC(y);
44 MPFR_ASSERTD(mpz_cmp_ui (p, 0) != 0);
46 accu = (mp_prec_t*) (*__gmp_allocate_func) ((2 * m + 2) * sizeof (mp_prec_t));
47 log2_nb_terms = accu + m + 1;
51 ptoj = S + 1*(m+1); /* p^2^j Precomputed table */
52 Q = S + 2*(m+1); /* Product of Odd integer table */
54 /* From p to p^2, and r to 2r */
56 MPFR_ASSERTD (2 * r > r);
61 mpz_tdiv_q_2exp (p, p, n); /* exact */
64 /* since |p/2^r| < 1, and p is a non-zero integer, necessarily r > 0 */
66 MPFR_ASSERTD (mpz_sgn (p) > 0);
69 /* check if p=1 (special case) */
72 We compute by binary splitting, with X = x^2 = p/2^r:
73 P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise
74 Q(a,b) = (2a+1)*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise
75 S(a,b) = p*(2a+1) if a+1=b, Q(c,b)*S(a,c)+Q(a,c)*P(a,c)*S(c,b) otherwise
76 Then atan(x)/x ~ S(0,i)/Q(0,i) for i so that (p/2^r)^i/i is small enough.
77 The factor 2^(r*(b-a)) in Q(a,b) is implicit, thus we have to take it
78 into account when we compute with Q.
80 accu[0] = 0; /* accu[k] = Mult[0] + ... + Mult[k], where Mult[j] is the
81 number of bits of the corresponding term S[j]/Q[j] */
82 if (mpz_cmp_ui (p, 1) != 0)
84 /* p <> 1: precompute ptoj table */
86 for (im = 1 ; im <= m ; im ++)
87 mpz_mul (ptoj[im], ptoj[im - 1], ptoj[im - 1]);
90 /* the ith term being X^i/(2i+1) with X=p/2^r, we can stop when
91 p^i/2^(r*i) < 2^(-precy), i.e. r*i > precy + log2(p^i) */
92 for (i = k = done = 0; (i < n) && (done == 0); i += 2, k ++)
94 /* initialize both S[k],Q[k] and S[k+1],Q[k+1] */
95 mpz_set_ui (Q[k+1], 2 * i + 3); /* Q(i+1,i+2) */
96 mpz_mul_ui (S[k+1], p, 2 * i + 1); /* S(i+1,i+2) */
97 mpz_mul_2exp (S[k], Q[k+1], r);
98 mpz_sub (S[k], S[k], S[k+1]); /* S(i,i+2) */
99 mpz_mul_ui (Q[k], Q[k+1], 2 * i + 1); /* Q(i,i+2) */
100 log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */
101 for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l ++, j >>= 1, k --)
103 /* invariant: S[k-1]/Q[k-1] and S[k]/Q[k] correspond
104 to 2^l terms each. We combine them into S[k-1]/Q[k-1] */
105 MPFR_ASSERTD (k > 0);
106 mpz_mul (S[k], S[k], Q[k-1]);
107 mpz_mul (S[k], S[k], ptoj[l]);
108 mpz_mul (S[k-1], S[k-1], Q[k]);
109 mpz_mul_2exp (S[k-1], S[k-1], r << l);
110 mpz_add (S[k-1], S[k-1], S[k]);
111 mpz_mul (Q[k-1], Q[k-1], Q[k]);
112 log2_nb_terms[k-1] = l + 1;
113 /* now S[k-1]/Q[k-1] corresponds to 2^(l+1) terms */
114 MPFR_MPZ_SIZEINBASE2(mult, ptoj[l+1]);
115 /* FIXME: precompute bits(ptoj[l+1]) outside the loop? */
116 mult = (r << (l + 1)) - mult - 1;
117 accu[k-1] = (k == 1) ? mult : accu[k-2] + mult;
118 if (accu[k-1] > precy)
123 else /* special case p=1: the ith term being X^i/(2i+1) with X=1/2^r,
124 we can stop when r*i > precy i.e. i > precy/r */
127 for (i = k = 0; (i < n) && (i <= precy / r); i += 2, k ++)
129 mpz_set_ui (Q[k + 1], 2 * i + 3);
130 mpz_mul_2exp (S[k], Q[k+1], r);
131 mpz_sub_ui (S[k], S[k], 1 + 2 * i);
132 mpz_mul_ui (Q[k], Q[k + 1], 1 + 2 * i);
133 log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */
134 for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l++, j >>= 1, k --)
136 MPFR_ASSERTD (k > 0);
137 mpz_mul (S[k], S[k], Q[k-1]);
138 mpz_mul (S[k-1], S[k-1], Q[k]);
139 mpz_mul_2exp (S[k-1], S[k-1], r << l);
140 mpz_add (S[k-1], S[k-1], S[k]);
141 mpz_mul (Q[k-1], Q[k-1], Q[k]);
142 log2_nb_terms[k-1] = l + 1;
147 /* we need to combine S[0]/Q[0]...S[k-1]/Q[k-1] */
148 l = 0; /* number of terms accumulated in S[k]/Q[k] */
152 /* combine S[k-1]/Q[k-1] and S[k]/Q[k] */
153 j = log2_nb_terms[k-1];
154 mpz_mul (S[k], S[k], Q[k-1]);
155 if (mpz_cmp_ui (p, 1) != 0)
156 mpz_mul (S[k], S[k], ptoj[j]);
157 mpz_mul (S[k-1], S[k-1], Q[k]);
158 l += 1 << log2_nb_terms[k];
159 mpz_mul_2exp (S[k-1], S[k-1], r * l);
160 mpz_add (S[k-1], S[k-1], S[k]);
161 mpz_mul (Q[k-1], Q[k-1], Q[k]);
163 (*__gmp_free_func) (accu, (2 * m + 2) * sizeof (mp_prec_t));
165 MPFR_MPZ_SIZEINBASE2 (diff, S[0]);
169 mpz_tdiv_q_2exp (S[0], S[0], diff);
171 mpz_mul_2exp (S[0], S[0], -diff);
173 MPFR_MPZ_SIZEINBASE2 (diff, Q[0]);
177 mpz_tdiv_q_2exp (Q[0], Q[0], diff);
179 mpz_mul_2exp (Q[0], Q[0], -diff);
181 mpz_tdiv_q (S[0], S[0], Q[0]);
182 mpfr_set_z (y, S[0], GMP_RNDD);
183 MPFR_SET_EXP (y, MPFR_EXP(y) + expo - r * (i - 1));
187 mpfr_atan (mpfr_ptr atan, mpfr_srcptr x, mp_rnd_t rnd_mode)
189 mpfr_t xp, arctgt, sk, tmp, tmp2;
193 mp_prec_t prec, realprec;
194 unsigned long twopoweri;
195 int comparaison, inexact;
197 MPFR_GROUP_DECL (group);
198 MPFR_SAVE_EXPO_DECL (expo);
199 MPFR_ZIV_DECL (loop);
201 MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", x, x, rnd_mode),
202 ("atan[%#R]=%R inexact=%d", atan, atan, inexact));
205 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
212 else if (MPFR_IS_INF (x))
214 MPFR_SAVE_EXPO_MARK (expo);
215 if (MPFR_IS_POS (x)) /* arctan(+inf) = Pi/2 */
216 inexact = mpfr_const_pi (atan, rnd_mode);
217 else /* arctan(-inf) = -Pi/2 */
219 inexact = -mpfr_const_pi (atan,
220 MPFR_INVERT_RND (rnd_mode));
221 MPFR_CHANGE_SIGN (atan);
223 mpfr_div_2ui (atan, atan, 1, rnd_mode); /* exact (no exceptions) */
224 MPFR_SAVE_EXPO_FREE (expo);
225 return mpfr_check_range (atan, inexact, rnd_mode);
227 else /* x is necessarily 0 */
229 MPFR_ASSERTD (MPFR_IS_ZERO (x));
230 MPFR_SET_ZERO (atan);
231 MPFR_SET_SAME_SIGN (atan, x);
236 /* atan(x) = x - x^3/3 + x^5/5...
237 so the error is < 2^(3*EXP(x)-1)
238 so `EXP(x)-(3*EXP(x)-1)` = -2*EXP(x)+1 */
239 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (atan, x, -2 * MPFR_GET_EXP (x), 1, 0,
243 MPFR_TMP_INIT_ABS (xp, x);
245 MPFR_SAVE_EXPO_MARK (expo);
247 /* Other simple case arctan(-+1)=-+pi/4 */
248 comparaison = mpfr_cmp_ui (xp, 1);
249 if (MPFR_UNLIKELY (comparaison == 0))
251 int neg = MPFR_IS_NEG (x);
252 inexact = mpfr_const_pi (atan, MPFR_IS_POS (x) ? rnd_mode
253 : MPFR_INVERT_RND (rnd_mode));
257 MPFR_CHANGE_SIGN (atan);
259 mpfr_div_2ui (atan, atan, 2, rnd_mode); /* exact (no exceptions) */
260 MPFR_SAVE_EXPO_FREE (expo);
261 return mpfr_check_range (atan, inexact, rnd_mode);
264 realprec = MPFR_PREC (atan) + MPFR_INT_CEIL_LOG2 (MPFR_PREC (atan)) + 4;
265 prec = realprec + BITS_PER_MP_LIMB;
269 MPFR_GROUP_INIT_4 (group, prec, sk, tmp, tmp2, arctgt);
273 MPFR_ZIV_INIT (loop, prec);
276 /* First, if |x| < 1, we need to have more prec to be able to round (sup)
277 n0 = ceil(log(prec_requested + 2 + 1+ln(2.4)/ln(2))/log(2)) */
281 if (MPFR_GET_EXP (xp) < 0
282 && (mpfr_uexp_t) (2-MPFR_GET_EXP (xp)) > realprec)
283 sup = (mpfr_uexp_t) (2-MPFR_GET_EXP (xp)) - realprec;
285 sup = MPFR_GET_EXP (xp) < 0 ? 2-MPFR_GET_EXP (xp) : 1;
287 n0 = MPFR_INT_CEIL_LOG2 ((realprec + sup) + 3);
288 MPFR_ASSERTD (3*n0 > 2);
289 prec = (realprec + sup) + 1 + MPFR_INT_CEIL_LOG2 (3*n0-2);
292 MPFR_GROUP_REPREC_4 (group, prec, sk, tmp, tmp2, arctgt);
293 if (MPFR_LIKELY (oldn0 == 0))
296 tabz = (mpz_t *) (*__gmp_allocate_func) (oldn0*sizeof (mpz_t));
297 for (i = 0; i < oldn0; i++)
300 else if (MPFR_UNLIKELY (oldn0 < 3 * (n0 + 1)))
302 tabz = (mpz_t *) (*__gmp_reallocate_func)
303 (tabz, oldn0*sizeof (mpz_t), 3*(n0+1)*sizeof (mpz_t));
304 for (i = oldn0; i < 3*(n0+1); i++)
310 mpfr_ui_div (sk, 1, xp, GMP_RNDN);
312 mpfr_set (sk, xp, GMP_RNDN);
314 /* sk is 1/|x| if |x| > 1, and |x| otherwise, i.e. min(|x|, 1/|x|) */
316 /* If sk=1, then if |x| < 1, we have 1 - 2^(-prec-1) <= |x| < 1,
317 or if |x| > 1, we have 1 - 2^(-prec-1) <= 1/|x| < 1, thus in all
318 cases ||x| - 1| <= 2^(-prec), from which it follows
319 |atan|x| - Pi/4| <= 2^(-prec), given the Taylor expansion
320 atan(1+x) = Pi/4 + x/2 - x^2/4 + ...
321 Since Pi/4 = 0.785..., the error is at most one ulp.
323 if (MPFR_UNLIKELY(mpfr_cmp_ui (sk, 1) == 0))
325 mpfr_const_pi (arctgt, GMP_RNDN); /* 1/2 ulp extra error */
326 mpfr_div_2ui (arctgt, arctgt, 2, GMP_RNDN); /* exact */
332 MPFR_SET_ZERO (arctgt);
334 MPFR_ASSERTD (n0 >= 4);
335 /* FIXME: further reduce the argument so that it is less than
336 1/n where n is the output precision. In such a way, the
337 first calls to mpfr_atan_aux will not be too expensive,
338 since the number of needed terms will be n/log(n), so the
339 factorial contribution will be O(n). */
340 for (i = 0 ; i < n0; i++)
342 if (MPFR_UNLIKELY (MPFR_IS_ZERO (sk)))
344 /* Calculation of trunc(tmp) --> mpz */
345 mpfr_mul_2ui (tmp, sk, twopoweri, GMP_RNDN);
346 mpfr_trunc (tmp, tmp);
347 if (!MPFR_IS_ZERO (tmp))
349 /* tmp = ukz*2^exptol */
350 exptol = mpfr_get_z_exp (ukz, tmp);
351 /* since the s_k are decreasing (see algorithms.tex),
352 and s_0 = min(|x|, 1/|x|) < 1, we have sk < 1,
354 MPFR_ASSERTD (exptol < 0);
355 mpz_tdiv_q_2exp (ukz, ukz, (unsigned long int) (-exptol));
356 /* since tmp is a non-zero integer, and tmp = ukzold*2^exptol,
357 we now have ukz = tmp, thus ukz is non-zero */
358 /* Calculation of arctan(Ak) */
359 mpfr_set_z (tmp, ukz, GMP_RNDN);
360 mpfr_div_2ui (tmp, tmp, twopoweri, GMP_RNDN);
361 mpfr_atan_aux (tmp2, ukz, twopoweri, n0 - i, tabz);
362 mpfr_mul (tmp2, tmp2, tmp, GMP_RNDN);
364 mpfr_add (arctgt, arctgt, tmp2, GMP_RNDN);
366 mpfr_sub (tmp2, sk, tmp, GMP_RNDN);
367 mpfr_mul (sk, sk, tmp, GMP_RNDN);
368 mpfr_add_ui (sk, sk, 1, GMP_RNDN);
369 mpfr_div (sk, tmp2, sk, GMP_RNDN);
373 /* Add last step (Arctan(sk) ~= sk */
374 mpfr_add (arctgt, arctgt, sk, GMP_RNDN);
377 mpfr_const_pi (tmp, GMP_RNDN);
378 mpfr_div_2ui (tmp, tmp, 1, GMP_RNDN);
379 mpfr_sub (arctgt, tmp, arctgt, GMP_RNDN);
381 MPFR_SET_POS (arctgt);
384 if (MPFR_LIKELY (MPFR_CAN_ROUND (arctgt, realprec, MPFR_PREC (atan),
387 MPFR_ZIV_NEXT (loop, realprec);
389 MPFR_ZIV_FREE (loop);
391 inexact = mpfr_set4 (atan, arctgt, rnd_mode, MPFR_SIGN (x));
393 for (i = 0 ; i < oldn0 ; i++)
396 (*__gmp_free_func) (tabz, oldn0*sizeof (mpz_t));
397 MPFR_GROUP_CLEAR (group);
399 MPFR_SAVE_EXPO_FREE (expo);
400 return mpfr_check_range (arctgt, inexact, rnd_mode);