Annotation of OpenXM_contrib/gmp/mpfr/const_pi.c, Revision 1.1.1.1
1.1 ohara 1: /* mpfr_const_pi -- compute Pi
2:
3: Copyright 1999, 2000, 2001 Free Software Foundation.
4:
5: This file is part of the MPFR Library.
6:
7: The MPFR Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The MPFR Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the MPFR Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include "gmp.h"
25: #include "gmp-impl.h"
26: #include "longlong.h"
27: #include "mpfr.h"
28: #include "mpfr-impl.h"
29:
30: static int mpfr_aux_pi _PROTO ((mpfr_ptr, mpz_srcptr, int, int));
31: static int mpfr_pi_machin3 _PROTO ((mpfr_ptr, mp_rnd_t));
32:
33: #define A
34: #define A1 1
35: #define A2 2
36: #undef B
37: #define C
38: #define C1 3
39: #define C2 2
40: #define GENERIC mpfr_aux_pi
41: #define R_IS_RATIONAL
42: #define NO_FACTORIAL
43: #include "generic.c"
44:
45:
46: static int
47: mpfr_pi_machin3 (mpfr_ptr mylog, mp_rnd_t rnd_mode)
48: {
49: int prec, logn, prec_x;
50: int prec_i_want=MPFR_PREC(mylog);
51: int good = 0;
52: mpfr_t tmp1, tmp2, result,tmp3,tmp4,tmp5,tmp6;
53: mpz_t cst;
54:
55: MPFR_CLEAR_FLAGS(mylog);
56: logn = _mpfr_ceil_log2 ((double) MPFR_PREC(mylog));
57: prec_x = prec_i_want + logn + 5;
58: mpz_init(cst);
59: while (!good){
60: prec = _mpfr_ceil_log2 ((double) prec_x);
61:
62: mpfr_init2(tmp1, prec_x);
63: mpfr_init2(tmp2, prec_x);
64: mpfr_init2(tmp3, prec_x);
65: mpfr_init2(tmp4, prec_x);
66: mpfr_init2(tmp5, prec_x);
67: mpfr_init2(tmp6, prec_x);
68: mpfr_init2(result, prec_x);
69: mpz_set_si(cst, -1);
70:
71: mpfr_aux_pi(tmp1, cst, 268*268, prec - 4);
72: mpfr_div_ui(tmp1, tmp1, 268, GMP_RNDD);
73: mpfr_mul_ui(tmp1, tmp1, 61, GMP_RNDD);
74:
75: mpfr_aux_pi(tmp2, cst, 343*343, prec - 4);
76: mpfr_div_ui(tmp2, tmp2, 343, GMP_RNDD);
77: mpfr_mul_ui(tmp2, tmp2, 122, GMP_RNDD);
78:
79: mpfr_aux_pi(tmp3, cst, 557*557, prec - 4);
80: mpfr_div_ui(tmp3, tmp3, 557, GMP_RNDD);
81: mpfr_mul_ui(tmp3, tmp3, 115, GMP_RNDD);
82:
83: mpfr_aux_pi(tmp4, cst, 1068*1068, prec - 4);
84: mpfr_div_ui(tmp4, tmp4, 1068, GMP_RNDD);
85: mpfr_mul_ui(tmp4, tmp4, 32, GMP_RNDD);
86:
87: mpfr_aux_pi(tmp5, cst, 3458*3458, prec - 4);
88: mpfr_div_ui(tmp5, tmp5, 3458, GMP_RNDD);
89: mpfr_mul_ui(tmp5, tmp5, 83, GMP_RNDD);
90:
91: mpfr_aux_pi(tmp6, cst, 27493*27493, prec - 4);
92: mpfr_div_ui(tmp6, tmp6, 27493, GMP_RNDD);
93: mpfr_mul_ui(tmp6, tmp6, 44, GMP_RNDD);
94:
95: mpfr_add(result, tmp1, tmp2, GMP_RNDD);
96: mpfr_add(result, result, tmp3, GMP_RNDD);
97: mpfr_sub(result, result, tmp4, GMP_RNDD);
98: mpfr_add(result, result, tmp5, GMP_RNDD);
99: mpfr_add(result, result, tmp6, GMP_RNDD);
100: mpfr_mul_2ui(result, result, 2, GMP_RNDD);
101: mpfr_clear(tmp1);
102: mpfr_clear(tmp2);
103: mpfr_clear(tmp3);
104: mpfr_clear(tmp4);
105: mpfr_clear(tmp5);
106: mpfr_clear(tmp6);
107: if (mpfr_can_round(result, prec_x - 5, GMP_RNDD, rnd_mode, prec_i_want)){
108: mpfr_set(mylog, result, rnd_mode);
109: mpfr_clear(result);
110: good = 1;
111: } else
112: {
113: mpfr_clear(result);
114: prec_x += logn;
115: }
116: }
117: mpz_clear(cst);
118: return 0;
119: }
120:
121: /*
122: Set x to the value of Pi to precision MPFR_PREC(x) rounded to direction rnd_mode.
123: Use the formula giving the binary representation of Pi found by Simon Plouffe
124: and the Borwein's brothers:
125:
126: infinity 4 2 1 1
127: ----- ------- - ------- - ------- - -------
128: \ 8 n + 1 8 n + 4 8 n + 5 8 n + 6
129: Pi = ) -------------------------------------
130: / n
131: ----- 16
132: n = 0
133:
134: i.e. Pi*16^N = S(N) + R(N) where
135: S(N) = sum(16^(N-n)*(4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6)), n=0..N-1)
136: R(N) = sum((4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6))/16^(n-N), n=N..infinity)
137:
138: Let f(n) = 4/(8*n+1)-2/(8*n+4)-1/(8*n+5)-1/(8*n+6), we can show easily that
139: f(n) < 15/(64*n^2), so R(N) < sum(15/(64*n^2)/16^(n-N), n=N..infinity)
140: < 15/64/N^2*sum(1/16^(n-N), n=N..infinity)
141: = 1/4/N^2
142:
143: Now let S'(N) = sum(floor(16^(N-n)*(120*n^2+151*n+47),
144: (512*n^4+1024*n^3+712*n^2+194*n+15)), n=0..N-1)
145:
146: S(N)-S'(N) <= sum(1, n=0..N-1) = N
147:
148: so Pi*16^N-S'(N) <= N+1 (as 1/4/N^2 < 1)
149: */
150:
151: mpfr_t __mpfr_const_pi; /* stored value of Pi */
152: int __mpfr_const_pi_prec=0; /* precision of stored value */
153: mp_rnd_t __mpfr_const_pi_rnd; /* rounding mode of stored value */
154:
155: void
156: mpfr_const_pi (mpfr_ptr x, mp_rnd_t rnd_mode)
157: {
158: int N, oldN, n, prec; mpz_t pi, num, den, d3, d2, tmp; mpfr_t y;
159:
160: prec=MPFR_PREC(x);
161:
162: /* has stored value enough precision ? */
163: if ((prec==__mpfr_const_pi_prec && rnd_mode==__mpfr_const_pi_rnd) ||
164: (prec<=__mpfr_const_pi_prec &&
165: mpfr_can_round(__mpfr_const_pi, __mpfr_const_pi_prec,
166: __mpfr_const_pi_rnd, rnd_mode, prec)))
167: {
168: mpfr_set(x, __mpfr_const_pi, rnd_mode); return;
169: }
170:
171: if (prec < 20000){
172: /* need to recompute */
173: N=1;
174: do {
175: oldN = N;
176: N = (prec+3)/4 + _mpfr_ceil_log2((double) N + 1.0);
177: } while (N != oldN);
178: mpz_init(pi); mpz_init(num); mpz_init(den); mpz_init(d3); mpz_init(d2);
179: mpz_init(tmp);
180: mpz_set_ui(pi, 0);
181: mpz_set_ui(num, 16); /* num(-1) */
182: mpz_set_ui(den, 21); /* den(-1) */
183: mpz_set_si(d3, -2454);
184: mpz_set_ui(d2, 14736);
185: /* invariants: num=120*n^2+151*n+47, den=512*n^4+1024*n^3+712*n^2+194*n+15
186: d3 = 2048*n^3+400*n-6, d2 = 6144*n^2-6144*n+2448
187: */
188: for (n=0; n<N; n++) {
189: /* num(n)-num(n-1) = 240*n+31 */
190: mpz_add_ui(num, num, 240*n+31); /* no overflow up to MPFR_PREC=71M */
191: /* d2(n) - d2(n-1) = 12288*(n-1) */
192: if (n>0) mpz_add_ui(d2, d2, 12288*(n-1));
193: else mpz_sub_ui(d2, d2, 12288);
194: /* d3(n) - d3(n-1) = d2 */
195: mpz_add(d3, d3, d2);
196: /* den(n)-den(n-1) = 2048*n^3 + 400n - 6 = d3 */
197: mpz_add(den, den, d3);
198: mpz_mul_2exp(tmp, num, 4*(N-n));
199: mpz_fdiv_q(tmp, tmp, den);
200: mpz_add(pi, pi, tmp);
201: }
202: mpfr_set_z(x, pi, rnd_mode);
203: mpfr_init2(y, mpfr_get_prec(x));
204: mpz_add_ui(pi, pi, N+1);
205: mpfr_set_z(y, pi, rnd_mode);
206: if (mpfr_cmp(x, y) != 0) {
207: fprintf(stderr, "does not converge\n"); exit(1);
208: }
209: MPFR_EXP(x) -= 4*N;
210: mpz_clear(pi); mpz_clear(num); mpz_clear(den); mpz_clear(d3); mpz_clear(d2);
211: mpz_clear(tmp); mpfr_clear(y);
212: } else
213: mpfr_pi_machin3(x, rnd_mode);
214: /* store computed value */
215: if (__mpfr_const_pi_prec==0) mpfr_init2(__mpfr_const_pi, prec);
216: else mpfr_set_prec(__mpfr_const_pi, prec);
217: mpfr_set(__mpfr_const_pi, x, rnd_mode);
218: __mpfr_const_pi_prec=prec;
219: __mpfr_const_pi_rnd=rnd_mode;
220: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>