Isomorphisms between Weierstrass models of elliptic curves#

AUTHORS:

  • Robert Bradshaw (2007): initial version

  • John Cremona (Jan 2008): isomorphisms, automorphisms and twists in all characteristics

  • Lorenz Panny (2021): EllipticCurveHom interface

class sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism(E=None, urst=None, F=None)#

Bases: EllipticCurveHom, baseWI

Class representing a Weierstrass isomorphism between two elliptic curves.

INPUT:

  • E – an EllipticCurve, or None (see below).

  • urst – a 4-tuple (u,r,s,t), a baseWI object, or None (see below).

  • F – an EllipticCurve, or None (see below).

Given two Elliptic Curves E and F (represented by Weierstrass models as usual), and a transformation urst from E to F, construct an isomorphism from E to F. An exception is raised if urst(E) != F. At most one of E, F, urst can be None. In this case, the missing input is constructed from the others in such a way that urst(E) == F holds, and an exception is raised if this is impossible (typically because E and F are not isomorphic).

Users will not usually need to use this class directly, but instead use methods such as isomorphism_to() or isomorphisms().

Explicitly, the isomorphism defined by (u,r,s,t) maps a point (x,y) to the point

((xr)/u2,(ys(xr)t)/u3).

If the domain E has Weierstrass coefficients [a1,a2,a3,a4,a6], the codomain F is given by

a1=(a1+2s)/ua2=(a2a1s+3rs2)/u2a3=(a3+a1r+2t)/u3a4=(a4+2a2ra1(rs+t)a3s+3r22st)/u4a6=(a6a1rt+a2r2a3t+a4r+r3t2)/u6.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import *
sage: WeierstrassIsomorphism(EllipticCurve([0,1,2,3,4]), (-1,2,3,4))
Elliptic-curve morphism:
  From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field
  To:   Elliptic Curve defined by y^2 - 6*x*y - 10*y = x^3 - 2*x^2 - 11*x - 2 over Rational Field
  Via:  (u,r,s,t) = (-1, 2, 3, 4)
sage: E = EllipticCurve([0,1,2,3,4])
sage: F = EllipticCurve(E.cremona_label())
sage: WeierstrassIsomorphism(E, None, F)
Elliptic-curve morphism:
  From: Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field
  To:   Elliptic Curve defined by y^2  = x^3 + x^2 + 3*x + 5 over Rational Field
  Via:  (u,r,s,t) = (1, 0, 0, -1)
sage: w = WeierstrassIsomorphism(None, (1,0,0,-1), F)
sage: w._domain == E
True
dual()#

Return the dual isogeny of this isomorphism.

For isomorphisms, the dual is just the inverse.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism
sage: E = EllipticCurve(QuadraticField(-3), [0,1])                          # optional - sage.rings.number_field
sage: w = WeierstrassIsomorphism(E, (CyclotomicField(3).gen(),0,0,0))       # optional - sage.rings.number_field
sage: (w.dual() * w).rational_maps()                                        # optional - sage.rings.number_field
(x, y)
sage: E1 = EllipticCurve([11,22,33,44,55])
sage: E2 = E1.short_weierstrass_model()
sage: iso = E1.isomorphism_to(E2)
sage: iso.dual() == ~iso
True
is_separable()#

Determine whether or not this isogeny is separable.

Since WeierstrassIsomorphism only implements isomorphisms, this method always returns True.

EXAMPLES:

sage: E = EllipticCurve(GF(31337), [0,1])                                   # optional - sage.rings.finite_rings
sage: {f.is_separable() for f in E.automorphisms()}                         # optional - sage.rings.finite_rings
{True}
kernel_polynomial()#

Return the kernel polynomial of this isomorphism.

Isomorphisms have trivial kernel by definition, hence this method always returns 1.

EXAMPLES:

sage: E1 = EllipticCurve([11,22,33,44,55])
sage: E2 = EllipticCurve_from_j(E1.j_invariant())
sage: iso = E1.isomorphism_to(E2)
sage: iso.kernel_polynomial()
1
sage: psi = E1.isogeny(iso.kernel_polynomial(), codomain=E2); psi
Isogeny of degree 1
 from Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55
      over Rational Field
   to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681
      over Rational Field
sage: psi in {iso, -iso}
True
rational_maps()#

Return the pair of rational maps defining this isomorphism.

EXAMPLES:

