Skip to content

Commit 1a88bb4

Browse files
committed
Fix ellwp(flag=1) bug
1 parent 8f8ec55 commit 1a88bb4

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

cypari2/gen.pyx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,37 @@ from .auto_paridecl cimport *
8686

8787
include 'auto_gen.pxi'
8888

89+
90+
cdef bint ellwp_flag1_bug = -1
91+
cdef inline bint have_ellwp_flag1_bug():
92+
"""
93+
The PARI function ``ellwp(..., flag=1)`` has a bug in PARI versions
94+
up to 2.9.3 where the derivative is a factor 2 too small.
95+
96+
This function does a cached check for this bug, returning 1 if
97+
the bug is there and 0 if not.
98+
"""
99+
global ellwp_flag1_bug
100+
if ellwp_flag1_bug >= 0:
101+
return ellwp_flag1_bug
102+
103+
# Check whether our PARI/GP version is buggy or not. This
104+
# computation should return 1.0, but in older PARI versions it
105+
# returns 0.5.
106+
sig_on()
107+
cdef GEN res = gp_read_str(b"localbitprec(128); my(E=ellinit([0,1/4])); ellwp(E,ellpointtoz(E,[0,1/2]),1)[2]")
108+
cdef double d = gtodouble(res)
109+
sig_off()
110+
111+
if d == 1.0:
112+
ellwp_flag1_bug = 0
113+
elif d == 0.5:
114+
ellwp_flag1_bug = 1
115+
else:
116+
raise AssertionError(f"unexpected result from ellwp() test: {d}")
117+
return ellwp_flag1_bug
118+
119+
89120
@cython.final
90121
cdef class Gen(Gen_auto):
91122
"""
@@ -4736,18 +4767,24 @@ cdef class Gen(Gen_auto):
47364767
With flag=1, compute the pair P(z) and P'(z):
47374768
47384769
>>> E.ellwp(1, flag=1)
4739-
[13.9658695257485, 50.5619300880073]
4770+
[13.9658695257485, 101.123860176015]
47404771
"""
47414772
cdef Gen t0 = objtogen(z)
47424773
cdef GEN g0 = t0.g
47434774

4744-
# Emulate toser_i() but with given precision
47454775
sig_on()
4776+
# Polynomial or rational function as input:
4777+
# emulate toser_i() but with given precision
47464778
if typ(g0) == t_POL:
47474779
g0 = RgX_to_ser(g0, n+4)
47484780
elif typ(g0) == t_RFRAC:
47494781
g0 = rfrac_to_ser(g0, n+4)
4750-
return new_gen(ellwp0(self.g, g0, flag, prec_bits_to_words(precision)))
4782+
4783+
cdef GEN r = ellwp0(self.g, g0, flag, prec_bits_to_words(precision))
4784+
if flag == 1 and have_ellwp_flag1_bug():
4785+
# Work around ellwp() bug: double the second element
4786+
set_gel(r, 2, gmulgs(gel(r, 2), 2))
4787+
return new_gen(r)
47514788

47524789
def debug(self, long depth = -1):
47534790
r"""

0 commit comments

Comments
 (0)