Modular parametrization of elliptic curves over Q

By the work of Taylor–Wiles et al. it is known that there is a surjective morphism

ϕE:X0(N)E.

from the modular curve X0(N), where N is the conductor of E. The map sends the cusp to the origin of E.

EXAMPLES:

sage: phi = EllipticCurve('11a1').modular_parametrization()
sage: phi
Modular parameterization
 from the upper half plane
   to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
sage: phi(0.5+CDF(I))
(285684.320516... + 7.0...e-11*I : 1.526964169...e8 + 5.6...e-8*I : 1.00000000000000)
sage: phi.power_series(prec = 7)
(q^-2 + 2*q^-1 + 4 + 5*q + 8*q^2 + q^3 + 7*q^4 + O(q^5),
 -q^-3 - 3*q^-2 - 7*q^-1 - 13 - 17*q - 26*q^2 - 19*q^3 + O(q^4))
>>> from sage.all import *
>>> phi = EllipticCurve('11a1').modular_parametrization()
>>> phi
Modular parameterization
 from the upper half plane
   to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
>>> phi(RealNumber('0.5')+CDF(I))
(285684.320516... + 7.0...e-11*I : 1.526964169...e8 + 5.6...e-8*I : 1.00000000000000)
>>> phi.power_series(prec = Integer(7))
(q^-2 + 2*q^-1 + 4 + 5*q + 8*q^2 + q^3 + 7*q^4 + O(q^5),
 -q^-3 - 3*q^-2 - 7*q^-1 - 13 - 17*q - 26*q^2 - 19*q^3 + O(q^4))
phi = EllipticCurve('11a1').modular_parametrization()
phi
phi(0.5+CDF(I))
phi.power_series(prec = 7)

AUTHORS:

  • Chris Wuthrich (02/10): moved from ell_rational_field.py.

class sage.schemes.elliptic_curves.modular_parametrization.ModularParameterization(E)[source]

Bases: object

This class represents the modular parametrization of an elliptic curve

ϕE:X0(N)E.

Evaluation is done by passing through the lattice representation of E.

EXAMPLES:

sage: phi = EllipticCurve('11a1').modular_parametrization()
sage: phi
Modular parameterization
 from the upper half plane
   to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20
      over Rational Field
>>> from sage.all import *
>>> phi = EllipticCurve('11a1').modular_parametrization()
>>> phi
Modular parameterization
 from the upper half plane
   to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20
      over Rational Field
phi = EllipticCurve('11a1').modular_parametrization()
phi
curve()[source]

Return the curve associated to this modular parametrization.

EXAMPLES:

sage: E = EllipticCurve('15a')
sage: phi = E.modular_parametrization()
sage: phi.curve() is E
True
>>> from sage.all import *
>>> E = EllipticCurve('15a')
>>> phi = E.modular_parametrization()
>>> phi.curve() is E
True
E = EllipticCurve('15a')
phi = E.modular_parametrization()
phi.curve() is E
map_to_complex_numbers(z, prec=None)[source]

Evaluate self at a point zX0(N) where z is given by a representative in the upper half plane, returning a point in the complex numbers.

All computations are done with prec bits of precision. If prec is not given, use the precision of z. Use self(z) to compute the image of z on the Weierstrass equation of the curve.

EXAMPLES:

