def point(self, v, check=True): """ Create a point. INPUT: - ``v`` -- anything that defines a point. - ``check`` -- boolean (optional, default=``True``). Whether to check the defining data for consistency. OUTPUT: A point of the scheme. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.point([4,5]) (4, 5) sage: R.<t> = PolynomialRing(QQ) sage: E = EllipticCurve([t + 1, t, t, 0, 0]) sage: E.point([0, 0]) (0 : 0 : 1) """ # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): try: return self._point(self.point_homset(), v, check=check) except AttributeError: # legacy code without point_homset return self._point(self, v, check=check) return self.point_homset() (v, check=check)
def point(self, v, check=True): """ Create a point. INPUT: - ``v`` -- anything that defines a point. - ``check`` -- boolean (optional, default=``True``). Whether to check the defining data for consistency. OUTPUT: A point of the scheme. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.point([4,5]) (4, 5) """ # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): return self._point(self, v, check=check) return self.point_homset() (v, check=check)
def point(self, v, check=True): """ Create a point. INPUT: - ``v`` -- anything that defines a point - ``check`` -- boolean (optional, default: ``True``); whether to check the defining data for consistency OUTPUT: A point of the scheme. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.point([4,5]) (4, 5) sage: R.<t> = PolynomialRing(QQ) sage: E = EllipticCurve([t + 1, t, t, 0, 0]) sage: E.point([0, 0]) (0 : 0 : 1) """ # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): try: return self._point(self.point_homset(), v, check=check) except AttributeError: # legacy code without point_homset return self._point(self, v, check=check) return self.point_homset()(v, check=check)
def point(self, v, check=True): """ Create a point. INPUT: - ``v`` -- anything that defines a point. - ``check`` -- boolean (optional, default=``True``). Whether to check the defining data for consistency. OUTPUT: A point of the scheme. EXAMPLES:: sage: A2 = AffineSpace(QQ,2) sage: A2.point([4,5]) (4, 5) """ # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): return self._point(self, v, check=check) return self.point_homset()(v, check=check)
def point(self, v, check=True): """ Create a point on this projective subscheme. INPUT: - ``v`` -- anything that defines a point - ``check`` -- boolean (optional, default: ``True``); whether to check the defining data for consistency OUTPUT: A point of the subscheme. EXAMPLES:: sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme([x-y,y-z]) sage: X.point([1,1,1]) (1 : 1 : 1) :: sage: P2.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([y]) sage: X.point(infinity) (1 : 0) :: sage: P.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P.subscheme(x^2+2*y^2) sage: X.point(infinity) Traceback (most recent call last): ... TypeError: Coordinates [1, 0] do not define a point on Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: x^2 + 2*y^2 """ from sage.rings.infinity import infinity if v is infinity or\ (isinstance(v, (list,tuple)) and len(v) == 1 and v[0] is infinity): if self.ambient_space().dimension_relative() > 1: raise ValueError("%s not well defined in dimension > 1" % v) v = [1, 0] # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): try: return self._point(self.point_homset(), v, check=check) except AttributeError: # legacy code without point_homset return self._point(self, v, check=check) return self.point_homset()(v, check=check)
def is_isogenous(self, other, field=None): """ Returns whether or not self is isogenous to other. INPUT: - ``other`` -- another elliptic curve. - ``field`` (default None) -- Currently not implemented. A field containing the base fields of the two elliptic curves onto which the two curves may be extended to test if they are isogenous over this field. By default is_isogenous will not try to find this field unless one of the curves can be be extended into the base field of the other, in which case it will test over the larger base field. OUTPUT: (bool) True if there is an isogeny from curve ``self`` to curve ``other`` defined over ``field``. METHOD: Over general fields this is only implemented in trivial cases. EXAMPLES:: sage: E1 = EllipticCurve(CC, [1,18]); E1 Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision sage: E2 = EllipticCurve(CC, [2,7]); E2 Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... NotImplementedError: Only implemented for isomorphic curves over general fields. sage: E1 = EllipticCurve(Frac(PolynomialRing(ZZ,'t')), [2,19]); E1 Elliptic Curve defined by y^2 = x^3 + 2*x + 19 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring sage: E2 = EllipticCurve(CC, [23,4]); E2 Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... NotImplementedError: Only implemented for isomorphic curves over general fields. """ from ell_generic import is_EllipticCurve if not is_EllipticCurve(other): raise ValueError("Second argument is not an Elliptic Curve.") if self.is_isomorphic(other): return True else: raise NotImplementedError( "Only implemented for isomorphic curves over general fields.")
def point(self, v, check=True): """ Create a point on this projective subscheme. INPUT: - ``v`` -- anything that defines a point - ``check`` -- boolean (optional, default: ``True``); whether to check the defining data for consistency OUTPUT: A point of the subscheme. EXAMPLES:: sage: P2.<x,y,z> = ProjectiveSpace(QQ, 2) sage: X = P2.subscheme([x-y,y-z]) sage: X.point([1,1,1]) (1 : 1 : 1) :: sage: P2.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P2.subscheme([y]) sage: X.point(infinity) (1 : 0) :: sage: P.<x,y> = ProjectiveSpace(QQ, 1) sage: X = P.subscheme(x^2+2*y^2) sage: X.point(infinity) Traceback (most recent call last): ... TypeError: Coordinates [1, 0] do not define a point on Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: x^2 + 2*y^2 """ from sage.rings.infinity import infinity if v is infinity or\ (isinstance(v, (list,tuple)) and len(v) == 1 and v[0] is infinity): if self.ambient_space().dimension_relative() > 1: raise ValueError("%s not well defined in dimension > 1"%v) v = [1, 0] # todo: update elliptic curve stuff to take point_homset as argument from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve if is_EllipticCurve(self): try: return self._point(self.point_homset(), v, check=check) except AttributeError: # legacy code without point_homset return self._point(self, v, check=check) return self.point_homset()(v, check=check)
def is_isogenous(self, other, field=None): """ Returns whether or not self is isogenous to other. INPUT: - ``other`` -- another elliptic curve. - ``field`` (default None) -- Currently not implemented. A field containing the base fields of the two elliptic curves onto which the two curves may be extended to test if they are isogenous over this field. By default is_isogenous will not try to find this field unless one of the curves can be be extended into the base field of the other, in which case it will test over the larger base field. OUTPUT: (bool) True if there is an isogeny from curve ``self`` to curve ``other`` defined over ``field``. METHOD: Over general fields this is only implemented in trivial cases. EXAMPLES:: sage: E1 = EllipticCurve(CC, [1,18]); E1 Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision sage: E2 = EllipticCurve(CC, [2,7]); E2 Elliptic Curve defined by y^2 = x^3 + 2.00000000000000*x + 7.00000000000000 over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... NotImplementedError: Only implemented for isomorphic curves over general fields. sage: E1 = EllipticCurve(Frac(PolynomialRing(ZZ,'t')), [2,19]); E1 Elliptic Curve defined by y^2 = x^3 + 2*x + 19 over Fraction Field of Univariate Polynomial Ring in t over Integer Ring sage: E2 = EllipticCurve(CC, [23,4]); E2 Elliptic Curve defined by y^2 = x^3 + 23.0000000000000*x + 4.00000000000000 over Complex Field with 53 bits of precision sage: E1.is_isogenous(E2) Traceback (most recent call last): ... NotImplementedError: Only implemented for isomorphic curves over general fields. """ from ell_generic import is_EllipticCurve if not is_EllipticCurve(other): raise ValueError("Second argument is not an Elliptic Curve.") if self.is_isomorphic(other): return True else: raise NotImplementedError("Only implemented for isomorphic curves over general fields.")
def is_sextic_twist(self, other): r""" Determine whether this curve is a sextic twist of another. INPUT: - ``other`` -- an elliptic curves with the same base field as self. OUTPUT: Either 0, if the curves are not sextic twists, or `D` if ``other`` is ``self.sextic_twist(D)`` (up to isomorphism). If ``self`` and ``other`` are isomorphic, returns 1. .. note:: Not fully implemented in characteristics 2 or 3. EXAMPLES:: sage: E = EllipticCurve_from_j(GF(13)(0)) sage: E1 = E.sextic_twist(2) sage: D = E.is_sextic_twist(E1); D!=0 True sage: E.sextic_twist(D).is_isomorphic(E1) True :: sage: E = EllipticCurve_from_j(0) sage: E1 = E.sextic_twist(12345) sage: D = E.is_sextic_twist(E1); D 575968320 sage: (D/12345).is_perfect_power(6) True """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve E = self F = other if not is_EllipticCurve(E) or not is_EllipticCurve(F): raise ValueError("arguments are not elliptic curves") K = E.base_ring() zero = K.zero_element() if not K == F.base_ring(): return zero j=E.j_invariant() if j != F.j_invariant() or not j.is_zero(): return zero if E.is_isomorphic(F): return K.one_element() char=K.characteristic() if char==2: raise NotImplementedError("not implemented in characteristic 2") elif char==3: raise NotImplementedError("not implemented in characteristic 3") else: # now char!=2,3: D = F.c6()/E.c6() if D.is_zero(): return D assert E.sextic_twist(D).is_isomorphic(F) return D
def is_quadratic_twist(self, other): r""" Determine whether this curve is a quadratic twist of another. INPUT: - ``other`` -- an elliptic curves with the same base field as self. OUTPUT: Either 0, if the curves are not quadratic twists, or `D` if ``other`` is ``self.quadratic_twist(D)`` (up to isomorphism). If ``self`` and ``other`` are isomorphic, returns 1. If the curves are defined over `\mathbb{Q}`, the output `D` is a squarefree integer. .. note:: Not fully implemented in characteristic 2, or in characteristic 3 when both `j`-invariants are 0. EXAMPLES:: sage: E = EllipticCurve('11a1') sage: Et = E.quadratic_twist(-24) sage: E.is_quadratic_twist(Et) -6 sage: E1=EllipticCurve([0,0,1,0,0]) sage: E1.j_invariant() 0 sage: E2=EllipticCurve([0,0,0,0,2]) sage: E1.is_quadratic_twist(E2) 2 sage: E1.is_quadratic_twist(E1) 1 sage: type(E1.is_quadratic_twist(E1)) == type(E1.is_quadratic_twist(E2)) #trac 6574 True :: sage: E1=EllipticCurve([0,0,0,1,0]) sage: E1.j_invariant() 1728 sage: E2=EllipticCurve([0,0,0,2,0]) sage: E1.is_quadratic_twist(E2) 0 sage: E2=EllipticCurve([0,0,0,25,0]) sage: E1.is_quadratic_twist(E2) 5 :: sage: F = GF(101) sage: E1 = EllipticCurve(F,[4,7]) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2); D!=0 True sage: F = GF(101) sage: E1 = EllipticCurve(F,[4,7]) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2) sage: E1.quadratic_twist(D).is_isomorphic(E2) True sage: E1.is_isomorphic(E2) False sage: F2 = GF(101^2,'a') sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2)) True A characteristic 3 example:: sage: F = GF(3^5,'a') sage: E1 = EllipticCurve_from_j(F(1)) sage: E2 = E1.quadratic_twist(-1) sage: D = E1.is_quadratic_twist(E2); D!=0 True sage: E1.quadratic_twist(D).is_isomorphic(E2) True :: sage: E1 = EllipticCurve_from_j(F(0)) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2); D 1 sage: E1.is_isomorphic(E2) True """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve E = self F = other if not is_EllipticCurve(E) or not is_EllipticCurve(F): raise ValueError("arguments are not elliptic curves") K = E.base_ring() zero = K.zero_element() if not K == F.base_ring(): return zero j=E.j_invariant() if j != F.j_invariant(): return zero if E.is_isomorphic(F): if K is rings.QQ: return rings.ZZ(1) return K.one_element() char=K.characteristic() if char==2: raise NotImplementedError("not implemented in characteristic 2") elif char==3: if j==0: raise NotImplementedError("not implemented in characteristic 3 for curves of j-invariant 0") D = E.b2()/F.b2() else: # now char!=2,3: c4E,c6E = E.c_invariants() c4F,c6F = F.c_invariants() if j==0: um = c6E/c6F x=rings.polygen(K) ulist=(x**3-um).roots(multiplicities=False) if len(ulist)==0: D = zero else: D = ulist[0] elif j==1728: um=c4E/c4F x=rings.polygen(K) ulist=(x**2-um).roots(multiplicities=False) if len(ulist)==0: D = zero else: D = ulist[0] else: D = (c6E*c4F)/(c6F*c4E) # Normalization of output: if D.is_zero(): return D if K is rings.QQ: D = D.squarefree_part() assert E.quadratic_twist(D).is_isomorphic(F) return D
def is_sextic_twist(self, other): r""" Determine whether this curve is a sextic twist of another. INPUT: - ``other`` -- an elliptic curves with the same base field as self. OUTPUT: Either 0, if the curves are not sextic twists, or `D` if ``other`` is ``self.sextic_twist(D)`` (up to isomorphism). If ``self`` and ``other`` are isomorphic, returns 1. .. note:: Not fully implemented in characteristics 2 or 3. EXAMPLES:: sage: E = EllipticCurve_from_j(GF(13)(0)) sage: E1 = E.sextic_twist(2) sage: D = E.is_sextic_twist(E1); D!=0 True sage: E.sextic_twist(D).is_isomorphic(E1) True :: sage: E = EllipticCurve_from_j(0) sage: E1 = E.sextic_twist(12345) sage: D = E.is_sextic_twist(E1); D 575968320 sage: (D/12345).is_perfect_power(6) True """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve E = self F = other if not is_EllipticCurve(E) or not is_EllipticCurve(F): raise ValueError("arguments are not elliptic curves") K = E.base_ring() zero = K.zero() if not K == F.base_ring(): return zero j = E.j_invariant() if j != F.j_invariant() or not j.is_zero(): return zero if E.is_isomorphic(F): return K.one() char = K.characteristic() if char == 2: raise NotImplementedError("not implemented in characteristic 2") elif char == 3: raise NotImplementedError("not implemented in characteristic 3") else: # now char!=2,3: D = F.c6() / E.c6() if D.is_zero(): return D assert E.sextic_twist(D).is_isomorphic(F) return D
def is_quadratic_twist(self, other): r""" Determine whether this curve is a quadratic twist of another. INPUT: - ``other`` -- an elliptic curves with the same base field as self. OUTPUT: Either 0, if the curves are not quadratic twists, or `D` if ``other`` is ``self.quadratic_twist(D)`` (up to isomorphism). If ``self`` and ``other`` are isomorphic, returns 1. If the curves are defined over `\mathbb{Q}`, the output `D` is a squarefree integer. .. note:: Not fully implemented in characteristic 2, or in characteristic 3 when both `j`-invariants are 0. EXAMPLES:: sage: E = EllipticCurve('11a1') sage: Et = E.quadratic_twist(-24) sage: E.is_quadratic_twist(Et) -6 sage: E1=EllipticCurve([0,0,1,0,0]) sage: E1.j_invariant() 0 sage: E2=EllipticCurve([0,0,0,0,2]) sage: E1.is_quadratic_twist(E2) 2 sage: E1.is_quadratic_twist(E1) 1 sage: type(E1.is_quadratic_twist(E1)) == type(E1.is_quadratic_twist(E2)) #trac 6574 True :: sage: E1=EllipticCurve([0,0,0,1,0]) sage: E1.j_invariant() 1728 sage: E2=EllipticCurve([0,0,0,2,0]) sage: E1.is_quadratic_twist(E2) 0 sage: E2=EllipticCurve([0,0,0,25,0]) sage: E1.is_quadratic_twist(E2) 5 :: sage: F = GF(101) sage: E1 = EllipticCurve(F,[4,7]) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2); D!=0 True sage: F = GF(101) sage: E1 = EllipticCurve(F,[4,7]) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2) sage: E1.quadratic_twist(D).is_isomorphic(E2) True sage: E1.is_isomorphic(E2) False sage: F2 = GF(101^2,'a') sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2)) True A characteristic 3 example:: sage: F = GF(3^5,'a') sage: E1 = EllipticCurve_from_j(F(1)) sage: E2 = E1.quadratic_twist(-1) sage: D = E1.is_quadratic_twist(E2); D!=0 True sage: E1.quadratic_twist(D).is_isomorphic(E2) True :: sage: E1 = EllipticCurve_from_j(F(0)) sage: E2 = E1.quadratic_twist() sage: D = E1.is_quadratic_twist(E2); D 1 sage: E1.is_isomorphic(E2) True """ from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve E = self F = other if not is_EllipticCurve(E) or not is_EllipticCurve(F): raise ValueError("arguments are not elliptic curves") K = E.base_ring() zero = K.zero() if not K == F.base_ring(): return zero j = E.j_invariant() if j != F.j_invariant(): return zero if E.is_isomorphic(F): if K is rings.QQ: return rings.ZZ(1) return K.one() char = K.characteristic() if char == 2: raise NotImplementedError("not implemented in characteristic 2") elif char == 3: if j == 0: raise NotImplementedError( "not implemented in characteristic 3 for curves of j-invariant 0" ) D = E.b2() / F.b2() else: # now char!=2,3: c4E, c6E = E.c_invariants() c4F, c6F = F.c_invariants() if j == 0: um = c6E / c6F x = rings.polygen(K) ulist = (x**3 - um).roots(multiplicities=False) if len(ulist) == 0: D = zero else: D = ulist[0] elif j == 1728: um = c4E / c4F x = rings.polygen(K) ulist = (x**2 - um).roots(multiplicities=False) if len(ulist) == 0: D = zero else: D = ulist[0] else: D = (c6E * c4F) / (c6F * c4E) # Normalization of output: if D.is_zero(): return D if K is rings.QQ: D = D.squarefree_part() assert E.quadratic_twist(D).is_isomorphic(F) return D