108
108
109
109
import sage .rings .abc
110
110
111
+ from sage .categories .morphism import IdentityMorphism
111
112
from sage .misc .cachefunc import cached_method
112
113
from sage .misc .lazy_import import lazy_import
113
114
from sage .modules .free_module import FreeModule_generic_pid
116
117
from sage .rings .integer_ring import ZZ
117
118
from sage .rings .qqbar import AA , QQbar
118
119
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
120
121
from sage .schemes .elliptic_curves .constructor import EllipticCurve
121
122
from sage .structure .richcmp import richcmp_method , richcmp , richcmp_not_equal
122
123
@@ -231,14 +232,14 @@ def __init__(self, E, embedding=None):
231
232
# the given embedding:
232
233
233
234
K = E .base_field ()
234
- self .is_approximate = isinstance ( K , ( RealField_class , ComplexField_class ) )
235
+ self ._is_exact = K . is_exact ( )
235
236
if embedding is None :
236
237
if K in (AA , QQbar ):
237
238
embedding = K .hom (QQbar )
238
239
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 ) )
242
243
else :
243
244
embs = K .embeddings (AA )
244
245
real = len (embs ) > 0
@@ -271,24 +272,24 @@ def __init__(self, E, embedding=None):
271
272
# The ei are used both for period computation and elliptic
272
273
# logarithms.
273
274
274
- if self .is_approximate :
275
- self .f2 = self .E .two_division_polynomial ()
276
- else :
275
+ if self ._is_exact :
277
276
self .Ebar = self .E .change_ring (self .embedding )
278
277
self .f2 = self .Ebar .two_division_polynomial ()
278
+ else :
279
+ self .f2 = self .E .two_division_polynomial ()
279
280
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 )
281
282
self ._ei .sort () # e1 < e2 < e3
282
283
e1 , e2 , e3 = self ._ei
283
284
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 )
285
286
self ._ei = sorted (self ._ei , key = lambda z : z .imag ())
286
287
e1 , e3 , e2 = self ._ei # so e3 is real
287
- if not self .is_approximate :
288
+ if self ._is_exact :
288
289
e3 = AA (e3 )
289
290
self ._ei = [e1 , e2 , e3 ]
290
291
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 )
292
293
e1 , e2 , e3 = self ._ei
293
294
294
295
# The quantities sqrt(e_i-e_j) are cached (as elements of
@@ -350,7 +351,7 @@ def __repr__(self):
350
351
Defn: a |--> 1.259921049894873?
351
352
"""
352
353
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 ):
354
355
return "Period lattice associated to %s" % (self .E )
355
356
return "Period lattice associated to %s with respect to the embedding %s" % (self .E , self .embedding )
356
357
@@ -656,7 +657,7 @@ def _compute_default_prec(self):
656
657
r"""
657
658
Internal function to compute the default precision to be used if nothing is passed in.
658
659
"""
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 ()
660
661
661
662
@cached_method
662
663
def _compute_periods_real (self , prec = None , algorithm = 'sage' ):
@@ -704,7 +705,7 @@ def _compute_periods_real(self, prec=None, algorithm='sage'):
704
705
705
706
if algorithm == 'pari' :
706
707
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 :
708
709
ainvs = [C (self .embedding (ai )).real () for ai in ainvs ]
709
710
710
711
# The precision for omega() is determined by ellinit()
@@ -716,7 +717,7 @@ def _compute_periods_real(self, prec=None, algorithm='sage'):
716
717
raise ValueError ("invalid value of 'algorithm' parameter" )
717
718
718
719
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 ),
720
721
# but now we must go transcendental. Only now is the desired precision used!
721
722
if self .real_flag == 1 : # positive discriminant
722
723
a , b , c = (R (x ) for x in self ._abc )
@@ -788,7 +789,7 @@ def _compute_periods_complex(self, prec=None, normalise=True):
788
789
prec = self ._compute_default_prec ()
789
790
C = ComplexField (prec )
790
791
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 ),
792
793
# but now we must go transcendental. Only now is the desired precision used!
793
794
pi = C .pi ()
794
795
a , b , c = (C (x ) for x in self ._abc )
@@ -1166,6 +1167,38 @@ def curve(self):
1166
1167
"""
1167
1168
return self .E
1168
1169
1170
+ @property
1171
+ def is_approximate (self ):
1172
+ """
1173
+ ``self.is_approximate`` is deprecated, use ``not self.curve().is_exact()`` instead.
1174
+
1175
+ TESTS::
1176
+
1177
+ sage: E = EllipticCurve(ComplexField(100), [I, 3*I+4])
1178
+ sage: L = E.period_lattice()
1179
+ sage: L.is_approximate
1180
+ doctest:...: DeprecationWarning: The attribute is_approximate for period lattice is deprecated,
1181
+ use self.curve().is_exact() instead.
1182
+ See https://github.com/sagemath/sage/issues/39212 for details.
1183
+ True
1184
+ sage: L.curve() is E
1185
+ True
1186
+ sage: E.is_exact()
1187
+ False
1188
+ sage: E = EllipticCurve(QQ, [0, 2])
1189
+ sage: L = E.period_lattice()
1190
+ sage: L.is_approximate
1191
+ False
1192
+ sage: L.curve() is E
1193
+ True
1194
+ sage: E.is_exact()
1195
+ True
1196
+ """
1197
+ from sage .misc .superseded import deprecation
1198
+ deprecation (39212 , "The attribute is_approximate for period lattice is "
1199
+ "deprecated, use self.curve().is_exact() instead." )
1200
+ return not self ._is_exact
1201
+
1169
1202
def ei (self ):
1170
1203
r"""
1171
1204
Return the x-coordinates of the 2-division points of the elliptic curve associated
@@ -1757,10 +1790,19 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
1757
1790
sage: L.real_flag
1758
1791
-1
1759
1792
sage: P = E(3, 6)
1760
- sage: L.elliptic_logarithm(P)
1793
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1761
1794
2.4593388737550379526023682666
1762
- sage: L.elliptic_exponential(_)
1795
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1763
1796
(3.0000000000000000000000000000 : 5.9999999999999999999999999999 : 1.0000000000000000000000000000)
1797
+ sage: E = EllipticCurve(RDF, [1, 6])
1798
+ sage: L = E.period_lattice()
1799
+ sage: L.real_flag
1800
+ -1
1801
+ sage: P = E(3, 6)
1802
+ sage: L.elliptic_logarithm(P) # abs tol 1e-13
1803
+ 2.45933887375504
1804
+ sage: L.elliptic_exponential(_) # abs tol 1e-13
1805
+ (3.00000000000000 : 6.00000000000001 : 1.00000000000000)
1764
1806
1765
1807
Real approximate field, positive discriminant::
1766
1808
@@ -1769,9 +1811,9 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
1769
1811
sage: L.real_flag
1770
1812
1
1771
1813
sage: P = E.lift_x(4)
1772
- sage: L.elliptic_logarithm(P)
1814
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1773
1815
0.51188849089267627141925354967
1774
- sage: L.elliptic_exponential(_)
1816
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1775
1817
(4.0000000000000000000000000000 : -7.1414284285428499979993998114 : 1.0000000000000000000000000000)
1776
1818
1777
1819
Complex approximate field::
@@ -1781,10 +1823,19 @@ def elliptic_logarithm(self, P, prec=None, reduce=True):
1781
1823
sage: L.real_flag
1782
1824
0
1783
1825
sage: P = E.lift_x(4)
1784
- sage: L.elliptic_logarithm(P)
1826
+ sage: L.elliptic_logarithm(P) # abs tol 1e-26
1785
1827
-1.1447032790074574712147458157 - 0.72429843602171875396186134806*I
1786
- sage: L.elliptic_exponential(_)
1828
+ sage: L.elliptic_exponential(_) # abs tol 1e-26
1787
1829
(4.0000000000000000000000000000 + 1.2025589033682610849950210280e-30*I : -8.2570982991257407680322611854 - 0.42387771989714340809597881586*I : 1.0000000000000000000000000000)
1830
+ sage: E = EllipticCurve(CDF, [I, 3*I+4])
1831
+ sage: L = E.period_lattice()
1832
+ sage: L.real_flag
1833
+ 0
1834
+ sage: P = E.lift_x(4)
1835
+ sage: L.elliptic_logarithm(P) # abs tol 1e-13
1836
+ -1.14470327900746 - 0.724298436021719*I
1837
+ sage: L.elliptic_exponential(_) # abs tol 1e-13
1838
+ (4.00000000000000 - 0*I : -8.25709829912574 - 0.423877719897148*I : 1.00000000000000)
1788
1839
"""
1789
1840
if P .curve () is not self .E :
1790
1841
raise ValueError ("Point is on the wrong curve" )
@@ -2002,10 +2053,10 @@ def elliptic_exponential(self, z, to_curve=True):
2002
2053
2003
2054
if to_curve :
2004
2055
K = x .parent ()
2005
- if self .is_approximate :
2006
- v = self .embedding
2007
- else :
2056
+ if self ._is_exact :
2008
2057
v = refine_embedding (self .embedding , Infinity )
2058
+ else :
2059
+ v = self .embedding
2009
2060
a1 , a2 , a3 , a4 , a6 = (K (v (a )) for a in self .E .ainvs ())
2010
2061
b2 = K (v (self .E .b2 ()))
2011
2062
x = x - b2 / 12
0 commit comments