sage: # needs sage.symbolic
sage: E = EllipticCurve('37a'); phi = E.modular_parametrization()
sage: x = polygen(ZZ, 'x')
sage: tau = (sqrt(7)*I - 17)/74
sage: z = phi.map_to_complex_numbers(tau); z
0.929592715285395 - 1.22569469099340*I
sage: E.elliptic_exponential(z)
(...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
sage: phi(tau)
(...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
>>> from sage.all import *
>>> # needs sage.symbolic
>>> E = EllipticCurve('37a'); phi = E.modular_parametrization()
>>> x = polygen(ZZ, 'x')
>>> tau = (sqrt(Integer(7))*I - Integer(17))/Integer(74)
>>> z = phi.map_to_complex_numbers(tau); z
0.929592715285395 - 1.22569469099340*I
>>> E.elliptic_exponential(z)
(...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
>>> phi(tau)
(...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
# needs sage.symbolic
E = EllipticCurve('37a'); phi = E.modular_parametrization()
x = polygen(ZZ, 'x')
tau = (sqrt(7)*I - 17)/74
z = phi.map_to_complex_numbers(tau); z
E.elliptic_exponential(z)
phi(tau)
power_series(prec=20)[source]

Return the power series of this modular parametrization.

The curve must be a minimal model. The prec parameter determines the number of significant terms. This means that X will be given up to O(q^(prec-2)) and Y will be given up to O(q^(prec-3)).

OUTPUT:

A list of two Laurent series [X(x),`Y(x)`] of degrees 2, 3, respectively, which satisfy the equation of the elliptic curve. There are modular functions on Γ0(N) where N is the conductor.

The series should satisfy the differential equation

dX2Y+a1X+a3=f(q)dqq

where f is self.curve().q_expansion().

EXAMPLES:

sage: E = EllipticCurve('389a1')
sage: phi = E.modular_parametrization()
sage: X, Y = phi.power_series(prec=10)
sage: X
q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + O(q^8)
sage: Y
-q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 + O(q^7)
sage: X,Y = phi.power_series()
sage: X
q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18)
sage: Y
-q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 - 861*q^7 - 1383*q^8 - 2218*q^9 - 3472*q^10 - 5451*q^11 - 8447*q^12 - 13020*q^13 - 19923*q^14 - 30403*q^15 - 46003*q^16 + O(q^17)
>>> from sage.all import *
>>> E = EllipticCurve('389a1')
>>> phi = E.modular_parametrization()
>>> X, Y = phi.power_series(prec=Integer(10))
>>> X
q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + O(q^8)
>>> Y
-q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 + O(q^7)
>>> X,Y = phi.power_series()
>>> X
q^-2 + 2*q^-1 + 4 + 7*q + 13*q^2 + 18*q^3 + 31*q^4 + 49*q^5 + 74*q^6 + 111*q^7 + 173*q^8 + 251*q^9 + 379*q^10 + 560*q^11 + 824*q^12 + 1199*q^13 + 1773*q^14 + 2548*q^15 + 3722*q^16 + 5374*q^17 + O(q^18)
>>> Y
-q^-3 - 3*q^-2 - 8*q^-1 - 17 - 33*q - 61*q^2 - 110*q^3 - 186*q^4 - 320*q^5 - 528*q^6 - 861*q^7 - 1383*q^8 - 2218*q^9 - 3472*q^10 - 5451*q^11 - 8447*q^12 - 13020*q^13 - 19923*q^14 - 30403*q^15 - 46003*q^16 + O(q^17)
E = EllipticCurve('389a1')
phi = E.modular_parametrization()
X, Y = phi.power_series(prec=10)
X
Y
X,Y = phi.power_series()
X
Y

The following should give 0, but only approximately:

sage: q = X.parent().gen()
sage: E.defining_polynomial()(X,Y,1) + O(q^11) == 0
True
>>> from sage.all import *
>>> q = X.parent().gen()
>>> E.defining_polynomial()(X,Y,Integer(1)) + O(q**Integer(11)) == Integer(0)
True
q = X.parent().gen()
E.defining_polynomial()(X,Y,1) + O(q^11) == 0

Note that below we have to change variable from x to q:

sage: a1,_,a3,_,_ = E.a_invariants()
sage: f = E.q_expansion(17)
sage: q = f.parent().gen()
sage: f/q == (X.derivative()/(2*Y+a1*X+a3))
True
>>> from sage.all import *
>>> a1,_,a3,_,_ = E.a_invariants()
>>> f = E.q_expansion(Integer(17))
>>> q = f.parent().gen()
>>> f/q == (X.derivative()/(Integer(2)*Y+a1*X+a3))
True
a1,_,a3,_,_ = E.a_invariants()
f = E.q_expansion(17)
q = f.parent().gen()
f/q == (X.derivative()/(2*Y+a1*X+a3))