Skip to content

Commit c181496

Browse files
committed
Refactor is_exact for period lattice
1 parent 274f78f commit c181496

File tree

2 files changed

+49
-26
lines changed

2 files changed

+49
-26
lines changed

src/sage/schemes/elliptic_curves/ell_field.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,10 +1548,14 @@ def period_lattice(self):
15481548
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + x + 6 over Rational Field
15491549
sage: EllipticCurve(RR, [1, 6]).period_lattice()
15501550
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 6.00000000000000 over Real Field with 53 bits of precision
1551+
sage: EllipticCurve(RDF, [1, 6]).period_lattice()
1552+
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.0*x + 6.0 over Real Double Field
15511553
sage: EllipticCurve(RealField(100), [1, 6]).period_lattice()
15521554
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.0000000000000000000000000000*x + 6.0000000000000000000000000000 over Real Field with 100 bits of precision
15531555
sage: EllipticCurve(CC, [1, 6]).period_lattice()
15541556
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 6.00000000000000 over Complex Field with 53 bits of precision
1557+
sage: EllipticCurve(CDF, [1, 6]).period_lattice()
1558+
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.0*x + 6.0 over Complex Double Field
15551559
sage: EllipticCurve(ComplexField(100), [1, 6]).period_lattice()
15561560
Period lattice associated to Elliptic Curve defined by y^2 = x^3 + 1.0000000000000000000000000000*x + 6.0000000000000000000000000000 over Complex Field with 100 bits of precision
15571561
sage: EllipticCurve(AA, [1, 6]).period_lattice()

src/sage/schemes/elliptic_curves/period_lattice.py

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108

109109
import sage.rings.abc
110110

111+
from sage.categories.morphism import IdentityMorphism
111112
from sage.misc.cachefunc import cached_method
112113
from sage.misc.lazy_import import lazy_import
113114
from sage.modules.free_module import FreeModule_generic_pid
@@ -116,7 +117,7 @@
116117
from sage.rings.integer_ring import ZZ
117118
from sage.rings.qqbar import AA, QQbar
118119
from sage.rings.rational_field import QQ
119-
from sage.rings.real_mpfr import RealField, RealField_class, RealNumber
120+
from sage.rings.real_mpfr import RealField, RealNumber
120121
from sage.schemes.elliptic_curves.constructor import EllipticCurve
121122
from sage.structure.richcmp import richcmp_method, richcmp, richcmp_not_equal
122123

@@ -231,14 +232,14 @@ def __init__(self, E, embedding=None):
231232
# the given embedding:
232233

233234
K = E.base_field()
234-
self.is_approximate = isinstance(K, (RealField_class, ComplexField_class))
235+
self._is_exact = K.is_exact()
235236
if embedding is None:
236237
if K in (AA, QQbar):
237238
embedding = K.hom(QQbar)
238239
real = K == AA
239-
elif self.is_approximate:
240-
embedding = K.hom(K)
241-
real = isinstance(K, RealField_class)
240+
elif not self._is_exact:
241+
embedding = IdentityMorphism(K)
242+
real = isinstance(K, (sage.rings.abc.RealField, sage.rings.abc.RealDoubleField))
242243
else:
243244
embs = K.embeddings(AA)
244245
real = len(embs) > 0
@@ -271,24 +272,24 @@ def __init__(self, E, embedding=None):
271272
# The ei are used both for period computation and elliptic
272273
# logarithms.
273274

274-
if self.is_approximate:
275-
self.f2 = self.E.two_division_polynomial()
276-
else:
275+
if self._is_exact:
277276
self.Ebar = self.E.change_ring(self.embedding)
278277
self.f2 = self.Ebar.two_division_polynomial()
278+
else:
279+
self.f2 = self.E.two_division_polynomial()
279280
if self.real_flag == 1: # positive discriminant
280-
self._ei = self.f2.roots(K if self.is_approximate else AA,multiplicities=False)
281+
self._ei = self.f2.roots(AA if self._is_exact else K, multiplicities=False)
281282
self._ei.sort() # e1 < e2 < e3
282283
e1, e2, e3 = self._ei
283284
elif self.real_flag == -1: # negative discriminant
284-
self._ei = self.f2.roots(ComplexField(K.precision()) if self.is_approximate else QQbar, multiplicities=False)
285+
self._ei = self.f2.roots(QQbar if self._is_exact else ComplexField(K.precision()), multiplicities=False)
285286
self._ei = sorted(self._ei, key=lambda z: z.imag())
286287
e1, e3, e2 = self._ei # so e3 is real
287-
if not self.is_approximate:
288+
if self._is_exact:
288289
e3 = AA(e3)
289290
self._ei = [e1, e2, e3]
290291
else:
291-
self._ei = self.f2.roots(ComplexField(K.precision()) if self.is_approximate else QQbar, multiplicities=False)
292+
self._ei = self.f2.roots(QQbar if self._is_exact else ComplexField(K.precision()), multiplicities=False)
292293
e1, e2, e3 = self._ei
293294

