Modular symbols using eclib newforms¶
- class sage.libs.eclib.newforms.ECModularSymbol[source]¶
Bases:
object
Modular symbol associated with an elliptic curve, using John Cremona’s newforms class.
EXAMPLES:
sage: from sage.libs.eclib.newforms import ECModularSymbol sage: E = EllipticCurve('11a') sage: M = ECModularSymbol(E,1); M Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
>>> from sage.all import * >>> from sage.libs.eclib.newforms import ECModularSymbol >>> E = EllipticCurve('11a') >>> M = ECModularSymbol(E,Integer(1)); M Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field
By default, symbols are based at the cusp \(\infty\), i.e. we evaluate \(\{\infty,r\}\):
sage: [M(1/i) for i in range(1,11)] [2/5, -8/5, -3/5, 7/5, 12/5, 12/5, 7/5, -3/5, -8/5, 2/5]
>>> from sage.all import * >>> [M(Integer(1)/i) for i in range(Integer(1),Integer(11))] [2/5, -8/5, -3/5, 7/5, 12/5, 12/5, 7/5, -3/5, -8/5, 2/5]
We can also switch the base point to the cusp \(0\):
sage: [M(1/i, base_at_infinity=False) for i in range(1,11)] [0, -2, -1, 1, 2, 2, 1, -1, -2, 0]
>>> from sage.all import * >>> [M(Integer(1)/i, base_at_infinity=False) for i in range(Integer(1),Integer(11))] [0, -2, -1, 1, 2, 2, 1, -1, -2, 0]
For the minus symbols this makes no difference since \(\{0,\infty\}\) is in the plus space. Note that to evaluate minus symbols the space must be defined with sign 0, which makes both signs available:
sage: M = ECModularSymbol(E,0); M Modular symbol with sign 0 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [M(1/i, -1) for i in range(1,11)] [0, 0, 1, 1, 0, 0, -1, -1, 0, 0] sage: [M(1/i, -1, base_at_infinity=False) for i in range(1,11)] [0, 0, 1, 1, 0, 0, -1, -1, 0, 0]
>>> from sage.all import * >>> M = ECModularSymbol(E,Integer(0)); M Modular symbol with sign 0 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field >>> [M(Integer(1)/i, -Integer(1)) for i in range(Integer(1),Integer(11))] [0, 0, 1, 1, 0, 0, -1, -1, 0, 0] >>> [M(Integer(1)/i, -Integer(1), base_at_infinity=False) for i in range(Integer(1),Integer(11))] [0, 0, 1, 1, 0, 0, -1, -1, 0, 0]
If the ECModularSymbol is created with sign 0 then as well as asking for both + and - symbols, we can also obtain both (as a tuple). However it is more work to create the full modular symbol space:
sage: E = EllipticCurve('11a1') sage: M = ECModularSymbol(E,0); M Modular symbol with sign 0 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: [M(1/i) for i in range(2,11)] [[-8/5, 0], [-3/5, 1], [7/5, 1], [12/5, 0], [12/5, 0], [7/5, -1], [-3/5, -1], [-8/5, 0], [2/5, 0]]
>>> from sage.all import * >>> E = EllipticCurve('11a1') >>> M = ECModularSymbol(E,Integer(0)); M Modular symbol with sign 0 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field >>> [M(Integer(1)/i) for i in range(Integer(2),Integer(11))] [[-8/5, 0], [-3/5, 1], [7/5, 1], [12/5, 0], [12/5, 0], [7/5, -1], [-3/5, -1], [-8/5, 0], [2/5, 0]]
The curve is automatically converted to its minimal model:
sage: E = EllipticCurve([0,0,0,0,1/4]) sage: ECModularSymbol(E) Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 over Rational Field
>>> from sage.all import * >>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),Integer(0),Integer(1)/Integer(4)]) >>> ECModularSymbol(E) Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 over Rational Field
Non-optimal curves are handled correctly in eclib, by comparing the ratios of real and/or imaginary periods:
sage: from sage.libs.eclib.newforms import ECModularSymbol sage: E1 = EllipticCurve('11a1') # optimal sage: E1.period_lattice().basis() (1.26920930427955, 0.634604652139777 + 1.45881661693850*I) sage: M1 = ECModularSymbol(E1,0) sage: M1(0) [2/5, 0] sage: M1(1/3) [-3/5, 1]
>>> from sage.all import * >>> from sage.libs.eclib.newforms import ECModularSymbol >>> E1 = EllipticCurve('11a1') # optimal >>> E1.period_lattice().basis() (1.26920930427955, 0.634604652139777 + 1.45881661693850*I) >>> M1 = ECModularSymbol(E1,Integer(0)) >>> M1(Integer(0)) [2/5, 0] >>> M1(Integer(1)/Integer(3)) [-3/5, 1]
One non-optimal curve has real period 1/5 that of the optimal one, so plus symbols scale up by a factor of 5 while minus symbols are unchanged:
sage: E2 = EllipticCurve('11a2') # not optimal sage: E2.period_lattice().basis() (0.253841860855911, 0.126920930427955 + 1.45881661693850*I) sage: M2 = ECModularSymbol(E2,0) sage: M2(0) [2, 0] sage: M2(1/3) [-3, 1] sage: all((M2(r,1)==5*M1(r,1)) for r in QQ.range_by_height(10)) True sage: all((M2(r,-1)==M1(r,-1)) for r in QQ.range_by_height(10)) True
>>> from sage.all import * >>> E2 = EllipticCurve('11a2') # not optimal >>> E2.period_lattice().basis() (0.253841860855911, 0.126920930427955 + 1.45881661693850*I) >>> M2 = ECModularSymbol(E2,Integer(0)) >>> M2(Integer(0)) [2, 0] >>> M2(Integer(1)/Integer(3)) [-3, 1] >>> all((M2(r,Integer(1))==Integer(5)*M1(r,Integer(1))) for r in QQ.range_by_height(Integer(10))) True >>> all((M2(r,-Integer(1))==M1(r,-Integer(1))) for r in QQ.range_by_height(Integer(10))) True
The other non-optimal curve has real period 5 times that of the optimal one, so plus symbols scale down by a factor of 5; again, minus symbols are unchanged:
sage: E3 = EllipticCurve('11a3') # not optimal sage: E3.period_lattice().basis() (6.34604652139777, 3.17302326069888 + 1.45881661693850*I) sage: M3 = ECModularSymbol(E3,0) sage: M3(0) [2/25, 0] sage: M3(1/3) [-3/25, 1] sage: all((5*M3(r,1)==M1(r,1)) for r in QQ.range_by_height(10)) True sage: all((M3(r,-1)==M1(r,-1)) for r in QQ.range_by_height(10)) True
>>> from sage.all import * >>> E3 = EllipticCurve('11a3') # not optimal >>> E3.period_lattice().basis() (6.34604652139777, 3.17302326069888 + 1.45881661693850*I) >>> M3 = ECModularSymbol(E3,Integer(0)) >>> M3(Integer(0)) [2/25, 0] >>> M3(Integer(1)/Integer(3)) [-3/25, 1] >>> all((Integer(5)*M3(r,Integer(1))==M1(r,Integer(1))) for r in QQ.range_by_height(Integer(10))) True >>> all((M3(r,-Integer(1))==M1(r,-Integer(1))) for r in QQ.range_by_height(Integer(10))) True