sage: E1 = EllipticCurve([11,22,33,44,55])
sage: E2 = EllipticCurve_from_j(E1.j_invariant())
sage: iso = E1.isomorphism_to(E2); iso
Elliptic-curve morphism:
  From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55
        over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681
        over Rational Field
  Via:  (u,r,s,t) = (1, -17, -5, 77)
sage: iso.rational_maps()
(x + 17, 5*x + y + 8)
sage: f = E2.defining_polynomial()(*iso.rational_maps(), 1)
sage: I = E1.defining_ideal()
sage: x,y,z = I.ring().gens()
sage: f in I + Ideal(z-1)
True
sage: E = EllipticCurve(GF(65537), [1,1,1,1,1])                             # optional - sage.rings.finite_rings
sage: w = E.isomorphism_to(E.short_weierstrass_model())                     # optional - sage.rings.finite_rings
sage: f,g = w.rational_maps()                                               # optional - sage.rings.finite_rings
sage: P = E.random_point()                                                  # optional - sage.rings.finite_rings
sage: w(P).xy() == (f(P.xy()), g(P.xy()))                                   # optional - sage.rings.finite_rings
True
scaling_factor()#

Return the Weierstrass scaling factor associated to this Weierstrass isomorphism.

The scaling factor is the constant u (in the base field) such that φω2=uω1, where φ:E1E2 is this isomorphism and ωi are the standard Weierstrass differentials on Ei defined by dx/(2y+a1x+a3).

EXAMPLES:

sage: E = EllipticCurve(QQbar, [0,1])                                       # optional - sage.rings.number_field
sage: all(f.scaling_factor() == f.formal()[1] for f in E.automorphisms())   # optional - sage.rings.number_field
True

ALGORITHM: The scaling factor equals the u component of the tuple (u,r,s,t) defining the isomorphism.

x_rational_map()#

Return the x-coordinate rational map of this isomorphism.

EXAMPLES:

sage: E1 = EllipticCurve([11,22,33,44,55])
sage: E2 = EllipticCurve_from_j(E1.j_invariant())
sage: iso = E1.isomorphism_to(E2); iso
Elliptic-curve morphism:
  From: Elliptic Curve defined by y^2 + 11*x*y + 33*y = x^3 + 22*x^2 + 44*x + 55
        over Rational Field
  To:   Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 684*x + 6681
        over Rational Field
  Via:  (u,r,s,t) = (1, -17, -5, 77)
sage: iso.x_rational_map()
x + 17
sage: iso.x_rational_map() == iso.rational_maps()[0]
True
class sage.schemes.elliptic_curves.weierstrass_morphism.baseWI(u=1, r=0, s=0, t=0)#

Bases: object

This class implements the basic arithmetic of isomorphisms between Weierstrass models of elliptic curves.

These are specified by lists of the form [u,r,s,t] (with u0) which specifies a transformation (x,y)(x,y) where

(x,y)=(u2x+r,u3y+su2x+t).

INPUT:

  • u,r,s,t (default (1,0,0,0)) – standard parameters of an isomorphism between Weierstrass models.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import *
sage: baseWI()
(1, 0, 0, 0)
sage: baseWI(2,3,4,5)
(2, 3, 4, 5)
sage: R.<u,r,s,t> = QQ[]
sage: baseWI(u,r,s,t)
(u, r, s, t)
is_identity()#

Return True if this is the identity isomorphism.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import *
sage: w = baseWI(); w.is_identity()
True
sage: w = baseWI(2,3,4,5); w.is_identity()
False
tuple()#

Return the parameters u,r,s,t as a tuple.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import *
sage: w = baseWI(2,3,4,5)
sage: w.tuple()
(2, 3, 4, 5)
sage.schemes.elliptic_curves.weierstrass_morphism.identity_morphism(E)#

Given an elliptic curve E, return the identity morphism on E as a WeierstrassIsomorphism.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism
sage: E = EllipticCurve([5,6,7,8,9])
sage: id_ = identity_morphism(E)
sage: id_.rational_maps()
(x, y)
sage.schemes.elliptic_curves.weierstrass_morphism.negation_morphism(E)#

Given an elliptic curve E, return the negation endomorphism [1] of E as a WeierstrassIsomorphism.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.weierstrass_morphism import negation_morphism
sage: E = EllipticCurve([5,6,7,8,9])
sage: neg = negation_morphism(E)
sage: neg.rational_maps()
(x, -5*x - y - 7)