294295
# The quantities sqrt(e_i-e_j) are cached (as elements of
@@ -350,7 +351,7 @@ def __repr__(self):
350351
Defn: a |--> 1.259921049894873?
351352
"""
352353
K = self.E.base_field()
353-
if K in (QQ, AA, QQbar) or isinstance(K, (RealField_class, ComplexField_class)):
354+
if K in (QQ, AA, QQbar) or isinstance(self.embedding, IdentityMorphism):
354355
return "Period lattice associated to %s" % (self.E)
355356
return "Period lattice associated to %s with respect to the embedding %s" % (self.E, self.embedding)
356357

@@ -656,7 +657,7 @@ def _compute_default_prec(self):
656657
r"""
657658
Internal function to compute the default precision to be used if nothing is passed in.
658659
"""
659-
return self.E.base_field().precision() if self.is_approximate else RealField().precision()
660+
return RealField().precision() if self._is_exact else self.E.base_field().precision()
660661

661662
@cached_method
662663
def _compute_periods_real(self, prec=None, algorithm='sage'):
@@ -704,7 +705,7 @@ def _compute_periods_real(self, prec=None, algorithm='sage'):
704705

705706
if algorithm == 'pari':
706707
ainvs = self.E.a_invariants()
707-
if self.E.base_field() is not QQ and not self.is_approximate:
708+
if self.E.base_field() is not QQ and self._is_exact:
708709
ainvs = [C(self.embedding(ai)).real() for ai in ainvs]
709710

710711
# The precision for omega() is determined by ellinit()
@@ -716,7 +717,7 @@ def _compute_periods_real(self, prec=None, algorithm='sage'):
716717
raise ValueError("invalid value of 'algorithm' parameter")
717718

718719
pi = R.pi()
719-
# Up to now everything has been exact in AA or QQbar (unless self.is_approximate),
720+
# Up to now everything has been exact in AA or QQbar (if self._is_exact),
720721
# but now we must go transcendental. Only now is the desired precision used!
721722
if self.real_flag == 1: # positive discriminant
722723
a, b, c = (R(x) for x in self._abc)
@@ -788,7 +789,7 @@ def _compute_periods_complex(self, prec=None, normalise=True):
788789
prec = self._compute_default_prec()
789790
C = ComplexField(prec)
790791

791-
# Up to now everything has been exact in AA or QQbar (unless self.is_approximate),
792+
# Up to now everything has been exact in AA or QQbar (if self._is_exact),
792793
# but now we must go transcendental. Only now is the desired precision used!
793794
pi = C.pi()
794795
a, b, c = (C(x) for x in self._abc)
@@ -1757,10 +1758,19 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
17571758
sage: L.real_flag
17581759
-1
17591760
sage: P = E(3, 6)
1760-
sage: L.elliptic_logarithm(P)
1761+
sage: L.elliptic_logarithm(P) # abs tol 1e-26
17611762
2.4593388737550379526023682666
1762-
sage: L.elliptic_exponential(_)
1763+
sage: L.elliptic_exponential(_) # abs tol 1e-26
17631764
(3.0000000000000000000000000000 : 5.9999999999999999999999999999 : 1.0000000000000000000000000000)
1765+
sage: E = EllipticCurve(RDF, [1, 6])
1766+
sage: L = E.period_lattice()
1767+
sage: L.real_flag
1768+
-1
1769+
sage: P = E(3, 6)
1770+
sage: L.elliptic_logarithm(P) # abs tol 1e-13
1771+
2.45933887375504
1772+
sage: L.elliptic_exponential(_) # abs tol 1e-13
1773+
(3.00000000000000 : 6.00000000000001 : 1.00000000000000)
17641774
17651775
Real approximate field, positive discriminant::
17661776
@@ -1769,9 +1779,9 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
17691779
sage: L.real_flag
17701780
1
17711781
sage: P = E.lift_x(4)
1772-
sage: L.elliptic_logarithm(P)
1782+
sage: L.elliptic_logarithm(P) # abs tol 1e-26
17731783
0.51188849089267627141925354967
1774-
sage: L.elliptic_exponential(_)
1784+
sage: L.elliptic_exponential(_) # abs tol 1e-26
17751785
(4.0000000000000000000000000000 : -7.1414284285428499979993998114 : 1.0000000000000000000000000000)
17761786
17771787
Complex approximate field::
@@ -1781,10 +1791,19 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
17811791
sage: L.real_flag
17821792
0
17831793
sage: P = E.lift_x(4)
1784-
sage: L.elliptic_logarithm(P)
1794+
sage: L.elliptic_logarithm(P) # abs tol 1e-26
17851795
-1.1447032790074574712147458157 - 0.72429843602171875396186134806*I
1786-
sage: L.elliptic_exponential(_)
1796+
sage: L.elliptic_exponential(_) # abs tol 1e-26
17871797
(4.0000000000000000000000000000 + 1.2025589033682610849950210280e-30*I : -8.2570982991257407680322611854 - 0.42387771989714340809597881586*I : 1.0000000000000000000000000000)
1798+
sage: E = EllipticCurve(CDF, [I, 3*I+4])
1799+
sage: L = E.period_lattice()
1800+
sage: L.real_flag
1801+
0
1802+
sage: P = E.lift_x(4)
1803+
sage: L.elliptic_logarithm(P) # abs tol 1e-13
1804+
-1.14470327900746 - 0.724298436021719*I
1805+
sage: L.elliptic_exponential(_) # abs tol 1e-13
1806+
(4.00000000000000 - 0*I : -8.25709829912574 - 0.423877719897148*I : 1.00000000000000)
17881807
"""
17891808
if P.curve() is not self.E:
17901809
raise ValueError("Point is on the wrong curve")
@@ -2002,10 +2021,10 @@ def elliptic_exponential(self, z, to_curve=True):
20022021

20032022
if to_curve:
20042023
K = x.parent()
2005-
if self.is_approximate:
2006-
v = self.embedding
2007-
else:
2024+
if self._is_exact:
20082025
v = refine_embedding(self.embedding, Infinity)
2026+
else:
2027+
v = self.embedding
20092028
a1, a2, a3, a4, a6 = (K(v(a)) for a in self.E.ainvs())
20102029
b2 = K(v(self.E.b2()))
20112030
x = x - b2 / 12

0 commit comments

Comments
 (0)