shomez commited on
Commit
db5b401
·
verified ·
1 Parent(s): 4de5125

Upload gammazeta.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. gammazeta.py +2167 -0
gammazeta.py ADDED
@@ -0,0 +1,2167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ -----------------------------------------------------------------------
3
+ This module implements gamma- and zeta-related functions:
4
+
5
+ * Bernoulli numbers
6
+ * Factorials
7
+ * The gamma function
8
+ * Polygamma functions
9
+ * Harmonic numbers
10
+ * The Riemann zeta function
11
+ * Constants related to these functions
12
+
13
+ -----------------------------------------------------------------------
14
+ """
15
+
16
+ import math
17
+ import sys
18
+
19
+ from .backend import xrange
20
+ from .backend import MPZ, MPZ_ZERO, MPZ_ONE, MPZ_THREE, gmpy
21
+
22
+ from .libintmath import list_primes, ifac, ifac2, moebius
23
+
24
+ from .libmpf import (\
25
+ round_floor, round_ceiling, round_down, round_up,
26
+ round_nearest, round_fast,
27
+ lshift, sqrt_fixed, isqrt_fast,
28
+ fzero, fone, fnone, fhalf, ftwo, finf, fninf, fnan,
29
+ from_int, to_int, to_fixed, from_man_exp, from_rational,
30
+ mpf_pos, mpf_neg, mpf_abs, mpf_add, mpf_sub,
31
+ mpf_mul, mpf_mul_int, mpf_div, mpf_sqrt, mpf_pow_int,
32
+ mpf_rdiv_int,
33
+ mpf_perturb, mpf_le, mpf_lt, mpf_gt, mpf_shift,
34
+ negative_rnd, reciprocal_rnd,
35
+ bitcount, to_float, mpf_floor, mpf_sign, ComplexResult
36
+ )
37
+
38
+ from .libelefun import (\
39
+ constant_memo,
40
+ def_mpf_constant,
41
+ mpf_pi, pi_fixed, ln2_fixed, log_int_fixed, mpf_ln2,
42
+ mpf_exp, mpf_log, mpf_pow, mpf_cosh,
43
+ mpf_cos_sin, mpf_cosh_sinh, mpf_cos_sin_pi, mpf_cos_pi, mpf_sin_pi,
44
+ ln_sqrt2pi_fixed, mpf_ln_sqrt2pi, sqrtpi_fixed, mpf_sqrtpi,
45
+ cos_sin_fixed, exp_fixed
46
+ )
47
+
48
+ from .libmpc import (\
49
+ mpc_zero, mpc_one, mpc_half, mpc_two,
50
+ mpc_abs, mpc_shift, mpc_pos, mpc_neg,
51
+ mpc_add, mpc_sub, mpc_mul, mpc_div,
52
+ mpc_add_mpf, mpc_mul_mpf, mpc_div_mpf, mpc_mpf_div,
53
+ mpc_mul_int, mpc_pow_int,
54
+ mpc_log, mpc_exp, mpc_pow,
55
+ mpc_cos_pi, mpc_sin_pi,
56
+ mpc_reciprocal, mpc_square,
57
+ mpc_sub_mpf
58
+ )
59
+
60
+
61
+
62
+ # Catalan's constant is computed using Lupas's rapidly convergent series
63
+ # (listed on http://mathworld.wolfram.com/CatalansConstant.html)
64
+ # oo
65
+ # ___ n-1 8n 2 3 2
66
+ # 1 \ (-1) 2 (40n - 24n + 3) [(2n)!] (n!)
67
+ # K = --- ) -----------------------------------------
68
+ # 64 /___ 3 2
69
+ # n (2n-1) [(4n)!]
70
+ # n = 1
71
+
72
+ @constant_memo
73
+ def catalan_fixed(prec):
74
+ prec = prec + 20
75
+ a = one = MPZ_ONE << prec
76
+ s, t, n = 0, 1, 1
77
+ while t:
78
+ a *= 32 * n**3 * (2*n-1)
79
+ a //= (3-16*n+16*n**2)**2
80
+ t = a * (-1)**(n-1) * (40*n**2-24*n+3) // (n**3 * (2*n-1))
81
+ s += t
82
+ n += 1
83
+ return s >> (20 + 6)
84
+
85
+ # Khinchin's constant is relatively difficult to compute. Here
86
+ # we use the rational zeta series
87
+
88
+ # oo 2*n-1
89
+ # ___ ___
90
+ # \ ` zeta(2*n)-1 \ ` (-1)^(k+1)
91
+ # log(K)*log(2) = ) ------------ ) ----------
92
+ # /___. n /___. k
93
+ # n = 1 k = 1
94
+
95
+ # which adds half a digit per term. The essential trick for achieving
96
+ # reasonable efficiency is to recycle both the values of the zeta
97
+ # function (essentially Bernoulli numbers) and the partial terms of
98
+ # the inner sum.
99
+
100
+ # An alternative might be to use K = 2*exp[1/log(2) X] where
101
+
102
+ # / 1 1 [ pi*x*(1-x^2) ]
103
+ # X = | ------ log [ ------------ ].
104
+ # / 0 x(1+x) [ sin(pi*x) ]
105
+
106
+ # and integrate numerically. In practice, this seems to be slightly
107
+ # slower than the zeta series at high precision.
108
+
109
+ @constant_memo
110
+ def khinchin_fixed(prec):
111
+ wp = int(prec + prec**0.5 + 15)
112
+ s = MPZ_ZERO
113
+ fac = from_int(4)
114
+ t = ONE = MPZ_ONE << wp
115
+ pi = mpf_pi(wp)
116
+ pipow = twopi2 = mpf_shift(mpf_mul(pi, pi, wp), 2)
117
+ n = 1
118
+ while 1:
119
+ zeta2n = mpf_abs(mpf_bernoulli(2*n, wp))
120
+ zeta2n = mpf_mul(zeta2n, pipow, wp)
121
+ zeta2n = mpf_div(zeta2n, fac, wp)
122
+ zeta2n = to_fixed(zeta2n, wp)
123
+ term = (((zeta2n - ONE) * t) // n) >> wp
124
+ if term < 100:
125
+ break
126
+ #if not n % 10:
127
+ # print n, math.log(int(abs(term)))
128
+ s += term
129
+ t += ONE//(2*n+1) - ONE//(2*n)
130
+ n += 1
131
+ fac = mpf_mul_int(fac, (2*n)*(2*n-1), wp)
132
+ pipow = mpf_mul(pipow, twopi2, wp)
133
+ s = (s << wp) // ln2_fixed(wp)
134
+ K = mpf_exp(from_man_exp(s, -wp), wp)
135
+ K = to_fixed(K, prec)
136
+ return K
137
+
138
+
139
+ # Glaisher's constant is defined as A = exp(1/2 - zeta'(-1)).
140
+ # One way to compute it would be to perform direct numerical
141
+ # differentiation, but computing arbitrary Riemann zeta function
142
+ # values at high precision is expensive. We instead use the formula
143
+
144
+ # A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12)
145
+
146
+ # and compute zeta'(2) from the series representation
147
+
148
+ # oo
149
+ # ___
150
+ # \ log k
151
+ # -zeta'(2) = ) -----
152
+ # /___ 2
153
+ # k
154
+ # k = 2
155
+
156
+ # This series converges exceptionally slowly, but can be accelerated
157
+ # using Euler-Maclaurin formula. The important insight is that the
158
+ # E-M integral can be done in closed form and that the high order
159
+ # are given by
160
+
161
+ # n / \
162
+ # d | log x | a + b log x
163
+ # --- | ----- | = -----------
164
+ # n | 2 | 2 + n
165
+ # dx \ x / x
166
+
167
+ # where a and b are integers given by a simple recurrence. Note
168
+ # that just one logarithm is needed. However, lots of integer
169
+ # logarithms are required for the initial summation.
170
+
171
+ # This algorithm could possibly be turned into a faster algorithm
172
+ # for general evaluation of zeta(s) or zeta'(s); this should be
173
+ # looked into.
174
+
175
+ @constant_memo
176
+ def glaisher_fixed(prec):
177
+ wp = prec + 30
178
+ # Number of direct terms to sum before applying the Euler-Maclaurin
179
+ # formula to the tail. TODO: choose more intelligently
180
+ N = int(0.33*prec + 5)
181
+ ONE = MPZ_ONE << wp
182
+ # Euler-Maclaurin, step 1: sum log(k)/k**2 for k from 2 to N-1
183
+ s = MPZ_ZERO
184
+ for k in range(2, N):
185
+ #print k, N
186
+ s += log_int_fixed(k, wp) // k**2
187
+ logN = log_int_fixed(N, wp)
188
+ #logN = to_fixed(mpf_log(from_int(N), wp+20), wp)
189
+ # E-M step 2: integral of log(x)/x**2 from N to inf
190
+ s += (ONE + logN) // N
191
+ # E-M step 3: endpoint correction term f(N)/2
192
+ s += logN // (N**2 * 2)
193
+ # E-M step 4: the series of derivatives
194
+ pN = N**3
195
+ a = 1
196
+ b = -2
197
+ j = 3
198
+ fac = from_int(2)
199
+ k = 1
200
+ while 1:
201
+ # D(2*k-1) * B(2*k) / fac(2*k) [D(n) = nth derivative]
202
+ D = ((a << wp) + b*logN) // pN
203
+ D = from_man_exp(D, -wp)
204
+ B = mpf_bernoulli(2*k, wp)
205
+ term = mpf_mul(B, D, wp)
206
+ term = mpf_div(term, fac, wp)
207
+ term = to_fixed(term, wp)
208
+ if abs(term) < 100:
209
+ break
210
+ #if not k % 10:
211
+ # print k, math.log(int(abs(term)), 10)
212
+ s -= term
213
+ # Advance derivative twice
214
+ a, b, pN, j = b-a*j, -j*b, pN*N, j+1
215
+ a, b, pN, j = b-a*j, -j*b, pN*N, j+1
216
+ k += 1
217
+ fac = mpf_mul_int(fac, (2*k)*(2*k-1), wp)
218
+ # A = exp((6*s/pi**2 + log(2*pi) + euler)/12)
219
+ pi = pi_fixed(wp)
220
+ s *= 6
221
+ s = (s << wp) // (pi**2 >> wp)
222
+ s += euler_fixed(wp)
223
+ s += to_fixed(mpf_log(from_man_exp(2*pi, -wp), wp), wp)
224
+ s //= 12
225
+ A = mpf_exp(from_man_exp(s, -wp), wp)
226
+ return to_fixed(A, prec)
227
+
228
+ # Apery's constant can be computed using the very rapidly convergent
229
+ # series
230
+ # oo
231
+ # ___ 2 10
232
+ # \ n 205 n + 250 n + 77 (n!)
233
+ # zeta(3) = ) (-1) ------------------- ----------
234
+ # /___ 64 5
235
+ # n = 0 ((2n+1)!)
236
+
237
+ @constant_memo
238
+ def apery_fixed(prec):
239
+ prec += 20
240
+ d = MPZ_ONE << prec
241
+ term = MPZ(77) << prec
242
+ n = 1
243
+ s = MPZ_ZERO
244
+ while term:
245
+ s += term
246
+ d *= (n**10)
247
+ d //= (((2*n+1)**5) * (2*n)**5)
248
+ term = (-1)**n * (205*(n**2) + 250*n + 77) * d
249
+ n += 1
250
+ return s >> (20 + 6)
251
+
252
+ """
253
+ Euler's constant (gamma) is computed using the Brent-McMillan formula,
254
+ gamma ~= I(n)/J(n) - log(n), where
255
+
256
+ I(n) = sum_{k=0,1,2,...} (n**k / k!)**2 * H(k)
257
+ J(n) = sum_{k=0,1,2,...} (n**k / k!)**2
258
+ H(k) = 1 + 1/2 + 1/3 + ... + 1/k
259
+
260
+ The error is bounded by O(exp(-4n)). Choosing n to be a power
261
+ of two, 2**p, the logarithm becomes particularly easy to calculate.[1]
262
+
263
+ We use the formulation of Algorithm 3.9 in [2] to make the summation
264
+ more efficient.
265
+
266
+ Reference:
267
+ [1] Xavier Gourdon & Pascal Sebah, The Euler constant: gamma
268
+ http://numbers.computation.free.fr/Constants/Gamma/gamma.pdf
269
+
270
+ [2] [BorweinBailey]_
271
+ """
272
+
273
+ @constant_memo
274
+ def euler_fixed(prec):
275
+ extra = 30
276
+ prec += extra
277
+ # choose p such that exp(-4*(2**p)) < 2**-n
278
+ p = int(math.log((prec/4) * math.log(2), 2)) + 1
279
+ n = 2**p
280
+ A = U = -p*ln2_fixed(prec)
281
+ B = V = MPZ_ONE << prec
282
+ k = 1
283
+ while 1:
284
+ B = B*n**2//k**2
285
+ A = (A*n**2//k + B)//k
286
+ U += A
287
+ V += B
288
+ if max(abs(A), abs(B)) < 100:
289
+ break
290
+ k += 1
291
+ return (U<<(prec-extra))//V
292
+
293
+ # Use zeta accelerated formulas for the Mertens and twin
294
+ # prime constants; see
295
+ # http://mathworld.wolfram.com/MertensConstant.html
296
+ # http://mathworld.wolfram.com/TwinPrimesConstant.html
297
+
298
+ @constant_memo
299
+ def mertens_fixed(prec):
300
+ wp = prec + 20
301
+ m = 2
302
+ s = mpf_euler(wp)
303
+ while 1:
304
+ t = mpf_zeta_int(m, wp)
305
+ if t == fone:
306
+ break
307
+ t = mpf_log(t, wp)
308
+ t = mpf_mul_int(t, moebius(m), wp)
309
+ t = mpf_div(t, from_int(m), wp)
310
+ s = mpf_add(s, t)
311
+ m += 1
312
+ return to_fixed(s, prec)
313
+
314
+ @constant_memo
315
+ def twinprime_fixed(prec):
316
+ def I(n):
317
+ return sum(moebius(d)<<(n//d) for d in xrange(1,n+1) if not n%d)//n
318
+ wp = 2*prec + 30
319
+ res = fone
320
+ primes = [from_rational(1,p,wp) for p in [2,3,5,7]]
321
+ ppowers = [mpf_mul(p,p,wp) for p in primes]
322
+ n = 2
323
+ while 1:
324
+ a = mpf_zeta_int(n, wp)
325
+ for i in range(4):
326
+ a = mpf_mul(a, mpf_sub(fone, ppowers[i]), wp)
327
+ ppowers[i] = mpf_mul(ppowers[i], primes[i], wp)
328
+ a = mpf_pow_int(a, -I(n), wp)
329
+ if mpf_pos(a, prec+10, 'n') == fone:
330
+ break
331
+ #from libmpf import to_str
332
+ #print n, to_str(mpf_sub(fone, a), 6)
333
+ res = mpf_mul(res, a, wp)
334
+ n += 1
335
+ res = mpf_mul(res, from_int(3*15*35), wp)
336
+ res = mpf_div(res, from_int(4*16*36), wp)
337
+ return to_fixed(res, prec)
338
+
339
+
340
+ mpf_euler = def_mpf_constant(euler_fixed)
341
+ mpf_apery = def_mpf_constant(apery_fixed)
342
+ mpf_khinchin = def_mpf_constant(khinchin_fixed)
343
+ mpf_glaisher = def_mpf_constant(glaisher_fixed)
344
+ mpf_catalan = def_mpf_constant(catalan_fixed)
345
+ mpf_mertens = def_mpf_constant(mertens_fixed)
346
+ mpf_twinprime = def_mpf_constant(twinprime_fixed)
347
+
348
+
349
+ #-----------------------------------------------------------------------#
350
+ # #
351
+ # Bernoulli numbers #
352
+ # #
353
+ #-----------------------------------------------------------------------#
354
+
355
+ MAX_BERNOULLI_CACHE = 3000
356
+
357
+
358
+ r"""
359
+ Small Bernoulli numbers and factorials are used in numerous summations,
360
+ so it is critical for speed that sequential computation is fast and that
361
+ values are cached up to a fairly high threshold.
362
+
363
+ On the other hand, we also want to support fast computation of isolated
364
+ large numbers. Currently, no such acceleration is provided for integer
365
+ factorials (though it is for large floating-point factorials, which are
366
+ computed via gamma if the precision is low enough).
367
+
368
+ For sequential computation of Bernoulli numbers, we use Ramanujan's formula
369
+
370
+ / n + 3 \
371
+ B = (A(n) - S(n)) / | |
372
+ n \ n /
373
+
374
+ where A(n) = (n+3)/3 when n = 0 or 2 (mod 6), A(n) = -(n+3)/6
375
+ when n = 4 (mod 6), and
376
+
377
+ [n/6]
378
+ ___
379
+ \ / n + 3 \
380
+ S(n) = ) | | * B
381
+ /___ \ n - 6*k / n-6*k
382
+ k = 1
383
+
384
+ For isolated large Bernoulli numbers, we use the Riemann zeta function
385
+ to calculate a numerical value for B_n. The von Staudt-Clausen theorem
386
+ can then be used to optionally find the exact value of the
387
+ numerator and denominator.
388
+ """
389
+
390
+ bernoulli_cache = {}
391
+ f3 = from_int(3)
392
+ f6 = from_int(6)
393
+
394
+ def bernoulli_size(n):
395
+ """Accurately estimate the size of B_n (even n > 2 only)"""
396
+ lgn = math.log(n,2)
397
+ return int(2.326 + 0.5*lgn + n*(lgn - 4.094))
398
+
399
+ BERNOULLI_PREC_CUTOFF = bernoulli_size(MAX_BERNOULLI_CACHE)
400
+
401
+ def mpf_bernoulli(n, prec, rnd=None):
402
+ """Computation of Bernoulli numbers (numerically)"""
403
+ if n < 2:
404
+ if n < 0:
405
+ raise ValueError("Bernoulli numbers only defined for n >= 0")
406
+ if n == 0:
407
+ return fone
408
+ if n == 1:
409
+ return mpf_neg(fhalf)
410
+ # For odd n > 1, the Bernoulli numbers are zero
411
+ if n & 1:
412
+ return fzero
413
+ # If precision is extremely high, we can save time by computing
414
+ # the Bernoulli number at a lower precision that is sufficient to
415
+ # obtain the exact fraction, round to the exact fraction, and
416
+ # convert the fraction back to an mpf value at the original precision
417
+ if prec > BERNOULLI_PREC_CUTOFF and prec > bernoulli_size(n)*1.1 + 1000:
418
+ p, q = bernfrac(n)
419
+ return from_rational(p, q, prec, rnd or round_floor)
420
+ if n > MAX_BERNOULLI_CACHE:
421
+ return mpf_bernoulli_huge(n, prec, rnd)
422
+ wp = prec + 30
423
+ # Reuse nearby precisions
424
+ wp += 32 - (prec & 31)
425
+ cached = bernoulli_cache.get(wp)
426
+ if cached:
427
+ numbers, state = cached
428
+ if n in numbers:
429
+ if not rnd:
430
+ return numbers[n]
431
+ return mpf_pos(numbers[n], prec, rnd)
432
+ m, bin, bin1 = state
433
+ if n - m > 10:
434
+ return mpf_bernoulli_huge(n, prec, rnd)
435
+ else:
436
+ if n > 10:
437
+ return mpf_bernoulli_huge(n, prec, rnd)
438
+ numbers = {0:fone}
439
+ m, bin, bin1 = state = [2, MPZ(10), MPZ_ONE]
440
+ bernoulli_cache[wp] = (numbers, state)
441
+ while m <= n:
442
+ #print m
443
+ case = m % 6
444
+ # Accurately estimate size of B_m so we can use
445
+ # fixed point math without using too much precision
446
+ szbm = bernoulli_size(m)
447
+ s = 0
448
+ sexp = max(0, szbm) - wp
449
+ if m < 6:
450
+ a = MPZ_ZERO
451
+ else:
452
+ a = bin1
453
+ for j in xrange(1, m//6+1):
454
+ usign, uman, uexp, ubc = u = numbers[m-6*j]
455
+ if usign:
456
+ uman = -uman
457
+ s += lshift(a*uman, uexp-sexp)
458
+ # Update inner binomial coefficient
459
+ j6 = 6*j
460
+ a *= ((m-5-j6)*(m-4-j6)*(m-3-j6)*(m-2-j6)*(m-1-j6)*(m-j6))
461
+ a //= ((4+j6)*(5+j6)*(6+j6)*(7+j6)*(8+j6)*(9+j6))
462
+ if case == 0: b = mpf_rdiv_int(m+3, f3, wp)
463
+ if case == 2: b = mpf_rdiv_int(m+3, f3, wp)
464
+ if case == 4: b = mpf_rdiv_int(-m-3, f6, wp)
465
+ s = from_man_exp(s, sexp, wp)
466
+ b = mpf_div(mpf_sub(b, s, wp), from_int(bin), wp)
467
+ numbers[m] = b
468
+ m += 2
469
+ # Update outer binomial coefficient
470
+ bin = bin * ((m+2)*(m+3)) // (m*(m-1))
471
+ if m > 6:
472
+ bin1 = bin1 * ((2+m)*(3+m)) // ((m-7)*(m-6))
473
+ state[:] = [m, bin, bin1]
474
+ return numbers[n]
475
+
476
+ def mpf_bernoulli_huge(n, prec, rnd=None):
477
+ wp = prec + 10
478
+ piprec = wp + int(math.log(n,2))
479
+ v = mpf_gamma_int(n+1, wp)
480
+ v = mpf_mul(v, mpf_zeta_int(n, wp), wp)
481
+ v = mpf_mul(v, mpf_pow_int(mpf_pi(piprec), -n, wp))
482
+ v = mpf_shift(v, 1-n)
483
+ if not n & 3:
484
+ v = mpf_neg(v)
485
+ return mpf_pos(v, prec, rnd or round_fast)
486
+
487
+ def bernfrac(n):
488
+ r"""
489
+ Returns a tuple of integers `(p, q)` such that `p/q = B_n` exactly,
490
+ where `B_n` denotes the `n`-th Bernoulli number. The fraction is
491
+ always reduced to lowest terms. Note that for `n > 1` and `n` odd,
492
+ `B_n = 0`, and `(0, 1)` is returned.
493
+
494
+ **Examples**
495
+
496
+ The first few Bernoulli numbers are exactly::
497
+
498
+ >>> from mpmath import *
499
+ >>> for n in range(15):
500
+ ... p, q = bernfrac(n)
501
+ ... print("%s %s/%s" % (n, p, q))
502
+ ...
503
+ 0 1/1
504
+ 1 -1/2
505
+ 2 1/6
506
+ 3 0/1
507
+ 4 -1/30
508
+ 5 0/1
509
+ 6 1/42
510
+ 7 0/1
511
+ 8 -1/30
512
+ 9 0/1
513
+ 10 5/66
514
+ 11 0/1
515
+ 12 -691/2730
516
+ 13 0/1
517
+ 14 7/6
518
+
519
+ This function works for arbitrarily large `n`::
520
+
521
+ >>> p, q = bernfrac(10**4)
522
+ >>> print(q)
523
+ 2338224387510
524
+ >>> print(len(str(p)))
525
+ 27692
526
+ >>> mp.dps = 15
527
+ >>> print(mpf(p) / q)
528
+ -9.04942396360948e+27677
529
+ >>> print(bernoulli(10**4))
530
+ -9.04942396360948e+27677
531
+
532
+ .. note ::
533
+
534
+ :func:`~mpmath.bernoulli` computes a floating-point approximation
535
+ directly, without computing the exact fraction first.
536
+ This is much faster for large `n`.
537
+
538
+ **Algorithm**
539
+
540
+ :func:`~mpmath.bernfrac` works by computing the value of `B_n` numerically
541
+ and then using the von Staudt-Clausen theorem [1] to reconstruct
542
+ the exact fraction. For large `n`, this is significantly faster than
543
+ computing `B_1, B_2, \ldots, B_2` recursively with exact arithmetic.
544
+ The implementation has been tested for `n = 10^m` up to `m = 6`.
545
+
546
+ In practice, :func:`~mpmath.bernfrac` appears to be about three times
547
+ slower than the specialized program calcbn.exe [2]
548
+
549
+ **References**
550
+
551
+ 1. MathWorld, von Staudt-Clausen Theorem:
552
+ http://mathworld.wolfram.com/vonStaudt-ClausenTheorem.html
553
+
554
+ 2. The Bernoulli Number Page:
555
+ http://www.bernoulli.org/
556
+
557
+ """
558
+ n = int(n)
559
+ if n < 3:
560
+ return [(1, 1), (-1, 2), (1, 6)][n]
561
+ if n & 1:
562
+ return (0, 1)
563
+ q = 1
564
+ for k in list_primes(n+1):
565
+ if not (n % (k-1)):
566
+ q *= k
567
+ prec = bernoulli_size(n) + int(math.log(q,2)) + 20
568
+ b = mpf_bernoulli(n, prec)
569
+ p = mpf_mul(b, from_int(q))
570
+ pint = to_int(p, round_nearest)
571
+ return (pint, q)
572
+
573
+
574
+ #-----------------------------------------------------------------------#
575
+ # #
576
+ # Polygamma functions #
577
+ # #
578
+ #-----------------------------------------------------------------------#
579
+
580
+ r"""
581
+ For all polygamma (psi) functions, we use the Euler-Maclaurin summation
582
+ formula. It looks slightly different in the m = 0 and m > 0 cases.
583
+
584
+ For m = 0, we have
585
+ oo
586
+ ___ B
587
+ (0) 1 \ 2 k -2 k
588
+ psi (z) ~ log z + --- - ) ------ z
589
+ 2 z /___ (2 k)!
590
+ k = 1
591
+
592
+ Experiment shows that the minimum term of the asymptotic series
593
+ reaches 2^(-p) when Re(z) > 0.11*p. So we simply use the recurrence
594
+ for psi (equivalent, in fact, to summing to the first few terms
595
+ directly before applying E-M) to obtain z large enough.
596
+
597
+ Since, very crudely, log z ~= 1 for Re(z) > 1, we can use
598
+ fixed-point arithmetic (if z is extremely large, log(z) itself
599
+ is a sufficient approximation, so we can stop there already).
600
+
601
+ For Re(z) << 0, we could use recurrence, but this is of course
602
+ inefficient for large negative z, so there we use the
603
+ reflection formula instead.
604
+
605
+ For m > 0, we have
606
+
607
+ N - 1
608
+ ___
609
+ ~~~(m) [ \ 1 ] 1 1
610
+ psi (z) ~ [ ) -------- ] + ---------- + -------- +
611
+ [ /___ m+1 ] m+1 m
612
+ k = 1 (z+k) ] 2 (z+N) m (z+N)
613
+
614
+ oo
615
+ ___ B
616
+ \ 2 k (m+1) (m+2) ... (m+2k-1)
617
+ + ) ------ ------------------------
618
+ /___ (2 k)! m + 2 k
619
+ k = 1 (z+N)
620
+
621
+ where ~~~ denotes the function rescaled by 1/((-1)^(m+1) m!).
622
+
623
+ Here again N is chosen to make z+N large enough for the minimum
624
+ term in the last series to become smaller than eps.
625
+
626
+ TODO: the current estimation of N for m > 0 is *very suboptimal*.
627
+
628
+ TODO: implement the reflection formula for m > 0, Re(z) << 0.
629
+ It is generally a combination of multiple cotangents. Need to
630
+ figure out a reasonably simple way to generate these formulas
631
+ on the fly.
632
+
633
+ TODO: maybe use exact algorithms to compute psi for integral
634
+ and certain rational arguments, as this can be much more
635
+ efficient. (On the other hand, the availability of these
636
+ special values provides a convenient way to test the general
637
+ algorithm.)
638
+ """
639
+
640
+ # Harmonic numbers are just shifted digamma functions
641
+ # We should calculate these exactly when x is an integer
642
+ # and when doing so is faster.
643
+
644
+ def mpf_harmonic(x, prec, rnd):
645
+ if x in (fzero, fnan, finf):
646
+ return x
647
+ a = mpf_psi0(mpf_add(fone, x, prec+5), prec)
648
+ return mpf_add(a, mpf_euler(prec+5, rnd), prec, rnd)
649
+
650
+ def mpc_harmonic(z, prec, rnd):
651
+ if z[1] == fzero:
652
+ return (mpf_harmonic(z[0], prec, rnd), fzero)
653
+ a = mpc_psi0(mpc_add_mpf(z, fone, prec+5), prec)
654
+ return mpc_add_mpf(a, mpf_euler(prec+5, rnd), prec, rnd)
655
+
656
+ def mpf_psi0(x, prec, rnd=round_fast):
657
+ """
658
+ Computation of the digamma function (psi function of order 0)
659
+ of a real argument.
660
+ """
661
+ sign, man, exp, bc = x
662
+ wp = prec + 10
663
+ if not man:
664
+ if x == finf: return x
665
+ if x == fninf or x == fnan: return fnan
666
+ if x == fzero or (exp >= 0 and sign):
667
+ raise ValueError("polygamma pole")
668
+ # Near 0 -- fixed-point arithmetic becomes bad
669
+ if exp+bc < -5:
670
+ v = mpf_psi0(mpf_add(x, fone, prec, rnd), prec, rnd)
671
+ return mpf_sub(v, mpf_div(fone, x, wp, rnd), prec, rnd)
672
+ # Reflection formula
673
+ if sign and exp+bc > 3:
674
+ c, s = mpf_cos_sin_pi(x, wp)
675
+ q = mpf_mul(mpf_div(c, s, wp), mpf_pi(wp), wp)
676
+ p = mpf_psi0(mpf_sub(fone, x, wp), wp)
677
+ return mpf_sub(p, q, prec, rnd)
678
+ # The logarithmic term is accurate enough
679
+ if (not sign) and bc + exp > wp:
680
+ return mpf_log(mpf_sub(x, fone, wp), prec, rnd)
681
+ # Initial recurrence to obtain a large enough x
682
+ m = to_int(x)
683
+ n = int(0.11*wp) + 2
684
+ s = MPZ_ZERO
685
+ x = to_fixed(x, wp)
686
+ one = MPZ_ONE << wp
687
+ if m < n:
688
+ for k in xrange(m, n):
689
+ s -= (one << wp) // x
690
+ x += one
691
+ x -= one
692
+ # Logarithmic term
693
+ s += to_fixed(mpf_log(from_man_exp(x, -wp, wp), wp), wp)
694
+ # Endpoint term in Euler-Maclaurin expansion
695
+ s += (one << wp) // (2*x)
696
+ # Euler-Maclaurin remainder sum
697
+ x2 = (x*x) >> wp
698
+ t = one
699
+ prev = 0
700
+ k = 1
701
+ while 1:
702
+ t = (t*x2) >> wp
703
+ bsign, bman, bexp, bbc = mpf_bernoulli(2*k, wp)
704
+ offset = (bexp + 2*wp)
705
+ if offset >= 0: term = (bman << offset) // (t*(2*k))
706
+ else: term = (bman >> (-offset)) // (t*(2*k))
707
+ if k & 1: s -= term
708
+ else: s += term
709
+ if k > 2 and term >= prev:
710
+ break
711
+ prev = term
712
+ k += 1
713
+ return from_man_exp(s, -wp, wp, rnd)
714
+
715
+ def mpc_psi0(z, prec, rnd=round_fast):
716
+ """
717
+ Computation of the digamma function (psi function of order 0)
718
+ of a complex argument.
719
+ """
720
+ re, im = z
721
+ # Fall back to the real case
722
+ if im == fzero:
723
+ return (mpf_psi0(re, prec, rnd), fzero)
724
+ wp = prec + 20
725
+ sign, man, exp, bc = re
726
+ # Reflection formula
727
+ if sign and exp+bc > 3:
728
+ c = mpc_cos_pi(z, wp)
729
+ s = mpc_sin_pi(z, wp)
730
+ q = mpc_mul_mpf(mpc_div(c, s, wp), mpf_pi(wp), wp)
731
+ p = mpc_psi0(mpc_sub(mpc_one, z, wp), wp)
732
+ return mpc_sub(p, q, prec, rnd)
733
+ # Just the logarithmic term
734
+ if (not sign) and bc + exp > wp:
735
+ return mpc_log(mpc_sub(z, mpc_one, wp), prec, rnd)
736
+ # Initial recurrence to obtain a large enough z
737
+ w = to_int(re)
738
+ n = int(0.11*wp) + 2
739
+ s = mpc_zero
740
+ if w < n:
741
+ for k in xrange(w, n):
742
+ s = mpc_sub(s, mpc_reciprocal(z, wp), wp)
743
+ z = mpc_add_mpf(z, fone, wp)
744
+ z = mpc_sub(z, mpc_one, wp)
745
+ # Logarithmic and endpoint term
746
+ s = mpc_add(s, mpc_log(z, wp), wp)
747
+ s = mpc_add(s, mpc_div(mpc_half, z, wp), wp)
748
+ # Euler-Maclaurin remainder sum
749
+ z2 = mpc_square(z, wp)
750
+ t = mpc_one
751
+ prev = mpc_zero
752
+ szprev = fzero
753
+ k = 1
754
+ eps = mpf_shift(fone, -wp+2)
755
+ while 1:
756
+ t = mpc_mul(t, z2, wp)
757
+ bern = mpf_bernoulli(2*k, wp)
758
+ term = mpc_mpf_div(bern, mpc_mul_int(t, 2*k, wp), wp)
759
+ s = mpc_sub(s, term, wp)
760
+ szterm = mpc_abs(term, 10)
761
+ if k > 2 and (mpf_le(szterm, eps) or mpf_le(szprev, szterm)):
762
+ break
763
+ prev = term
764
+ szprev = szterm
765
+ k += 1
766
+ return s
767
+
768
+ # Currently unoptimized
769
+ def mpf_psi(m, x, prec, rnd=round_fast):
770
+ """
771
+ Computation of the polygamma function of arbitrary integer order
772
+ m >= 0, for a real argument x.
773
+ """
774
+ if m == 0:
775
+ return mpf_psi0(x, prec, rnd=round_fast)
776
+ return mpc_psi(m, (x, fzero), prec, rnd)[0]
777
+
778
+ def mpc_psi(m, z, prec, rnd=round_fast):
779
+ """
780
+ Computation of the polygamma function of arbitrary integer order
781
+ m >= 0, for a complex argument z.
782
+ """
783
+ if m == 0:
784
+ return mpc_psi0(z, prec, rnd)
785
+ re, im = z
786
+ wp = prec + 20
787
+ sign, man, exp, bc = re
788
+ if not im[1]:
789
+ if im in (finf, fninf, fnan):
790
+ return (fnan, fnan)
791
+ if not man:
792
+ if re == finf and im == fzero:
793
+ return (fzero, fzero)
794
+ if re == fnan:
795
+ return (fnan, fnan)
796
+ # Recurrence
797
+ w = to_int(re)
798
+ n = int(0.4*wp + 4*m)
799
+ s = mpc_zero
800
+ if w < n:
801
+ for k in xrange(w, n):
802
+ t = mpc_pow_int(z, -m-1, wp)
803
+ s = mpc_add(s, t, wp)
804
+ z = mpc_add_mpf(z, fone, wp)
805
+ zm = mpc_pow_int(z, -m, wp)
806
+ z2 = mpc_pow_int(z, -2, wp)
807
+ # 1/m*(z+N)^m
808
+ integral_term = mpc_div_mpf(zm, from_int(m), wp)
809
+ s = mpc_add(s, integral_term, wp)
810
+ # 1/2*(z+N)^(-(m+1))
811
+ s = mpc_add(s, mpc_mul_mpf(mpc_div(zm, z, wp), fhalf, wp), wp)
812
+ a = m + 1
813
+ b = 2
814
+ k = 1
815
+ # Important: we want to sum up to the *relative* error,
816
+ # not the absolute error, because psi^(m)(z) might be tiny
817
+ magn = mpc_abs(s, 10)
818
+ magn = magn[2]+magn[3]
819
+ eps = mpf_shift(fone, magn-wp+2)
820
+ while 1:
821
+ zm = mpc_mul(zm, z2, wp)
822
+ bern = mpf_bernoulli(2*k, wp)
823
+ scal = mpf_mul_int(bern, a, wp)
824
+ scal = mpf_div(scal, from_int(b), wp)
825
+ term = mpc_mul_mpf(zm, scal, wp)
826
+ s = mpc_add(s, term, wp)
827
+ szterm = mpc_abs(term, 10)
828
+ if k > 2 and mpf_le(szterm, eps):
829
+ break
830
+ #print k, to_str(szterm, 10), to_str(eps, 10)
831
+ a *= (m+2*k)*(m+2*k+1)
832
+ b *= (2*k+1)*(2*k+2)
833
+ k += 1
834
+ # Scale and sign factor
835
+ v = mpc_mul_mpf(s, mpf_gamma(from_int(m+1), wp), prec, rnd)
836
+ if not (m & 1):
837
+ v = mpf_neg(v[0]), mpf_neg(v[1])
838
+ return v
839
+
840
+
841
+ #-----------------------------------------------------------------------#
842
+ # #
843
+ # Riemann zeta function #
844
+ # #
845
+ #-----------------------------------------------------------------------#
846
+
847
+ r"""
848
+ We use zeta(s) = eta(s) / (1 - 2**(1-s)) and Borwein's approximation
849
+
850
+ n-1
851
+ ___ k
852
+ -1 \ (-1) (d_k - d_n)
853
+ eta(s) ~= ---- ) ------------------
854
+ d_n /___ s
855
+ k = 0 (k + 1)
856
+ where
857
+ k
858
+ ___ i
859
+ \ (n + i - 1)! 4
860
+ d_k = n ) ---------------.
861
+ /___ (n - i)! (2i)!
862
+ i = 0
863
+
864
+ If s = a + b*I, the absolute error for eta(s) is bounded by
865
+
866
+ 3 (1 + 2|b|)
867
+ ------------ * exp(|b| pi/2)
868
+ n
869
+ (3+sqrt(8))
870
+
871
+ Disregarding the linear term, we have approximately,
872
+
873
+ log(err) ~= log(exp(1.58*|b|)) - log(5.8**n)
874
+ log(err) ~= 1.58*|b| - log(5.8)*n
875
+ log(err) ~= 1.58*|b| - 1.76*n
876
+ log2(err) ~= 2.28*|b| - 2.54*n
877
+
878
+ So for p bits, we should choose n > (p + 2.28*|b|) / 2.54.
879
+
880
+ References:
881
+ -----------
882
+
883
+ Peter Borwein, "An Efficient Algorithm for the Riemann Zeta Function"
884
+ http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P117.ps
885
+
886
+ http://en.wikipedia.org/wiki/Dirichlet_eta_function
887
+ """
888
+
889
+ borwein_cache = {}
890
+
891
+ def borwein_coefficients(n):
892
+ if n in borwein_cache:
893
+ return borwein_cache[n]
894
+ ds = [MPZ_ZERO] * (n+1)
895
+ d = MPZ_ONE
896
+ s = ds[0] = MPZ_ONE
897
+ for i in range(1, n+1):
898
+ d = d * 4 * (n+i-1) * (n-i+1)
899
+ d //= ((2*i) * ((2*i)-1))
900
+ s += d
901
+ ds[i] = s
902
+ borwein_cache[n] = ds
903
+ return ds
904
+
905
+ ZETA_INT_CACHE_MAX_PREC = 1000
906
+ zeta_int_cache = {}
907
+
908
+ def mpf_zeta_int(s, prec, rnd=round_fast):
909
+ """
910
+ Optimized computation of zeta(s) for an integer s.
911
+ """
912
+ wp = prec + 20
913
+ s = int(s)
914
+ if s in zeta_int_cache and zeta_int_cache[s][0] >= wp:
915
+ return mpf_pos(zeta_int_cache[s][1], prec, rnd)
916
+ if s < 2:
917
+ if s == 1:
918
+ raise ValueError("zeta(1) pole")
919
+ if not s:
920
+ return mpf_neg(fhalf)
921
+ return mpf_div(mpf_bernoulli(-s+1, wp), from_int(s-1), prec, rnd)
922
+ # 2^-s term vanishes?
923
+ if s >= wp:
924
+ return mpf_perturb(fone, 0, prec, rnd)
925
+ # 5^-s term vanishes?
926
+ elif s >= wp*0.431:
927
+ t = one = 1 << wp
928
+ t += 1 << (wp - s)
929
+ t += one // (MPZ_THREE ** s)
930
+ t += 1 << max(0, wp - s*2)
931
+ return from_man_exp(t, -wp, prec, rnd)
932
+ else:
933
+ # Fast enough to sum directly?
934
+ # Even better, we use the Euler product (idea stolen from pari)
935
+ m = (float(wp)/(s-1) + 1)
936
+ if m < 30:
937
+ needed_terms = int(2.0**m + 1)
938
+ if needed_terms < int(wp/2.54 + 5) / 10:
939
+ t = fone
940
+ for k in list_primes(needed_terms):
941
+ #print k, needed_terms
942
+ powprec = int(wp - s*math.log(k,2))
943
+ if powprec < 2:
944
+ break
945
+ a = mpf_sub(fone, mpf_pow_int(from_int(k), -s, powprec), wp)
946
+ t = mpf_mul(t, a, wp)
947
+ return mpf_div(fone, t, wp)
948
+ # Use Borwein's algorithm
949
+ n = int(wp/2.54 + 5)
950
+ d = borwein_coefficients(n)
951
+ t = MPZ_ZERO
952
+ s = MPZ(s)
953
+ for k in xrange(n):
954
+ t += (((-1)**k * (d[k] - d[n])) << wp) // (k+1)**s
955
+ t = (t << wp) // (-d[n])
956
+ t = (t << wp) // ((1 << wp) - (1 << (wp+1-s)))
957
+ if (s in zeta_int_cache and zeta_int_cache[s][0] < wp) or (s not in zeta_int_cache):
958
+ zeta_int_cache[s] = (wp, from_man_exp(t, -wp-wp))
959
+ return from_man_exp(t, -wp-wp, prec, rnd)
960
+
961
+ def mpf_zeta(s, prec, rnd=round_fast, alt=0):
962
+ sign, man, exp, bc = s
963
+ if not man:
964
+ if s == fzero:
965
+ if alt:
966
+ return fhalf
967
+ else:
968
+ return mpf_neg(fhalf)
969
+ if s == finf:
970
+ return fone
971
+ return fnan
972
+ wp = prec + 20
973
+ # First term vanishes?
974
+ if (not sign) and (exp + bc > (math.log(wp,2) + 2)):
975
+ return mpf_perturb(fone, alt, prec, rnd)
976
+ # Optimize for integer arguments
977
+ elif exp >= 0:
978
+ if alt:
979
+ if s == fone:
980
+ return mpf_ln2(prec, rnd)
981
+ z = mpf_zeta_int(to_int(s), wp, negative_rnd[rnd])
982
+ q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp)
983
+ return mpf_mul(z, q, prec, rnd)
984
+ else:
985
+ return mpf_zeta_int(to_int(s), prec, rnd)
986
+ # Negative: use the reflection formula
987
+ # Borwein only proves the accuracy bound for x >= 1/2. However, based on
988
+ # tests, the accuracy without reflection is quite good even some distance
989
+ # to the left of 1/2. XXX: verify this.
990
+ if sign:
991
+ # XXX: could use the separate refl. formula for Dirichlet eta
992
+ if alt:
993
+ q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp)
994
+ return mpf_mul(mpf_zeta(s, wp), q, prec, rnd)
995
+ # XXX: -1 should be done exactly
996
+ y = mpf_sub(fone, s, 10*wp)
997
+ a = mpf_gamma(y, wp)
998
+ b = mpf_zeta(y, wp)
999
+ c = mpf_sin_pi(mpf_shift(s, -1), wp)
1000
+ wp2 = wp + max(0,exp+bc)
1001
+ pi = mpf_pi(wp+wp2)
1002
+ d = mpf_div(mpf_pow(mpf_shift(pi, 1), s, wp2), pi, wp2)
1003
+ return mpf_mul(a,mpf_mul(b,mpf_mul(c,d,wp),wp),prec,rnd)
1004
+
1005
+ # Near pole
1006
+ r = mpf_sub(fone, s, wp)
1007
+ asign, aman, aexp, abc = mpf_abs(r)
1008
+ pole_dist = -2*(aexp+abc)
1009
+ if pole_dist > wp:
1010
+ if alt:
1011
+ return mpf_ln2(prec, rnd)
1012
+ else:
1013
+ q = mpf_neg(mpf_div(fone, r, wp))
1014
+ return mpf_add(q, mpf_euler(wp), prec, rnd)
1015
+ else:
1016
+ wp += max(0, pole_dist)
1017
+
1018
+ t = MPZ_ZERO
1019
+ #wp += 16 - (prec & 15)
1020
+ # Use Borwein's algorithm
1021
+ n = int(wp/2.54 + 5)
1022
+ d = borwein_coefficients(n)
1023
+ t = MPZ_ZERO
1024
+ sf = to_fixed(s, wp)
1025
+ ln2 = ln2_fixed(wp)
1026
+ for k in xrange(n):
1027
+ u = (-sf*log_int_fixed(k+1, wp, ln2)) >> wp
1028
+ #esign, eman, eexp, ebc = mpf_exp(u, wp)
1029
+ #offset = eexp + wp
1030
+ #if offset >= 0:
1031
+ # w = ((d[k] - d[n]) * eman) << offset
1032
+ #else:
1033
+ # w = ((d[k] - d[n]) * eman) >> (-offset)
1034
+ eman = exp_fixed(u, wp, ln2)
1035
+ w = (d[k] - d[n]) * eman
1036
+ if k & 1:
1037
+ t -= w
1038
+ else:
1039
+ t += w
1040
+ t = t // (-d[n])
1041
+ t = from_man_exp(t, -wp, wp)
1042
+ if alt:
1043
+ return mpf_pos(t, prec, rnd)
1044
+ else:
1045
+ q = mpf_sub(fone, mpf_pow(ftwo, mpf_sub(fone, s, wp), wp), wp)
1046
+ return mpf_div(t, q, prec, rnd)
1047
+
1048
+ def mpc_zeta(s, prec, rnd=round_fast, alt=0, force=False):
1049
+ re, im = s
1050
+ if im == fzero:
1051
+ return mpf_zeta(re, prec, rnd, alt), fzero
1052
+
1053
+ # slow for large s
1054
+ if (not force) and mpf_gt(mpc_abs(s, 10), from_int(prec)):
1055
+ raise NotImplementedError
1056
+
1057
+ wp = prec + 20
1058
+
1059
+ # Near pole
1060
+ r = mpc_sub(mpc_one, s, wp)
1061
+ asign, aman, aexp, abc = mpc_abs(r, 10)
1062
+ pole_dist = -2*(aexp+abc)
1063
+ if pole_dist > wp:
1064
+ if alt:
1065
+ q = mpf_ln2(wp)
1066
+ y = mpf_mul(q, mpf_euler(wp), wp)
1067
+ g = mpf_shift(mpf_mul(q, q, wp), -1)
1068
+ g = mpf_sub(y, g)
1069
+ z = mpc_mul_mpf(r, mpf_neg(g), wp)
1070
+ z = mpc_add_mpf(z, q, wp)
1071
+ return mpc_pos(z, prec, rnd)
1072
+ else:
1073
+ q = mpc_neg(mpc_div(mpc_one, r, wp))
1074
+ q = mpc_add_mpf(q, mpf_euler(wp), wp)
1075
+ return mpc_pos(q, prec, rnd)
1076
+ else:
1077
+ wp += max(0, pole_dist)
1078
+
1079
+ # Reflection formula. To be rigorous, we should reflect to the left of
1080
+ # re = 1/2 (see comments for mpf_zeta), but this leads to unnecessary
1081
+ # slowdown for interesting values of s
1082
+ if mpf_lt(re, fzero):
1083
+ # XXX: could use the separate refl. formula for Dirichlet eta
1084
+ if alt:
1085
+ q = mpc_sub(mpc_one, mpc_pow(mpc_two, mpc_sub(mpc_one, s, wp),
1086
+ wp), wp)
1087
+ return mpc_mul(mpc_zeta(s, wp), q, prec, rnd)
1088
+ # XXX: -1 should be done exactly
1089
+ y = mpc_sub(mpc_one, s, 10*wp)
1090
+ a = mpc_gamma(y, wp)
1091
+ b = mpc_zeta(y, wp)
1092
+ c = mpc_sin_pi(mpc_shift(s, -1), wp)
1093
+ rsign, rman, rexp, rbc = re
1094
+ isign, iman, iexp, ibc = im
1095
+ mag = max(rexp+rbc, iexp+ibc)
1096
+ wp2 = wp + max(0, mag)
1097
+ pi = mpf_pi(wp+wp2)
1098
+ pi2 = (mpf_shift(pi, 1), fzero)
1099
+ d = mpc_div_mpf(mpc_pow(pi2, s, wp2), pi, wp2)
1100
+ return mpc_mul(a,mpc_mul(b,mpc_mul(c,d,wp),wp),prec,rnd)
1101
+ n = int(wp/2.54 + 5)
1102
+ n += int(0.9*abs(to_int(im)))
1103
+ d = borwein_coefficients(n)
1104
+ ref = to_fixed(re, wp)
1105
+ imf = to_fixed(im, wp)
1106
+ tre = MPZ_ZERO
1107
+ tim = MPZ_ZERO
1108
+ one = MPZ_ONE << wp
1109
+ one_2wp = MPZ_ONE << (2*wp)
1110
+ critical_line = re == fhalf
1111
+ ln2 = ln2_fixed(wp)
1112
+ pi2 = pi_fixed(wp-1)
1113
+ wp2 = wp+wp
1114
+ for k in xrange(n):
1115
+ log = log_int_fixed(k+1, wp, ln2)
1116
+ # A square root is much cheaper than an exp
1117
+ if critical_line:
1118
+ w = one_2wp // isqrt_fast((k+1) << wp2)
1119
+ else:
1120
+ w = exp_fixed((-ref*log) >> wp, wp)
1121
+ if k & 1:
1122
+ w *= (d[n] - d[k])
1123
+ else:
1124
+ w *= (d[k] - d[n])
1125
+ wre, wim = cos_sin_fixed((-imf*log)>>wp, wp, pi2)
1126
+ tre += (w * wre) >> wp
1127
+ tim += (w * wim) >> wp
1128
+ tre //= (-d[n])
1129
+ tim //= (-d[n])
1130
+ tre = from_man_exp(tre, -wp, wp)
1131
+ tim = from_man_exp(tim, -wp, wp)
1132
+ if alt:
1133
+ return mpc_pos((tre, tim), prec, rnd)
1134
+ else:
1135
+ q = mpc_sub(mpc_one, mpc_pow(mpc_two, r, wp), wp)
1136
+ return mpc_div((tre, tim), q, prec, rnd)
1137
+
1138
+ def mpf_altzeta(s, prec, rnd=round_fast):
1139
+ return mpf_zeta(s, prec, rnd, 1)
1140
+
1141
+ def mpc_altzeta(s, prec, rnd=round_fast):
1142
+ return mpc_zeta(s, prec, rnd, 1)
1143
+
1144
+ # Not optimized currently
1145
+ mpf_zetasum = None
1146
+
1147
+
1148
+ def pow_fixed(x, n, wp):
1149
+ if n == 1:
1150
+ return x
1151
+ y = MPZ_ONE << wp
1152
+ while n:
1153
+ if n & 1:
1154
+ y = (y*x) >> wp
1155
+ n -= 1
1156
+ x = (x*x) >> wp
1157
+ n //= 2
1158
+ return y
1159
+
1160
+ # TODO: optimize / cleanup interface / unify with list_primes
1161
+ sieve_cache = []
1162
+ primes_cache = []
1163
+ mult_cache = []
1164
+
1165
+ def primesieve(n):
1166
+ global sieve_cache, primes_cache, mult_cache
1167
+ if n < len(sieve_cache):
1168
+ sieve = sieve_cache#[:n+1]
1169
+ primes = primes_cache[:primes_cache.index(max(sieve))+1]
1170
+ mult = mult_cache#[:n+1]
1171
+ return sieve, primes, mult
1172
+ sieve = [0] * (n+1)
1173
+ mult = [0] * (n+1)
1174
+ primes = list_primes(n)
1175
+ for p in primes:
1176
+ #sieve[p::p] = p
1177
+ for k in xrange(p,n+1,p):
1178
+ sieve[k] = p
1179
+ for i, p in enumerate(sieve):
1180
+ if i >= 2:
1181
+ m = 1
1182
+ n = i // p
1183
+ while not n % p:
1184
+ n //= p
1185
+ m += 1
1186
+ mult[i] = m
1187
+ sieve_cache = sieve
1188
+ primes_cache = primes
1189
+ mult_cache = mult
1190
+ return sieve, primes, mult
1191
+
1192
+ def zetasum_sieved(critical_line, sre, sim, a, n, wp):
1193
+ if a < 1:
1194
+ raise ValueError("a cannot be less than 1")
1195
+ sieve, primes, mult = primesieve(a+n)
1196
+ basic_powers = {}
1197
+ one = MPZ_ONE << wp
1198
+ one_2wp = MPZ_ONE << (2*wp)
1199
+ wp2 = wp+wp
1200
+ ln2 = ln2_fixed(wp)
1201
+ pi2 = pi_fixed(wp-1)
1202
+ for p in primes:
1203
+ if p*2 > a+n:
1204
+ break
1205
+ log = log_int_fixed(p, wp, ln2)
1206
+ cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2)
1207
+ if critical_line:
1208
+ u = one_2wp // isqrt_fast(p<<wp2)
1209
+ else:
1210
+ u = exp_fixed((-sre*log)>>wp, wp)
1211
+ pre = (u*cos) >> wp
1212
+ pim = (u*sin) >> wp
1213
+ basic_powers[p] = [(pre, pim)]
1214
+ tre, tim = pre, pim
1215
+ for m in range(1,int(math.log(a+n,p)+0.01)+1):
1216
+ tre, tim = ((pre*tre-pim*tim)>>wp), ((pim*tre+pre*tim)>>wp)
1217
+ basic_powers[p].append((tre,tim))
1218
+ xre = MPZ_ZERO
1219
+ xim = MPZ_ZERO
1220
+ if a == 1:
1221
+ xre += one
1222
+ aa = max(a,2)
1223
+ for k in xrange(aa, a+n+1):
1224
+ p = sieve[k]
1225
+ if p in basic_powers:
1226
+ m = mult[k]
1227
+ tre, tim = basic_powers[p][m-1]
1228
+ while 1:
1229
+ k //= p**m
1230
+ if k == 1:
1231
+ break
1232
+ p = sieve[k]
1233
+ m = mult[k]
1234
+ pre, pim = basic_powers[p][m-1]
1235
+ tre, tim = ((pre*tre-pim*tim)>>wp), ((pim*tre+pre*tim)>>wp)
1236
+ else:
1237
+ log = log_int_fixed(k, wp, ln2)
1238
+ cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2)
1239
+ if critical_line:
1240
+ u = one_2wp // isqrt_fast(k<<wp2)
1241
+ else:
1242
+ u = exp_fixed((-sre*log)>>wp, wp)
1243
+ tre = (u*cos) >> wp
1244
+ tim = (u*sin) >> wp
1245
+ xre += tre
1246
+ xim += tim
1247
+ return xre, xim
1248
+
1249
+ # Set to something large to disable
1250
+ ZETASUM_SIEVE_CUTOFF = 10
1251
+
1252
+ def mpc_zetasum(s, a, n, derivatives, reflect, prec):
1253
+ """
1254
+ Fast version of mp._zetasum, assuming s = complex, a = integer.
1255
+ """
1256
+
1257
+ wp = prec + 10
1258
+ derivatives = list(derivatives)
1259
+ have_derivatives = derivatives != [0]
1260
+ have_one_derivative = len(derivatives) == 1
1261
+
1262
+ # parse s
1263
+ sre, sim = s
1264
+ critical_line = (sre == fhalf)
1265
+ sre = to_fixed(sre, wp)
1266
+ sim = to_fixed(sim, wp)
1267
+
1268
+ if a > 0 and n > ZETASUM_SIEVE_CUTOFF and not have_derivatives \
1269
+ and not reflect and (n < 4e7 or sys.maxsize > 2**32):
1270
+ re, im = zetasum_sieved(critical_line, sre, sim, a, n, wp)
1271
+ xs = [(from_man_exp(re, -wp, prec, 'n'), from_man_exp(im, -wp, prec, 'n'))]
1272
+ return xs, []
1273
+
1274
+ maxd = max(derivatives)
1275
+ if not have_one_derivative:
1276
+ derivatives = range(maxd+1)
1277
+
1278
+ # x_d = 0, y_d = 0
1279
+ xre = [MPZ_ZERO for d in derivatives]
1280
+ xim = [MPZ_ZERO for d in derivatives]
1281
+ if reflect:
1282
+ yre = [MPZ_ZERO for d in derivatives]
1283
+ yim = [MPZ_ZERO for d in derivatives]
1284
+ else:
1285
+ yre = yim = []
1286
+
1287
+ one = MPZ_ONE << wp
1288
+ one_2wp = MPZ_ONE << (2*wp)
1289
+
1290
+ ln2 = ln2_fixed(wp)
1291
+ pi2 = pi_fixed(wp-1)
1292
+ wp2 = wp+wp
1293
+
1294
+ for w in xrange(a, a+n+1):
1295
+ log = log_int_fixed(w, wp, ln2)
1296
+ cos, sin = cos_sin_fixed((-sim*log)>>wp, wp, pi2)
1297
+ if critical_line:
1298
+ u = one_2wp // isqrt_fast(w<<wp2)
1299
+ else:
1300
+ u = exp_fixed((-sre*log)>>wp, wp)
1301
+ xterm_re = (u * cos) >> wp
1302
+ xterm_im = (u * sin) >> wp
1303
+ if reflect:
1304
+ reciprocal = (one_2wp // (u*w))
1305
+ yterm_re = (reciprocal * cos) >> wp
1306
+ yterm_im = (reciprocal * sin) >> wp
1307
+
1308
+ if have_derivatives:
1309
+ if have_one_derivative:
1310
+ log = pow_fixed(log, maxd, wp)
1311
+ xre[0] += (xterm_re * log) >> wp
1312
+ xim[0] += (xterm_im * log) >> wp
1313
+ if reflect:
1314
+ yre[0] += (yterm_re * log) >> wp
1315
+ yim[0] += (yterm_im * log) >> wp
1316
+ else:
1317
+ t = MPZ_ONE << wp
1318
+ for d in derivatives:
1319
+ xre[d] += (xterm_re * t) >> wp
1320
+ xim[d] += (xterm_im * t) >> wp
1321
+ if reflect:
1322
+ yre[d] += (yterm_re * t) >> wp
1323
+ yim[d] += (yterm_im * t) >> wp
1324
+ t = (t * log) >> wp
1325
+ else:
1326
+ xre[0] += xterm_re
1327
+ xim[0] += xterm_im
1328
+ if reflect:
1329
+ yre[0] += yterm_re
1330
+ yim[0] += yterm_im
1331
+ if have_derivatives:
1332
+ if have_one_derivative:
1333
+ if maxd % 2:
1334
+ xre[0] = -xre[0]
1335
+ xim[0] = -xim[0]
1336
+ if reflect:
1337
+ yre[0] = -yre[0]
1338
+ yim[0] = -yim[0]
1339
+ else:
1340
+ xre = [(-1)**d * xre[d] for d in derivatives]
1341
+ xim = [(-1)**d * xim[d] for d in derivatives]
1342
+ if reflect:
1343
+ yre = [(-1)**d * yre[d] for d in derivatives]
1344
+ yim = [(-1)**d * yim[d] for d in derivatives]
1345
+ xs = [(from_man_exp(xa, -wp, prec, 'n'), from_man_exp(xb, -wp, prec, 'n'))
1346
+ for (xa, xb) in zip(xre, xim)]
1347
+ ys = [(from_man_exp(ya, -wp, prec, 'n'), from_man_exp(yb, -wp, prec, 'n'))
1348
+ for (ya, yb) in zip(yre, yim)]
1349
+ return xs, ys
1350
+
1351
+
1352
+ #-----------------------------------------------------------------------#
1353
+ # #
1354
+ # The gamma function (NEW IMPLEMENTATION) #
1355
+ # #
1356
+ #-----------------------------------------------------------------------#
1357
+
1358
+ # Higher means faster, but more precomputation time
1359
+ MAX_GAMMA_TAYLOR_PREC = 5000
1360
+ # Need to derive higher bounds for Taylor series to go higher
1361
+ assert MAX_GAMMA_TAYLOR_PREC < 15000
1362
+
1363
+ # Use Stirling's series if abs(x) > beta*prec
1364
+ # Important: must be large enough for convergence!
1365
+ GAMMA_STIRLING_BETA = 0.2
1366
+
1367
+ SMALL_FACTORIAL_CACHE_SIZE = 150
1368
+
1369
+ gamma_taylor_cache = {}
1370
+ gamma_stirling_cache = {}
1371
+
1372
+ small_factorial_cache = [from_int(ifac(n)) for \
1373
+ n in range(SMALL_FACTORIAL_CACHE_SIZE+1)]
1374
+
1375
+ def zeta_array(N, prec):
1376
+ """
1377
+ zeta(n) = A * pi**n / n! + B
1378
+
1379
+ where A is a rational number (A = Bernoulli number
1380
+ for n even) and B is an infinite sum over powers of exp(2*pi).
1381
+ (B = 0 for n even).
1382
+
1383
+ TODO: this is currently only used for gamma, but could
1384
+ be very useful elsewhere.
1385
+ """
1386
+ extra = 30
1387
+ wp = prec+extra
1388
+ zeta_values = [MPZ_ZERO] * (N+2)
1389
+ pi = pi_fixed(wp)
1390
+ # STEP 1:
1391
+ one = MPZ_ONE << wp
1392
+ zeta_values[0] = -one//2
1393
+ f_2pi = mpf_shift(mpf_pi(wp),1)
1394
+ exp_2pi_k = exp_2pi = mpf_exp(f_2pi, wp)
1395
+ # Compute exponential series
1396
+ # Store values of 1/(exp(2*pi*k)-1),
1397
+ # exp(2*pi*k)/(exp(2*pi*k)-1)**2, 1/(exp(2*pi*k)-1)**2
1398
+ # pi*k*exp(2*pi*k)/(exp(2*pi*k)-1)**2
1399
+ exps3 = []
1400
+ k = 1
1401
+ while 1:
1402
+ tp = wp - 9*k
1403
+ if tp < 1:
1404
+ break
1405
+ # 1/(exp(2*pi*k-1)
1406
+ q1 = mpf_div(fone, mpf_sub(exp_2pi_k, fone, tp), tp)
1407
+ # pi*k*exp(2*pi*k)/(exp(2*pi*k)-1)**2
1408
+ q2 = mpf_mul(exp_2pi_k, mpf_mul(q1,q1,tp), tp)
1409
+ q1 = to_fixed(q1, wp)
1410
+ q2 = to_fixed(q2, wp)
1411
+ q2 = (k * q2 * pi) >> wp
1412
+ exps3.append((q1, q2))
1413
+ # Multiply for next round
1414
+ exp_2pi_k = mpf_mul(exp_2pi_k, exp_2pi, wp)
1415
+ k += 1
1416
+ # Exponential sum
1417
+ for n in xrange(3, N+1, 2):
1418
+ s = MPZ_ZERO
1419
+ k = 1
1420
+ for e1, e2 in exps3:
1421
+ if n%4 == 3:
1422
+ t = e1 // k**n
1423
+ else:
1424
+ U = (n-1)//4
1425
+ t = (e1 + e2//U) // k**n
1426
+ if not t:
1427
+ break
1428
+ s += t
1429
+ k += 1
1430
+ zeta_values[n] = -2*s
1431
+ # Even zeta values
1432
+ B = [mpf_abs(mpf_bernoulli(k,wp)) for k in xrange(N+2)]
1433
+ pi_pow = fpi = mpf_pow_int(mpf_shift(mpf_pi(wp), 1), 2, wp)
1434
+ pi_pow = mpf_div(pi_pow, from_int(4), wp)
1435
+ for n in xrange(2,N+2,2):
1436
+ z = mpf_mul(B[n], pi_pow, wp)
1437
+ zeta_values[n] = to_fixed(z, wp)
1438
+ pi_pow = mpf_mul(pi_pow, fpi, wp)
1439
+ pi_pow = mpf_div(pi_pow, from_int((n+1)*(n+2)), wp)
1440
+ # Zeta sum
1441
+ reciprocal_pi = (one << wp) // pi
1442
+ for n in xrange(3, N+1, 4):
1443
+ U = (n-3)//4
1444
+ s = zeta_values[4*U+4]*(4*U+7)//4
1445
+ for k in xrange(1, U+1):
1446
+ s -= (zeta_values[4*k] * zeta_values[4*U+4-4*k]) >> wp
1447
+ zeta_values[n] += (2*s*reciprocal_pi) >> wp
1448
+ for n in xrange(5, N+1, 4):
1449
+ U = (n-1)//4
1450
+ s = zeta_values[4*U+2]*(2*U+1)
1451
+ for k in xrange(1, 2*U+1):
1452
+ s += ((-1)**k*2*k* zeta_values[2*k] * zeta_values[4*U+2-2*k])>>wp
1453
+ zeta_values[n] += ((s*reciprocal_pi)>>wp)//(2*U)
1454
+ return [x>>extra for x in zeta_values]
1455
+
1456
+ def gamma_taylor_coefficients(inprec):
1457
+ """
1458
+ Gives the Taylor coefficients of 1/gamma(1+x) as
1459
+ a list of fixed-point numbers. Enough coefficients are returned
1460
+ to ensure that the series converges to the given precision
1461
+ when x is in [0.5, 1.5].
1462
+ """
1463
+ # Reuse nearby cache values (small case)
1464
+ if inprec < 400:
1465
+ prec = inprec + (10-(inprec%10))
1466
+ elif inprec < 1000:
1467
+ prec = inprec + (30-(inprec%30))
1468
+ else:
1469
+ prec = inprec
1470
+ if prec in gamma_taylor_cache:
1471
+ return gamma_taylor_cache[prec], prec
1472
+
1473
+ # Experimentally determined bounds
1474
+ if prec < 1000:
1475
+ N = int(prec**0.76 + 2)
1476
+ else:
1477
+ # Valid to at least 15000 bits
1478
+ N = int(prec**0.787 + 2)
1479
+
1480
+ # Reuse higher precision values
1481
+ for cprec in gamma_taylor_cache:
1482
+ if cprec > prec:
1483
+ coeffs = [x>>(cprec-prec) for x in gamma_taylor_cache[cprec][-N:]]
1484
+ if inprec < 1000:
1485
+ gamma_taylor_cache[prec] = coeffs
1486
+ return coeffs, prec
1487
+
1488
+ # Cache at a higher precision (large case)
1489
+ if prec > 1000:
1490
+ prec = int(prec * 1.2)
1491
+
1492
+ wp = prec + 20
1493
+ A = [0] * N
1494
+ A[0] = MPZ_ZERO
1495
+ A[1] = MPZ_ONE << wp
1496
+ A[2] = euler_fixed(wp)
1497
+ # SLOW, reference implementation
1498
+ #zeta_values = [0,0]+[to_fixed(mpf_zeta_int(k,wp),wp) for k in xrange(2,N)]
1499
+ zeta_values = zeta_array(N, wp)
1500
+ for k in xrange(3, N):
1501
+ a = (-A[2]*A[k-1])>>wp
1502
+ for j in xrange(2,k):
1503
+ a += ((-1)**j * zeta_values[j] * A[k-j]) >> wp
1504
+ a //= (1-k)
1505
+ A[k] = a
1506
+ A = [a>>20 for a in A]
1507
+ A = A[::-1]
1508
+ A = A[:-1]
1509
+ gamma_taylor_cache[prec] = A
1510
+ #return A, prec
1511
+ return gamma_taylor_coefficients(inprec)
1512
+
1513
+ def gamma_fixed_taylor(xmpf, x, wp, prec, rnd, type):
1514
+ # Determine nearest multiple of N/2
1515
+ #n = int(x >> (wp-1))
1516
+ #steps = (n-1)>>1
1517
+ nearest_int = ((x >> (wp-1)) + MPZ_ONE) >> 1
1518
+ one = MPZ_ONE << wp
1519
+ coeffs, cwp = gamma_taylor_coefficients(wp)
1520
+ if nearest_int > 0:
1521
+ r = one
1522
+ for i in xrange(nearest_int-1):
1523
+ x -= one
1524
+ r = (r*x) >> wp
1525
+ x -= one
1526
+ p = MPZ_ZERO
1527
+ for c in coeffs:
1528
+ p = c + ((x*p)>>wp)
1529
+ p >>= (cwp-wp)
1530
+ if type == 0:
1531
+ return from_man_exp((r<<wp)//p, -wp, prec, rnd)
1532
+ if type == 2:
1533
+ return mpf_shift(from_rational(p, (r<<wp), prec, rnd), wp)
1534
+ if type == 3:
1535
+ return mpf_log(mpf_abs(from_man_exp((r<<wp)//p, -wp)), prec, rnd)
1536
+ else:
1537
+ r = one
1538
+ for i in xrange(-nearest_int):
1539
+ r = (r*x) >> wp
1540
+ x += one
1541
+ p = MPZ_ZERO
1542
+ for c in coeffs:
1543
+ p = c + ((x*p)>>wp)
1544
+ p >>= (cwp-wp)
1545
+ if wp - bitcount(abs(x)) > 10:
1546
+ # pass very close to 0, so do floating-point multiply
1547
+ g = mpf_add(xmpf, from_int(-nearest_int)) # exact
1548
+ r = from_man_exp(p*r,-wp-wp)
1549
+ r = mpf_mul(r, g, wp)
1550
+ if type == 0:
1551
+ return mpf_div(fone, r, prec, rnd)
1552
+ if type == 2:
1553
+ return mpf_pos(r, prec, rnd)
1554
+ if type == 3:
1555
+ return mpf_log(mpf_abs(mpf_div(fone, r, wp)), prec, rnd)
1556
+ else:
1557
+ r = from_man_exp(x*p*r,-3*wp)
1558
+ if type == 0: return mpf_div(fone, r, prec, rnd)
1559
+ if type == 2: return mpf_pos(r, prec, rnd)
1560
+ if type == 3: return mpf_neg(mpf_log(mpf_abs(r), prec, rnd))
1561
+
1562
+ def stirling_coefficient(n):
1563
+ if n in gamma_stirling_cache:
1564
+ return gamma_stirling_cache[n]
1565
+ p, q = bernfrac(n)
1566
+ q *= MPZ(n*(n-1))
1567
+ gamma_stirling_cache[n] = p, q, bitcount(abs(p)), bitcount(q)
1568
+ return gamma_stirling_cache[n]
1569
+
1570
+ def real_stirling_series(x, prec):
1571
+ """
1572
+ Sums the rational part of Stirling's expansion,
1573
+
1574
+ log(sqrt(2*pi)) - z + 1/(12*z) - 1/(360*z^3) + ...
1575
+
1576
+ """
1577
+ t = (MPZ_ONE<<(prec+prec)) // x # t = 1/x
1578
+ u = (t*t)>>prec # u = 1/x**2
1579
+ s = ln_sqrt2pi_fixed(prec) - x
1580
+ # Add initial terms of Stirling's series
1581
+ s += t//12; t = (t*u)>>prec
1582
+ s -= t//360; t = (t*u)>>prec
1583
+ s += t//1260; t = (t*u)>>prec
1584
+ s -= t//1680; t = (t*u)>>prec
1585
+ if not t: return s
1586
+ s += t//1188; t = (t*u)>>prec
1587
+ s -= 691*t//360360; t = (t*u)>>prec
1588
+ s += t//156; t = (t*u)>>prec
1589
+ if not t: return s
1590
+ s -= 3617*t//122400; t = (t*u)>>prec
1591
+ s += 43867*t//244188; t = (t*u)>>prec
1592
+ s -= 174611*t//125400; t = (t*u)>>prec
1593
+ if not t: return s
1594
+ k = 22
1595
+ # From here on, the coefficients are growing, so we
1596
+ # have to keep t at a roughly constant size
1597
+ usize = bitcount(abs(u))
1598
+ tsize = bitcount(abs(t))
1599
+ texp = 0
1600
+ while 1:
1601
+ p, q, pb, qb = stirling_coefficient(k)
1602
+ term_mag = tsize + pb + texp
1603
+ shift = -texp
1604
+ m = pb - term_mag
1605
+ if m > 0 and shift < m:
1606
+ p >>= m
1607
+ shift -= m
1608
+ m = tsize - term_mag
1609
+ if m > 0 and shift < m:
1610
+ w = t >> m
1611
+ shift -= m
1612
+ else:
1613
+ w = t
1614
+ term = (t*p//q) >> shift
1615
+ if not term:
1616
+ break
1617
+ s += term
1618
+ t = (t*u) >> usize
1619
+ texp -= (prec - usize)
1620
+ k += 2
1621
+ return s
1622
+
1623
+ def complex_stirling_series(x, y, prec):
1624
+ # t = 1/z
1625
+ _m = (x*x + y*y) >> prec
1626
+ tre = (x << prec) // _m
1627
+ tim = (-y << prec) // _m
1628
+ # u = 1/z**2
1629
+ ure = (tre*tre - tim*tim) >> prec
1630
+ uim = tim*tre >> (prec-1)
1631
+ # s = log(sqrt(2*pi)) - z
1632
+ sre = ln_sqrt2pi_fixed(prec) - x
1633
+ sim = -y
1634
+
1635
+ # Add initial terms of Stirling's series
1636
+ sre += tre//12; sim += tim//12;
1637
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1638
+ sre -= tre//360; sim -= tim//360;
1639
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1640
+ sre += tre//1260; sim += tim//1260;
1641
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1642
+ sre -= tre//1680; sim -= tim//1680;
1643
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1644
+ if abs(tre) + abs(tim) < 5: return sre, sim
1645
+ sre += tre//1188; sim += tim//1188;
1646
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1647
+ sre -= 691*tre//360360; sim -= 691*tim//360360;
1648
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1649
+ sre += tre//156; sim += tim//156;
1650
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1651
+ if abs(tre) + abs(tim) < 5: return sre, sim
1652
+ sre -= 3617*tre//122400; sim -= 3617*tim//122400;
1653
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1654
+ sre += 43867*tre//244188; sim += 43867*tim//244188;
1655
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1656
+ sre -= 174611*tre//125400; sim -= 174611*tim//125400;
1657
+ tre, tim = ((tre*ure-tim*uim)>>prec), ((tre*uim+tim*ure)>>prec)
1658
+ if abs(tre) + abs(tim) < 5: return sre, sim
1659
+
1660
+ k = 22
1661
+ # From here on, the coefficients are growing, so we
1662
+ # have to keep t at a roughly constant size
1663
+ usize = bitcount(max(abs(ure), abs(uim)))
1664
+ tsize = bitcount(max(abs(tre), abs(tim)))
1665
+ texp = 0
1666
+ while 1:
1667
+ p, q, pb, qb = stirling_coefficient(k)
1668
+ term_mag = tsize + pb + texp
1669
+ shift = -texp
1670
+ m = pb - term_mag
1671
+ if m > 0 and shift < m:
1672
+ p >>= m
1673
+ shift -= m
1674
+ m = tsize - term_mag
1675
+ if m > 0 and shift < m:
1676
+ wre = tre >> m
1677
+ wim = tim >> m
1678
+ shift -= m
1679
+ else:
1680
+ wre = tre
1681
+ wim = tim
1682
+ termre = (tre*p//q) >> shift
1683
+ termim = (tim*p//q) >> shift
1684
+ if abs(termre) + abs(termim) < 5:
1685
+ break
1686
+ sre += termre
1687
+ sim += termim
1688
+ tre, tim = ((tre*ure - tim*uim)>>usize), \
1689
+ ((tre*uim + tim*ure)>>usize)
1690
+ texp -= (prec - usize)
1691
+ k += 2
1692
+ return sre, sim
1693
+
1694
+
1695
+ def mpf_gamma(x, prec, rnd='d', type=0):
1696
+ """
1697
+ This function implements multipurpose evaluation of the gamma
1698
+ function, G(x), as well as the following versions of the same:
1699
+
1700
+ type = 0 -- G(x) [standard gamma function]
1701
+ type = 1 -- G(x+1) = x*G(x+1) = x! [factorial]
1702
+ type = 2 -- 1/G(x) [reciprocal gamma function]
1703
+ type = 3 -- log(|G(x)|) [log-gamma function, real part]
1704
+ """
1705
+
1706
+ # Specal values
1707
+ sign, man, exp, bc = x
1708
+ if not man:
1709
+ if x == fzero:
1710
+ if type == 1: return fone
1711
+ if type == 2: return fzero
1712
+ raise ValueError("gamma function pole")
1713
+ if x == finf:
1714
+ if type == 2: return fzero
1715
+ return finf
1716
+ return fnan
1717
+
1718
+ # First of all, for log gamma, numbers can be well beyond the fixed-point
1719
+ # range, so we must take care of huge numbers before e.g. trying
1720
+ # to convert x to the nearest integer
1721
+ if type == 3:
1722
+ wp = prec+20
1723
+ if exp+bc > wp and not sign:
1724
+ return mpf_sub(mpf_mul(x, mpf_log(x, wp), wp), x, prec, rnd)
1725
+
1726
+ # We strongly want to special-case small integers
1727
+ is_integer = exp >= 0
1728
+ if is_integer:
1729
+ # Poles
1730
+ if sign:
1731
+ if type == 2:
1732
+ return fzero
1733
+ raise ValueError("gamma function pole")
1734
+ # n = x
1735
+ n = man << exp
1736
+ if n < SMALL_FACTORIAL_CACHE_SIZE:
1737
+ if type == 0:
1738
+ return mpf_pos(small_factorial_cache[n-1], prec, rnd)
1739
+ if type == 1:
1740
+ return mpf_pos(small_factorial_cache[n], prec, rnd)
1741
+ if type == 2:
1742
+ return mpf_div(fone, small_factorial_cache[n-1], prec, rnd)
1743
+ if type == 3:
1744
+ return mpf_log(small_factorial_cache[n-1], prec, rnd)
1745
+ else:
1746
+ # floor(abs(x))
1747
+ n = int(man >> (-exp))
1748
+
1749
+ # Estimate size and precision
1750
+ # Estimate log(gamma(|x|),2) as x*log(x,2)
1751
+ mag = exp + bc
1752
+ gamma_size = n*mag
1753
+
1754
+ if type == 3:
1755
+ wp = prec + 20
1756
+ else:
1757
+ wp = prec + bitcount(gamma_size) + 20
1758
+
1759
+ # Very close to 0, pole
1760
+ if mag < -wp:
1761
+ if type == 0:
1762
+ return mpf_sub(mpf_div(fone,x, wp),mpf_shift(fone,-wp),prec,rnd)
1763
+ if type == 1: return mpf_sub(fone, x, prec, rnd)
1764
+ if type == 2: return mpf_add(x, mpf_shift(fone,mag-wp), prec, rnd)
1765
+ if type == 3: return mpf_neg(mpf_log(mpf_abs(x), prec, rnd))
1766
+
1767
+ # From now on, we assume having a gamma function
1768
+ if type == 1:
1769
+ return mpf_gamma(mpf_add(x, fone), prec, rnd, 0)
1770
+
1771
+ # Special case integers (those not small enough to be caught above,
1772
+ # but still small enough for an exact factorial to be faster
1773
+ # than an approximate algorithm), and half-integers
1774
+ if exp >= -1:
1775
+ if is_integer:
1776
+ if gamma_size < 10*wp:
1777
+ if type == 0:
1778
+ return from_int(ifac(n-1), prec, rnd)
1779
+ if type == 2:
1780
+ return from_rational(MPZ_ONE, ifac(n-1), prec, rnd)
1781
+ if type == 3:
1782
+ return mpf_log(from_int(ifac(n-1)), prec, rnd)
1783
+ # half-integer
1784
+ if n < 100 or gamma_size < 10*wp:
1785
+ if sign:
1786
+ w = sqrtpi_fixed(wp)
1787
+ if n % 2: f = ifac2(2*n+1)
1788
+ else: f = -ifac2(2*n+1)
1789
+ if type == 0:
1790
+ return mpf_shift(from_rational(w, f, prec, rnd), -wp+n+1)
1791
+ if type == 2:
1792
+ return mpf_shift(from_rational(f, w, prec, rnd), wp-n-1)
1793
+ if type == 3:
1794
+ return mpf_log(mpf_shift(from_rational(w, abs(f),
1795
+ prec, rnd), -wp+n+1), prec, rnd)
1796
+ elif n == 0:
1797
+ if type == 0: return mpf_sqrtpi(prec, rnd)
1798
+ if type == 2: return mpf_div(fone, mpf_sqrtpi(wp), prec, rnd)
1799
+ if type == 3: return mpf_log(mpf_sqrtpi(wp), prec, rnd)
1800
+ else:
1801
+ w = sqrtpi_fixed(wp)
1802
+ w = from_man_exp(w * ifac2(2*n-1), -wp-n)
1803
+ if type == 0: return mpf_pos(w, prec, rnd)
1804
+ if type == 2: return mpf_div(fone, w, prec, rnd)
1805
+ if type == 3: return mpf_log(mpf_abs(w), prec, rnd)
1806
+
1807
+ # Convert to fixed point
1808
+ offset = exp + wp
1809
+ if offset >= 0: absxman = man << offset
1810
+ else: absxman = man >> (-offset)
1811
+
1812
+ # For log gamma, provide accurate evaluation for x = 1+eps and 2+eps
1813
+ if type == 3 and not sign:
1814
+ one = MPZ_ONE << wp
1815
+ one_dist = abs(absxman-one)
1816
+ two_dist = abs(absxman-2*one)
1817
+ cancellation = (wp - bitcount(min(one_dist, two_dist)))
1818
+ if cancellation > 10:
1819
+ xsub1 = mpf_sub(fone, x)
1820
+ xsub2 = mpf_sub(ftwo, x)
1821
+ xsub1mag = xsub1[2]+xsub1[3]
1822
+ xsub2mag = xsub2[2]+xsub2[3]
1823
+ if xsub1mag < -wp:
1824
+ return mpf_mul(mpf_euler(wp), mpf_sub(fone, x), prec, rnd)
1825
+ if xsub2mag < -wp:
1826
+ return mpf_mul(mpf_sub(fone, mpf_euler(wp)),
1827
+ mpf_sub(x, ftwo), prec, rnd)
1828
+ # Proceed but increase precision
1829
+ wp += max(-xsub1mag, -xsub2mag)
1830
+ offset = exp + wp
1831
+ if offset >= 0: absxman = man << offset
1832
+ else: absxman = man >> (-offset)
1833
+
1834
+ # Use Taylor series if appropriate
1835
+ n_for_stirling = int(GAMMA_STIRLING_BETA*wp)
1836
+ if n < max(100, n_for_stirling) and wp < MAX_GAMMA_TAYLOR_PREC:
1837
+ if sign:
1838
+ absxman = -absxman
1839
+ return gamma_fixed_taylor(x, absxman, wp, prec, rnd, type)
1840
+
1841
+ # Use Stirling's series
1842
+ # First ensure that |x| is large enough for rapid convergence
1843
+ xorig = x
1844
+
1845
+ # Argument reduction
1846
+ r = 0
1847
+ if n < n_for_stirling:
1848
+ r = one = MPZ_ONE << wp
1849
+ d = n_for_stirling - n
1850
+ for k in xrange(d):
1851
+ r = (r * absxman) >> wp
1852
+ absxman += one
1853
+ x = xabs = from_man_exp(absxman, -wp)
1854
+ if sign:
1855
+ x = mpf_neg(x)
1856
+ else:
1857
+ xabs = mpf_abs(x)
1858
+
1859
+ # Asymptotic series
1860
+ y = real_stirling_series(absxman, wp)
1861
+ u = to_fixed(mpf_log(xabs, wp), wp)
1862
+ u = ((absxman - (MPZ_ONE<<(wp-1))) * u) >> wp
1863
+ y += u
1864
+ w = from_man_exp(y, -wp)
1865
+
1866
+ # Compute final value
1867
+ if sign:
1868
+ # Reflection formula
1869
+ A = mpf_mul(mpf_sin_pi(xorig, wp), xorig, wp)
1870
+ B = mpf_neg(mpf_pi(wp))
1871
+ if type == 0 or type == 2:
1872
+ A = mpf_mul(A, mpf_exp(w, wp))
1873
+ if r:
1874
+ B = mpf_mul(B, from_man_exp(r, -wp), wp)
1875
+ if type == 0:
1876
+ return mpf_div(B, A, prec, rnd)
1877
+ if type == 2:
1878
+ return mpf_div(A, B, prec, rnd)
1879
+ if type == 3:
1880
+ if r:
1881
+ B = mpf_mul(B, from_man_exp(r, -wp), wp)
1882
+ A = mpf_add(mpf_log(mpf_abs(A), wp), w, wp)
1883
+ return mpf_sub(mpf_log(mpf_abs(B), wp), A, prec, rnd)
1884
+ else:
1885
+ if type == 0:
1886
+ if r:
1887
+ return mpf_div(mpf_exp(w, wp),
1888
+ from_man_exp(r, -wp), prec, rnd)
1889
+ return mpf_exp(w, prec, rnd)
1890
+ if type == 2:
1891
+ if r:
1892
+ return mpf_div(from_man_exp(r, -wp),
1893
+ mpf_exp(w, wp), prec, rnd)
1894
+ return mpf_exp(mpf_neg(w), prec, rnd)
1895
+ if type == 3:
1896
+ if r:
1897
+ return mpf_sub(w, mpf_log(from_man_exp(r,-wp), wp), prec, rnd)
1898
+ return mpf_pos(w, prec, rnd)
1899
+
1900
+
1901
+ def mpc_gamma(z, prec, rnd='d', type=0):
1902
+ a, b = z
1903
+ asign, aman, aexp, abc = a
1904
+ bsign, bman, bexp, bbc = b
1905
+
1906
+ if b == fzero:
1907
+ # Imaginary part on negative half-axis for log-gamma function
1908
+ if type == 3 and asign:
1909
+ re = mpf_gamma(a, prec, rnd, 3)
1910
+ n = (-aman) >> (-aexp)
1911
+ im = mpf_mul_int(mpf_pi(prec+10), n, prec, rnd)
1912
+ return re, im
1913
+ return mpf_gamma(a, prec, rnd, type), fzero
1914
+
1915
+ # Some kind of complex inf/nan
1916
+ if (not aman and aexp) or (not bman and bexp):
1917
+ return (fnan, fnan)
1918
+
1919
+ # Initial working precision
1920
+ wp = prec + 20
1921
+
1922
+ amag = aexp+abc
1923
+ bmag = bexp+bbc
1924
+ if aman:
1925
+ mag = max(amag, bmag)
1926
+ else:
1927
+ mag = bmag
1928
+
1929
+ # Close to 0
1930
+ if mag < -8:
1931
+ if mag < -wp:
1932
+ # 1/gamma(z) = z + euler*z^2 + O(z^3)
1933
+ v = mpc_add(z, mpc_mul_mpf(mpc_mul(z,z,wp),mpf_euler(wp),wp), wp)
1934
+ if type == 0: return mpc_reciprocal(v, prec, rnd)
1935
+ if type == 1: return mpc_div(z, v, prec, rnd)
1936
+ if type == 2: return mpc_pos(v, prec, rnd)
1937
+ if type == 3: return mpc_log(mpc_reciprocal(v, prec), prec, rnd)
1938
+ elif type != 1:
1939
+ wp += (-mag)
1940
+
1941
+ # Handle huge log-gamma values; must do this before converting to
1942
+ # a fixed-point value. TODO: determine a precise cutoff of validity
1943
+ # depending on amag and bmag
1944
+ if type == 3 and mag > wp and ((not asign) or (bmag >= amag)):
1945
+ return mpc_sub(mpc_mul(z, mpc_log(z, wp), wp), z, prec, rnd)
1946
+
1947
+ # From now on, we assume having a gamma function
1948
+ if type == 1:
1949
+ return mpc_gamma((mpf_add(a, fone), b), prec, rnd, 0)
1950
+
1951
+ an = abs(to_int(a))
1952
+ bn = abs(to_int(b))
1953
+ absn = max(an, bn)
1954
+ gamma_size = absn*mag
1955
+ if type == 3:
1956
+ pass
1957
+ else:
1958
+ wp += bitcount(gamma_size)
1959
+
1960
+ # Reflect to the right half-plane. Note that Stirling's expansion
1961
+ # is valid in the left half-plane too, as long as we're not too close
1962
+ # to the real axis, but in order to use this argument reduction
1963
+ # in the negative direction must be implemented.
1964
+ #need_reflection = asign and ((bmag < 0) or (amag-bmag > 4))
1965
+ need_reflection = asign
1966
+ zorig = z
1967
+ if need_reflection:
1968
+ z = mpc_neg(z)
1969
+ asign, aman, aexp, abc = a = z[0]
1970
+ bsign, bman, bexp, bbc = b = z[1]
1971
+
1972
+ # Imaginary part very small compared to real one?
1973
+ yfinal = 0
1974
+ balance_prec = 0
1975
+ if bmag < -10:
1976
+ # Check z ~= 1 and z ~= 2 for loggamma
1977
+ if type == 3:
1978
+ zsub1 = mpc_sub_mpf(z, fone)
1979
+ if zsub1[0] == fzero:
1980
+ cancel1 = -bmag
1981
+ else:
1982
+ cancel1 = -max(zsub1[0][2]+zsub1[0][3], bmag)
1983
+ if cancel1 > wp:
1984
+ pi = mpf_pi(wp)
1985
+ x = mpc_mul_mpf(zsub1, pi, wp)
1986
+ x = mpc_mul(x, x, wp)
1987
+ x = mpc_div_mpf(x, from_int(12), wp)
1988
+ y = mpc_mul_mpf(zsub1, mpf_neg(mpf_euler(wp)), wp)
1989
+ yfinal = mpc_add(x, y, wp)
1990
+ if not need_reflection:
1991
+ return mpc_pos(yfinal, prec, rnd)
1992
+ elif cancel1 > 0:
1993
+ wp += cancel1
1994
+ zsub2 = mpc_sub_mpf(z, ftwo)
1995
+ if zsub2[0] == fzero:
1996
+ cancel2 = -bmag
1997
+ else:
1998
+ cancel2 = -max(zsub2[0][2]+zsub2[0][3], bmag)
1999
+ if cancel2 > wp:
2000
+ pi = mpf_pi(wp)
2001
+ t = mpf_sub(mpf_mul(pi, pi), from_int(6))
2002
+ x = mpc_mul_mpf(mpc_mul(zsub2, zsub2, wp), t, wp)
2003
+ x = mpc_div_mpf(x, from_int(12), wp)
2004
+ y = mpc_mul_mpf(zsub2, mpf_sub(fone, mpf_euler(wp)), wp)
2005
+ yfinal = mpc_add(x, y, wp)
2006
+ if not need_reflection:
2007
+ return mpc_pos(yfinal, prec, rnd)
2008
+ elif cancel2 > 0:
2009
+ wp += cancel2
2010
+ if bmag < -wp:
2011
+ # Compute directly from the real gamma function.
2012
+ pp = 2*(wp+10)
2013
+ aabs = mpf_abs(a)
2014
+ eps = mpf_shift(fone, amag-wp)
2015
+ x1 = mpf_gamma(aabs, pp, type=type)
2016
+ x2 = mpf_gamma(mpf_add(aabs, eps), pp, type=type)
2017
+ xprime = mpf_div(mpf_sub(x2, x1, pp), eps, pp)
2018
+ y = mpf_mul(b, xprime, prec, rnd)
2019
+ yfinal = (x1, y)
2020
+ # Note: we still need to use the reflection formula for
2021
+ # near-poles, and the correct branch of the log-gamma function
2022
+ if not need_reflection:
2023
+ return mpc_pos(yfinal, prec, rnd)
2024
+ else:
2025
+ balance_prec += (-bmag)
2026
+
2027
+ wp += balance_prec
2028
+ n_for_stirling = int(GAMMA_STIRLING_BETA*wp)
2029
+ need_reduction = absn < n_for_stirling
2030
+
2031
+ afix = to_fixed(a, wp)
2032
+ bfix = to_fixed(b, wp)
2033
+
2034
+ r = 0
2035
+ if not yfinal:
2036
+ zprered = z
2037
+ # Argument reduction
2038
+ if absn < n_for_stirling:
2039
+ absn = complex(an, bn)
2040
+ d = int((1 + n_for_stirling**2 - bn**2)**0.5 - an)
2041
+ rre = one = MPZ_ONE << wp
2042
+ rim = MPZ_ZERO
2043
+ for k in xrange(d):
2044
+ rre, rim = ((afix*rre-bfix*rim)>>wp), ((afix*rim + bfix*rre)>>wp)
2045
+ afix += one
2046
+ r = from_man_exp(rre, -wp), from_man_exp(rim, -wp)
2047
+ a = from_man_exp(afix, -wp)
2048
+ z = a, b
2049
+
2050
+ yre, yim = complex_stirling_series(afix, bfix, wp)
2051
+ # (z-1/2)*log(z) + S
2052
+ lre, lim = mpc_log(z, wp)
2053
+ lre = to_fixed(lre, wp)
2054
+ lim = to_fixed(lim, wp)
2055
+ yre = ((lre*afix - lim*bfix)>>wp) - (lre>>1) + yre
2056
+ yim = ((lre*bfix + lim*afix)>>wp) - (lim>>1) + yim
2057
+ y = from_man_exp(yre, -wp), from_man_exp(yim, -wp)
2058
+
2059
+ if r and type == 3:
2060
+ # If re(z) > 0 and abs(z) <= 4, the branches of loggamma(z)
2061
+ # and log(gamma(z)) coincide. Otherwise, use the zeroth order
2062
+ # Stirling expansion to compute the correct imaginary part.
2063
+ y = mpc_sub(y, mpc_log(r, wp), wp)
2064
+ zfa = to_float(zprered[0])
2065
+ zfb = to_float(zprered[1])
2066
+ zfabs = math.hypot(zfa,zfb)
2067
+ #if not (zfa > 0.0 and zfabs <= 4):
2068
+ yfb = to_float(y[1])
2069
+ u = math.atan2(zfb, zfa)
2070
+ if zfabs <= 0.5:
2071
+ gi = 0.577216*zfb - u
2072
+ else:
2073
+ gi = -zfb - 0.5*u + zfa*u + zfb*math.log(zfabs)
2074
+ n = int(math.floor((gi-yfb)/(2*math.pi)+0.5))
2075
+ y = (y[0], mpf_add(y[1], mpf_mul_int(mpf_pi(wp), 2*n, wp), wp))
2076
+
2077
+ if need_reflection:
2078
+ if type == 0 or type == 2:
2079
+ A = mpc_mul(mpc_sin_pi(zorig, wp), zorig, wp)
2080
+ B = (mpf_neg(mpf_pi(wp)), fzero)
2081
+ if yfinal:
2082
+ if type == 2:
2083
+ A = mpc_div(A, yfinal, wp)
2084
+ else:
2085
+ A = mpc_mul(A, yfinal, wp)
2086
+ else:
2087
+ A = mpc_mul(A, mpc_exp(y, wp), wp)
2088
+ if r:
2089
+ B = mpc_mul(B, r, wp)
2090
+ if type == 0: return mpc_div(B, A, prec, rnd)
2091
+ if type == 2: return mpc_div(A, B, prec, rnd)
2092
+
2093
+ # Reflection formula for the log-gamma function with correct branch
2094
+ # http://functions.wolfram.com/GammaBetaErf/LogGamma/16/01/01/0006/
2095
+ # LogGamma[z] == -LogGamma[-z] - Log[-z] +
2096
+ # Sign[Im[z]] Floor[Re[z]] Pi I + Log[Pi] -
2097
+ # Log[Sin[Pi (z - Floor[Re[z]])]] -
2098
+ # Pi I (1 - Abs[Sign[Im[z]]]) Abs[Floor[Re[z]]]
2099
+ if type == 3:
2100
+ if yfinal:
2101
+ s1 = mpc_neg(yfinal)
2102
+ else:
2103
+ s1 = mpc_neg(y)
2104
+ # s -= log(-z)
2105
+ s1 = mpc_sub(s1, mpc_log(mpc_neg(zorig), wp), wp)
2106
+ # floor(re(z))
2107
+ rezfloor = mpf_floor(zorig[0])
2108
+ imzsign = mpf_sign(zorig[1])
2109
+ pi = mpf_pi(wp)
2110
+ t = mpf_mul(pi, rezfloor)
2111
+ t = mpf_mul_int(t, imzsign, wp)
2112
+ s1 = (s1[0], mpf_add(s1[1], t, wp))
2113
+ s1 = mpc_add_mpf(s1, mpf_log(pi, wp), wp)
2114
+ t = mpc_sin_pi(mpc_sub_mpf(zorig, rezfloor), wp)
2115
+ t = mpc_log(t, wp)
2116
+ s1 = mpc_sub(s1, t, wp)
2117
+ # Note: may actually be unused, because we fall back
2118
+ # to the mpf_ function for real arguments
2119
+ if not imzsign:
2120
+ t = mpf_mul(pi, mpf_floor(rezfloor), wp)
2121
+ s1 = (s1[0], mpf_sub(s1[1], t, wp))
2122
+ return mpc_pos(s1, prec, rnd)
2123
+ else:
2124
+ if type == 0:
2125
+ if r:
2126
+ return mpc_div(mpc_exp(y, wp), r, prec, rnd)
2127
+ return mpc_exp(y, prec, rnd)
2128
+ if type == 2:
2129
+ if r:
2130
+ return mpc_div(r, mpc_exp(y, wp), prec, rnd)
2131
+ return mpc_exp(mpc_neg(y), prec, rnd)
2132
+ if type == 3:
2133
+ return mpc_pos(y, prec, rnd)
2134
+
2135
+ def mpf_factorial(x, prec, rnd='d'):
2136
+ return mpf_gamma(x, prec, rnd, 1)
2137
+
2138
+ def mpc_factorial(x, prec, rnd='d'):
2139
+ return mpc_gamma(x, prec, rnd, 1)
2140
+
2141
+ def mpf_rgamma(x, prec, rnd='d'):
2142
+ return mpf_gamma(x, prec, rnd, 2)
2143
+
2144
+ def mpc_rgamma(x, prec, rnd='d'):
2145
+ return mpc_gamma(x, prec, rnd, 2)
2146
+
2147
+ def mpf_loggamma(x, prec, rnd='d'):
2148
+ sign, man, exp, bc = x
2149
+ if sign:
2150
+ raise ComplexResult
2151
+ return mpf_gamma(x, prec, rnd, 3)
2152
+
2153
+ def mpc_loggamma(z, prec, rnd='d'):
2154
+ a, b = z
2155
+ asign, aman, aexp, abc = a
2156
+ bsign, bman, bexp, bbc = b
2157
+ if b == fzero and asign:
2158
+ re = mpf_gamma(a, prec, rnd, 3)
2159
+ n = (-aman) >> (-aexp)
2160
+ im = mpf_mul_int(mpf_pi(prec+10), n, prec, rnd)
2161
+ return re, im
2162
+ return mpc_gamma(z, prec, rnd, 3)
2163
+
2164
+ def mpf_gamma_int(n, prec, rnd=round_fast):
2165
+ if n < SMALL_FACTORIAL_CACHE_SIZE:
2166
+ return mpf_pos(small_factorial_cache[n-1], prec, rnd)
2167
+ return mpf_gamma(from_int(n), prec, rnd)