2
This module implements computation of hypergeometric and related
3
functions. In particular, it provides code for generic summation
4
of hypergeometric series. Optimized versions for various special
5
cases are also provided.
10
from .backend import MPZ_ONE, MPZ_ZERO
11
from .gammazeta import euler_fixed, mpf_euler, mpf_gamma_int
12
from .libelefun import (agm_fixed, mpf_cos_sin, mpf_exp, mpf_log, mpf_pi,
13
mpf_sin, mpf_sqrt, pi_fixed)
14
from .libintmath import ifac, sqrt_fixed
15
from .libmpc import (complex_int_pow, mpc_abs, mpc_add, mpc_add_mpf, mpc_div,
16
mpc_exp, mpc_is_infnan, mpc_log, mpc_mpf_div, mpc_mul,
17
mpc_neg, mpc_one, mpc_pos, mpc_shift, mpc_sqrt, mpc_sub,
19
from .libmpf import (ComplexResult, finf, fnan, fninf, fnone, fone, from_int,
20
from_man_exp, from_rational, ftwo, fzero, mpf_abs,
21
mpf_add, mpf_div, mpf_le, mpf_lt, mpf_min_max, mpf_mul,
22
mpf_neg, mpf_perturb, mpf_pos, mpf_pow_int, mpf_shift,
23
mpf_sign, mpf_sqrt, mpf_sub, negative_rnd, round_fast,
27
class NoConvergence(Exception):
41
2. imaginary z special-cased (also: rational, integer?)
42
3. more clever handling of series that don't converge because of stupid
44
4. checking for cancellation
48
def make_hyp_summator(key):
50
Returns a function that sums a generalized hypergeometric series,
51
for given parameter types (integer, rational, real, complex).
54
p, q, param_types, ztype = key
56
pstring = "".join(param_types)
57
fname = "hypsum_%i_%i_%s_%s_%s" % (p, q, pstring[:p], pstring[p:], ztype)
60
have_complex_param = 'C' in param_types
61
have_complex_arg = ztype == 'C'
62
have_complex = have_complex_param or have_complex_arg
77
add("MAX = kwargs.get('maxterms', wp*100)")
78
add("HIGH = MPZ_ONE<<epsshift")
82
add("SRE = PRE = one = (MPZ_ONE << wp)")
84
add("SIM = PIM = MPZ_ZERO")
87
add("xsign, xm, xe, xbc = z[0]")
88
add("if xsign: xm = -xm")
89
add("ysign, ym, ye, ybc = z[1]")
90
add("if ysign: ym = -ym")
92
add("xsign, xm, xe, xbc = z")
93
add("if xsign: xm = -xm")
95
add("offset = xe + wp")
96
add("if offset >= 0:")
97
add(" ZRE = xm << offset")
99
add(" ZRE = xm >> (-offset)")
101
add("offset = ye + wp")
102
add("if offset >= 0:")
103
add(" ZIM = ym << offset")
105
add(" ZIM = ym >> (-offset)")
107
for i, flag in enumerate(param_types):
108
W = ["A", "B"][i >= p]
110
([aint,bint][i >= p]).append(i)
111
add("%sINT_%i = coeffs[%i]" % (W, i, i))
113
([arat,brat][i >= p]).append(i)
114
add("%sP_%i, %sQ_%i = coeffs[%i].numerator, coeffs[%i].denominator" % (W, i, W, i, i, i))
116
([areal,breal][i >= p]).append(i)
117
add("xsign, xm, xe, xbc = coeffs[%i]._mpf_" % i)
118
add("if xsign: xm = -xm")
119
add("offset = xe + wp")
120
add("if offset >= 0:")
121
add(" %sREAL_%i = xm << offset" % (W, i))
123
add(" %sREAL_%i = xm >> (-offset)" % (W, i))
125
([acomplex,bcomplex][i >= p]).append(i)
126
add("__re, __im = coeffs[%i]._mpc_" % i)
127
add("xsign, xm, xe, xbc = __re")
128
add("if xsign: xm = -xm")
129
add("ysign, ym, ye, ybc = __im")
130
add("if ysign: ym = -ym")
132
add("offset = xe + wp")
133
add("if offset >= 0:")
134
add(" %sCRE_%i = xm << offset" % (W, i))
136
add(" %sCRE_%i = xm >> (-offset)" % (W, i))
137
add("offset = ye + wp")
138
add("if offset >= 0:")
139
add(" %sCIM_%i = ym << offset" % (W, i))
141
add(" %sCIM_%i = ym >> (-offset)" % (W, i))
147
cancellable_real = min(l_areal, l_breal)
148
noncancellable_real_num = areal[cancellable_real:]
149
noncancellable_real_den = breal[cancellable_real:]
152
add("for n in range(1,10**8):")
154
add(" if n in magnitude_check:")
155
add(" p_mag = PRE.bit_length()")
157
add(" p_mag = max(p_mag, PIM.bit_length())")
158
add(" magnitude_check[n] = wp-p_mag")
161
multiplier = " * ".join(["AINT_#".replace("#", str(i)) for i in aint] + \
162
["AP_#".replace("#", str(i)) for i in arat] + \
163
["BQ_#".replace("#", str(i)) for i in brat])
165
divisor = " * ".join(["BINT_#".replace("#", str(i)) for i in bint] + \
166
["BP_#".replace("#", str(i)) for i in brat] + \
167
["AQ_#".replace("#", str(i)) for i in arat] + ["n"])
170
add(" mul = " + multiplier)
171
add(" div = " + divisor)
178
add(" raise ZeroDivisionError")
186
for k in range(cancellable_real): add(" PRE = PRE * AREAL_%i // BREAL_%i" % (areal[k], breal[k]))
187
for i in noncancellable_real_num: add(" PRE = (PRE * AREAL_#) >> wp".replace("#", str(i)))
188
for i in noncancellable_real_den: add(" PRE = (PRE << wp) // BREAL_#".replace("#", str(i)))
189
for k in range(cancellable_real): add(" PIM = PIM * AREAL_%i // BREAL_%i" % (areal[k], breal[k]))
190
for i in noncancellable_real_num: add(" PIM = (PIM * AREAL_#) >> wp".replace("#", str(i)))
191
for i in noncancellable_real_den: add(" PIM = (PIM << wp) // BREAL_#".replace("#", str(i)))
195
add(" PRE, PIM = (mul*(PRE*ZRE-PIM*ZIM))//div, (mul*(PIM*ZRE+PRE*ZIM))//div")
199
add(" PRE = ((mul * PRE * ZRE) >> wp) // div")
200
add(" PIM = ((mul * PIM * ZRE) >> wp) // div")
203
add(" PRE, PIM = (PRE*ZRE-PIM*ZIM)//div, (PIM*ZRE+PRE*ZIM)//div")
207
add(" PRE = ((PRE * ZRE) >> wp) // div")
208
add(" PIM = ((PIM * ZRE) >> wp) // div")
211
add(" PRE, PIM = PRE*ACRE_#-PIM*ACIM_#, PIM*ACRE_#+PRE*ACIM_#".replace("#", str(i)))
216
add(" mag = BCRE_#*BCRE_#+BCIM_#*BCIM_#".replace("#", str(i)))
217
add(" re = PRE*BCRE_# + PIM*BCIM_#".replace("#", str(i)))
218
add(" im = PIM*BCRE_# - PRE*BCIM_#".replace("#", str(i)))
219
add(" PRE = (re << wp) // mag".replace("#", str(i)))
220
add(" PIM = (im << wp) // mag".replace("#", str(i)))
223
for k in range(cancellable_real): add(" PRE = PRE * AREAL_%i // BREAL_%i" % (areal[k], breal[k]))
224
for i in noncancellable_real_num: add(" PRE = (PRE * AREAL_#) >> wp".replace("#", str(i)))
225
for i in noncancellable_real_den: add(" PRE = (PRE << wp) // BREAL_#".replace("#", str(i)))
227
add(" PRE = ((PRE * mul * ZRE) >> wp) // div")
229
add(" PRE = ((PRE * ZRE) >> wp) // div")
235
add(" if (HIGH > PRE > LOW) and (HIGH > PIM > LOW):")
239
add(" if HIGH > PRE > LOW:")
246
add(" raise NoConvergence('Hypergeometric series converges too slowly. Try increasing maxterms.')")
249
for i in aint: add(" AINT_# += 1".replace("#", str(i)))
250
for i in bint: add(" BINT_# += 1".replace("#", str(i)))
251
for i in arat: add(" AP_# += AQ_#".replace("#", str(i)))
252
for i in brat: add(" BP_# += BQ_#".replace("#", str(i)))
253
for i in areal: add(" AREAL_# += one".replace("#", str(i)))
254
for i in breal: add(" BREAL_# += one".replace("#", str(i)))
255
for i in acomplex: add(" ACRE_# += one".replace("#", str(i)))
256
for i in bcomplex: add(" BCRE_# += one".replace("#", str(i)))
259
add("a = from_man_exp(SRE, -wp, prec, 'n')")
260
add("b = from_man_exp(SIM, -wp, prec, 'n')")
264
add(" magn = max(a[2]+a[3], b[2]+b[3])")
266
add(" magn = a[2]+a[3]")
268
add(" magn = b[2]+b[3]")
272
add("return (a, b), True, magn")
274
add("a = from_man_exp(SRE, -wp, prec, 'n')")
277
add(" magn = a[2]+a[3]")
281
add("return a, False, magn")
283
source = "\n".join((" " + line) for line in source)
284
source = ("def %s(coeffs, z, prec, wp, epsshift, magnitude_check, **kwargs):\n" % fname) + source
288
exec(source, globals(), namespace)
291
return source, namespace[fname]
303
def mpf_erf(x, prec, rnd=round_fast):
304
sign, man, exp, bc = x
306
if x == fzero: return fzero
307
if x == finf: return fone
308
if x== fninf: return fnone
313
if size > 3 and 2*(size-1) + 0.528766 > lg(prec,2):
315
return mpf_perturb(fnone, 0, prec, rnd)
317
return mpf_perturb(fone, 1, prec, rnd)
322
c = mpf_sqrt(mpf_pi(prec+20), prec+20)
324
return mpf_div(x, c, prec, rnd)
325
wp = prec + abs(size) + 25
327
t = abs(to_fixed(x, wp))
329
s, term, k = t, 12345, 1
331
t = ((t * t2) >> wp) // k
338
s = (s << (wp+1)) // sqrt_fixed(pi_fixed(wp), wp)
341
return from_man_exp(s, -wp, prec, rnd)
348
def erfc_check_series(x, prec):
350
if n**2 * 1.44 > prec:
354
def mpf_erfc(x, prec, rnd=round_fast):
355
sign, man, exp, bc = x
357
if x == fzero: return fone
358
if x == finf: return fzero
359
if x == fninf: return ftwo
365
regular_erf = sign or mag < 2
366
if regular_erf or not erfc_check_series(x, wp):
368
return mpf_sub(fone, mpf_erf(x, prec+10, negative_rnd[rnd]), prec, rnd)
371
return mpf_sub(fone, mpf_erf(x, prec + int(n**2*1.44) + 10), prec, rnd)
372
s = term = MPZ_ONE << wp
374
t = (2 * to_fixed(x, wp) ** 2) >> wp
377
term = ((term * (2*k - 1)) << wp) // t
378
if k > 4 and term > term_prev or not term:
387
s = (s << wp) // sqrt_fixed(pi_fixed(wp), wp)
388
s = from_man_exp(s, -wp, wp)
389
z = mpf_exp(mpf_neg(mpf_mul(x,x,wp),wp),wp)
390
y = mpf_div(mpf_mul(z, s, wp), x, prec, rnd)
400
def ei_taylor(x, prec):
404
t = ((t*x) >> prec) // k
409
def complex_ei_taylor(zre, zim, prec):
414
while _abs(tre) + _abs(tim) > 5:
415
tre, tim = ((tre*zre-tim*zim)//k)>>prec, ((tre*zim+tim*zre)//k)>>prec
421
def ei_asymptotic(x, prec):
422
one = MPZ_ONE << prec
423
x = t = ((one << prec) // x)
432
def complex_ei_asymptotic(zre, zim, prec):
434
one = MPZ_ONE << prec
435
M = (zim*zim + zre*zre) >> prec
437
xre = tre = (zre << prec) // M
438
xim = tim = ((-zim) << prec) // M
442
while _abs(tre) + _abs(tim) > 1000:
444
tre, tim = ((tre*xre-tim*xim)*k)>>prec, ((tre*xim+tim*xre)*k)>>prec
452
def mpf_ei(x, prec, rnd=round_fast, e1=False):
455
sign, man, exp, bc = x
459
raise ComplexResult("E1(x) for x < 0")
461
xabs = 0, man, exp, bc
464
can_use_asymp = xmag > wp
465
if not can_use_asymp:
469
xabsint = man >> (-exp)
470
can_use_asymp = xabsint > int(wp*0.693) + 10
475
v = from_man_exp(ei_asymptotic(to_fixed(x, wp), wp), -wp)
476
v = mpf_mul(v, mpf_exp(x, wp), wp)
477
v = mpf_div(v, x, prec, rnd)
479
wp += 2*int(to_int(xabs))
481
v = ei_taylor(u, wp) + euler_fixed(wp)
482
t1 = from_man_exp(v,-wp)
483
t2 = mpf_log(xabs,wp)
484
v = mpf_add(t1, t2, prec, rnd)
486
if x == fzero: v = fninf
487
elif x == finf: v = finf
488
elif x == fninf: v = fzero
494
def mpc_ei(z, prec, rnd=round_fast, e1=False):
498
asign, aman, aexp, abc = a
499
bsign, bman, bexp, bbc = b
502
x = mpf_neg(mpf_ei(a, prec, rnd))
504
y = mpf_neg(mpf_pi(prec, rnd))
509
return mpf_ei(a, prec, rnd), fzero
511
if not aman or not bman:
516
zmag = max(amag, bmag)
517
can_use_asymp = zmag > wp
518
if not can_use_asymp:
519
zabsint = abs(to_int(a)) + abs(to_int(b))
520
can_use_asymp = zabsint > int(wp*0.693) + 20
526
zre = to_fixed(a, wp)
527
zim = to_fixed(b, wp)
528
vre, vim = complex_ei_asymptotic(zre, zim, wp)
529
v = from_man_exp(vre, -wp), from_man_exp(vim, -wp)
530
v = mpc_mul(v, mpc_exp(z, wp), wp)
531
v = mpc_div(v, z, wp)
533
v = mpc_neg(v, prec, rnd)
537
v = mpf_pos(x, prec, rnd), mpf_sub(y, mpf_pi(wp), prec, rnd)
539
v = mpf_pos(x, prec, rnd), mpf_add(y, mpf_pi(wp), prec, rnd)
541
except NoConvergence:
544
wp += 2*int(to_int(mpc_abs(z, 5)))
545
zre = to_fixed(a, wp)
546
zim = to_fixed(b, wp)
547
vre, vim = complex_ei_taylor(zre, zim, wp)
548
vre += euler_fixed(wp)
549
v = from_man_exp(vre,-wp), from_man_exp(vim,-wp)
551
u = mpc_log(mpc_neg(z),wp)
554
v = mpc_add(v, u, prec, rnd)
559
def mpf_e1(x, prec, rnd=round_fast):
560
return mpf_ei(x, prec, rnd, True)
562
def mpc_e1(x, prec, rnd=round_fast):
563
return mpc_ei(x, prec, rnd, True)
565
def mpf_expint(n, x, prec, rnd=round_fast, gamma=False):
567
E_n(x), n an integer, x real
569
With gamma=True, computes Gamma(n,x) (upper incomplete gamma function)
571
Returns (real, None) if real, otherwise (real, imag)
572
The imaginary part is an optional branch cut term
575
sign, man, exp, bc = x
582
return mpf_gamma_int(n, prec, rnd), None
590
return from_rational(1, n-1, prec, rnd), None
603
raise NotImplementedError
604
nmag = n.bit_length()
605
have_imag = n > 0 and sign
608
if n == 0 or 2*nmag - xmag < -wp:
610
v = mpf_exp(negx, wp)
611
re = mpf_mul(v, mpf_pow_int(x, n_orig-1, wp), prec, rnd)
613
v = mpf_exp(negx, wp)
614
re = mpf_div(v, x, prec, rnd)
617
can_use_asymptotic_series = -3*wp < n <= 0
619
if not can_use_asymptotic_series:
621
m = min(max(1, xi-n), 2*wp)
622
siz = -n*nmag + (m+n)*(m+n).bit_length() - m*xmag - (144*m//100)
624
can_use_asymptotic_series = siz < tol
625
if can_use_asymptotic_series:
626
r = ((-MPZ_ONE) << (wp+wp)) // to_fixed(x, wp)
634
v = mpf_exp(negx, wp)
637
v = mpf_mul(v, mpf_pow_int(x, n_orig-1, wp), wp)
640
v = mpf_div(v, x, wp)
641
re = mpf_mul(v, from_man_exp(s, -wp), prec, rnd)
643
re = mpf_neg(mpf_ei(negx, prec, rnd))
644
elif n > 0 and n < 3*wp:
645
T1 = mpf_neg(mpf_ei(negx, wp))
650
T1 = mpf_mul(T1, mpf_pow_int(negx, n-1, wp), wp)
651
r = t = to_fixed(x, wp)
653
for k in range(1,n-1):
654
facs[k] = facs[k-1] * k
657
for k in range(1, n-1):
663
T2 = from_man_exp(s, -wp, wp)
664
T2 = mpf_mul(T2, mpf_exp(negx, wp))
666
T2 = mpf_mul(T2, mpf_pow_int(x, n_orig, wp), wp)
668
re = mpf_div(R, from_int(ifac(n-1)), prec, rnd)
670
raise NotImplementedError
672
M = from_int(-ifac(n-1))
674
im = mpf_div(mpf_pi(wp), M, prec, rnd)
678
im = mpf_div(mpf_mul(mpf_pi(wp), mpf_pow_int(negx, n_orig-1, wp), wp), M, prec, rnd)
683
def mpf_ci_si_taylor(x, wp, which=0):
685
0 - Ci(x) - (euler+log(x))
691
s, t, k = 0, (MPZ_ONE<<wp), 2
695
t = (t*x2//(k*(k-1)))>>wp
698
return from_man_exp(s, -wp)
700
def mpc_ci_si_taylor(re, im, wp, which=0):
708
mag = max(mag, im[2]+im[3])
709
if mag > 2 or mag < -wp:
710
raise NotImplementedError
712
zre = to_fixed(re, wp)
713
zim = to_fixed(im, wp)
714
z2re = (zim*zim-zre*zre)>>wp
715
z2im = (-2*zre*zim)>>wp
720
sre, sim, tre, tim, k = 0, 0, (MPZ_ONE<<wp), 0, 2
722
sre, sim, tre, tim, k = zre, zim, zre, zim, 3
723
while max(abs(tre), abs(tim)) > 2:
725
tre, tim = ((tre*z2re-tim*z2im)//f)>>wp, ((tre*z2im+tim*z2re)//f)>>wp
729
return from_man_exp(sre, -wp), from_man_exp(sim, -wp)
731
def mpf_ci_si(x, prec, rnd=round_fast, which=2):
733
Calculation of Ci(x), Si(x) for real x.
735
which = 0 -- returns (Ci(x), -)
736
which = 1 -- returns (Si(x), -)
737
which = 2 -- returns (Ci(x), Si(x))
739
Note: if x < 0, Ci(x) needs an additional imaginary term, pi*i.
742
sign, man, exp, bc = x
746
return (fninf, fzero)
752
si = mpf_shift(mpf_pi(prec, rnd), -1)
754
si = mpf_neg(mpf_shift(mpf_pi(prec, negative_rnd[rnd]), -1))
760
si = mpf_perturb(x, 1-sign, prec, rnd)
764
ci = mpf_add(y, mpf_log(xabs, wp), prec, rnd)
770
si = mpf_neg(mpf_pi(prec, negative_rnd[rnd]))
772
si = mpf_pi(prec, rnd)
773
si = mpf_shift(si, -1)
775
ci = mpf_div(mpf_sin(x, wp), x, prec, rnd)
781
asymptotic = mag-1 > math.log(wp, 2)
785
si = mpf_pos(mpf_ci_si_taylor(x, wp, 1), prec, rnd)
787
ci = mpf_ci_si_taylor(x, wp, 0)
788
ci = mpf_add(ci, mpf_euler(wp), wp)
789
ci = mpf_add(ci, mpf_log(mpf_abs(x), wp), prec, rnd)
794
xr = (MPZ_ONE<<(2*wp)) // xf
807
s1 = from_man_exp(s1, -wp)
808
s2 = from_man_exp(s2, -wp)
809
s1 = mpf_div(s1, x, wp)
810
s2 = mpf_div(s2, x, wp)
811
cos, sin = mpf_cos_sin(x, wp)
815
si = mpf_add(mpf_mul(cos, s1), mpf_mul(sin, s2), wp)
816
si = mpf_sub(mpf_shift(mpf_pi(wp), -1), si, wp)
819
si = mpf_pos(si, prec, rnd)
821
ci = mpf_sub(mpf_mul(sin, s1), mpf_mul(cos, s2), prec, rnd)
824
def mpf_ci(x, prec, rnd=round_fast):
827
return mpf_ci_si(x, prec, rnd, 0)[0]
829
def mpf_si(x, prec, rnd=round_fast):
830
return mpf_ci_si(x, prec, rnd, 1)[1]
832
def mpc_ci(z, prec, rnd=round_fast):
835
ci = mpf_ci_si(re, prec, rnd, 0)[0]
837
return (ci, mpf_pi(prec, rnd))
840
cre, cim = mpc_ci_si_taylor(re, im, wp, 0)
841
cre = mpf_add(cre, mpf_euler(wp), wp)
842
ci = mpc_add((cre, cim), mpc_log(z, wp), prec, rnd)
845
def mpc_si(z, prec, rnd=round_fast):
848
return (mpf_ci_si(re, prec, rnd, 1)[1], fzero)
850
z = mpc_ci_si_taylor(re, im, wp, 1)
851
return mpc_pos(z, prec, rnd)
885
def mpf_besseljn(n, x, prec, rounding=round_fast):
887
negate = n < 0 and n & 1
890
wp = prec + 20 + n*n.bit_length()
896
s = t = MPZ_ONE << wp
898
s = t = (x**n // ifac(n)) >> ((n-1)*wp + n)
901
t = ((t * x2) // (-4*k*(k+n))) >> wp
906
return from_man_exp(s, -wp, prec, rounding)
908
def mpc_besseljn(n, z, prec, rounding=round_fast):
909
negate = n < 0 and n & 1
913
mag = max(zre[2]+zre[3], zim[2]+zim[3])
914
prec += 20 + n*n.bit_length() + abs(mag)
917
zre = to_fixed(zre, prec)
918
zim = to_fixed(zim, prec)
919
z2re = (zre**2 - zim**2) >> prec
920
z2im = (zre*zim) >> (prec-1)
922
sre = tre = MPZ_ONE << prec
925
re, im = complex_int_pow(zre, zim, n)
926
sre = tre = (re // ifac(n)) >> ((n-1)*prec + n)
927
sim = tim = (im // ifac(n)) >> ((n-1)*prec + n)
929
while abs(tre) + abs(tim) > 3:
931
tre, tim = tre*z2re - tim*z2im, tim*z2re + tre*z2im
932
tre = (tre // p) >> prec
933
tim = (tim // p) >> prec
940
re = from_man_exp(sre, -prec, origprec, rounding)
941
im = from_man_exp(sim, -prec, origprec, rounding)
944
def mpf_agm(a, b, prec, rnd=round_fast):
946
Computes the arithmetic-geometric mean agm(a,b) for
947
nonnegative mpf values a, b.
949
asign, aman, aexp, abc = a
950
bsign, bman, bexp, bbc = b
952
raise ComplexResult("agm of a negative number")
954
if not (aman and bman):
955
if a == fnan or b == fnan:
970
mag_delta = amag - bmag
972
abs_mag_delta = abs(mag_delta)
973
if abs_mag_delta > 10:
974
while abs_mag_delta > 10:
975
a, b = mpf_shift(mpf_add(a,b,wp),-1), \
976
mpf_sqrt(mpf_mul(a,b,wp),wp)
978
asign, aman, aexp, abc = a
979
bsign, bman, bexp, bbc = b
982
mag_delta = amag - bmag
985
min_mag = min(amag,bmag)
986
max_mag = max(amag,bmag)
1000
g = agm_fixed(af, bf, wp)
1001
return from_man_exp(g, -wp-n, prec, rnd)
1003
def mpf_agm1(a, prec, rnd=round_fast):
1005
Computes the arithmetic-geometric mean agm(1,a) for a nonnegative
1008
return mpf_agm(fone, a, prec, rnd)
1010
def mpc_agm(a, b, prec, rnd=round_fast):
1015
* check that convergence works as intended
1017
* select a nonarbitrary branch
1019
if mpc_is_infnan(a) or mpc_is_infnan(b):
1021
if mpc_zero in (a, b):
1026
eps = mpf_shift(fone, -wp+10)
1028
a1 = mpc_shift(mpc_add(a, b, wp), -1)
1029
b1 = mpc_sqrt(mpc_mul(a, b, wp), wp)
1031
size = mpf_min_max([mpc_abs(a,10), mpc_abs(b,10)])[1]
1032
err = mpc_abs(mpc_sub(a, b, 10), 10)
1033
if size == fzero or mpf_lt(err, mpf_mul(eps, size)):
1036
def mpc_agm1(a, prec, rnd=round_fast):
1037
return mpc_agm(mpc_one, a, prec, rnd)
1039
def mpf_ellipk(x, prec, rnd=round_fast):
1042
return mpf_shift(mpf_pi(prec, rnd), -1)
1054
a = mpf_sqrt(mpf_sub(fone, x, wp), wp)
1056
r = mpf_div(mpf_pi(wp), v, prec, rnd)
1057
return mpf_shift(r, -1)
1059
def mpc_ellipk(z, prec, rnd=round_fast):
1064
if mpf_le(re, fone):
1065
return mpf_ellipk(re, prec, rnd), fzero
1067
a = mpc_sqrt(mpc_sub(mpc_one, z, wp), wp)
1069
r = mpc_mpf_div(mpf_pi(wp), v, prec, rnd)
1070
return mpc_shift(r, -1)
1072
def mpf_ellipe(x, prec, rnd=round_fast):
1076
sign, man, exp, bc = x
1079
return mpf_shift(mpf_pi(prec, rnd), -1)
1091
return mpf_shift(mpf_pi(prec, rnd), -1)
1093
p = max(mag, 0) - wp
1094
h = mpf_shift(fone, p)
1095
K = mpf_ellipk(x, 2*wp)
1096
Kh = mpf_ellipk(mpf_sub(x, h), 2*wp)
1097
Kdiff = mpf_shift(mpf_sub(K, Kh), -p)
1098
t = mpf_sub(fone, x)
1099
b = mpf_mul(Kdiff, mpf_shift(x,1), wp)
1100
return mpf_mul(t, mpf_add(K, b), prec, rnd)
1102
def mpc_ellipe(z, prec, rnd=round_fast):
1106
return (fzero, finf)
1107
if mpf_le(re, fone):
1108
return mpf_ellipe(re, prec, rnd), fzero
1111
p = max(mag[2]+mag[3], 0) - wp
1112
h = mpf_shift(fone, p)
1113
K = mpc_ellipk(z, 2*wp)
1114
Kh = mpc_ellipk(mpc_add_mpf(z, h, 2*wp), 2*wp)
1115
Kdiff = mpc_shift(mpc_sub(Kh, K, wp), -p)
1116
t = mpc_sub(mpc_one, z, wp)
1117
b = mpc_mul(Kdiff, mpc_shift(z,1), wp)
1118
return mpc_mul(t, mpc_add(K, b, wp), prec, rnd)