108108
109109import sage .rings .abc
110110
111+ from sage .categories .morphism import IdentityMorphism
111112from sage .misc .cachefunc import cached_method
112113from sage .misc .lazy_import import lazy_import
113114from sage .modules .free_module import FreeModule_generic_pid
116117from sage .rings .integer_ring import ZZ
117118from sage .rings .qqbar import AA , QQbar
118119from 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
120121from sage .schemes .elliptic_curves .constructor import EllipticCurve
121122from 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