Modular parametrization of elliptic curves over \(\QQ\)

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

\[\phi_E: X_0(N) \rightarrow E.\]

from the modular curve \(X_0(N)\), where \(N\) is the conductor of \(E\). The map sends the cusp \(\infty\) 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

\[\phi_E: X_0(N) \rightarrow 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 \(z \in X_0(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 \(\Gamma_0(N)\) where \(N\) is the conductor.

The series should satisfy the differential equation

\[\frac{\mathrm{d}X}{2Y + a_1 X + a_3} = \frac{f(q)\, \mathrm{d}q}{q}\]

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))