def isogenies_prime_degree(self, l=None, max_l=31): """ Generic code, valid for all fields, for arbitrary prime `l` not equal to the characteristic. INPUT: - ``l`` -- either None, a prime or a list of primes. - ``max_l`` -- a bound on the primes to be tested (ignored unless `l` is None). OUTPUT: (list) All `l`-isogenies for the given `l` with domain self. METHOD: Calls the generic function ``isogenies_prime_degree()``. This requires that certain operations have been implemented over the base field, such as root-finding for univariate polynomials. EXAMPLES:: sage: F = QQbar sage: E = EllipticCurve(F, [1,18]); E Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field sage: E.isogenies_prime_degree() Traceback (most recent call last): ... NotImplementedError: This code could be implemented for QQbar, but has not been yet. sage: F = CC sage: E = EllipticCurve(F, [1,18]); E Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision sage: E.isogenies_prime_degree(11) Traceback (most recent call last): ... NotImplementedError: This code could be implemented for general complex fields, but has not been yet. Examples over finite fields:: sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8]) sage: E.isogenies_prime_degree() [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 347438*x + 594729 over Finite Field of size 1000003, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 674846*x + 7392 over Finite Field of size 1000003, Isogeny of degree 23 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 390065*x + 605596 over Finite Field of size 1000003] sage: E.isogenies_prime_degree(2) [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003] sage: E.isogenies_prime_degree(3) [] sage: E.isogenies_prime_degree(5) [] sage: E.isogenies_prime_degree(7) [] sage: E.isogenies_prime_degree(13) [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] sage: E.isogenies_prime_degree([2, 3, 5, 7, 13]) [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 970389*x + 794257 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 29783*x + 206196 over Finite Field of size 1000003, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 999960*x + 78 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 878063*x + 845666 over Finite Field of size 1000003, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 1000003 to Elliptic Curve defined by y^2 = x^3 + 375648*x + 342776 over Finite Field of size 1000003] sage: E.isogenies_prime_degree([2, 4]) Traceback (most recent call last): ... ValueError: 4 is not prime. sage: E.isogenies_prime_degree(4) Traceback (most recent call last): ... ValueError: 4 is not prime. sage: E.isogenies_prime_degree(11) [] sage: E = EllipticCurve(GF(17),[2,0]) sage: E.isogenies_prime_degree(3) [] sage: E.isogenies_prime_degree(2) [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 9 over Finite Field of size 17, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x over Finite Field of size 17 to Elliptic Curve defined by y^2 = x^3 + 5*x + 8 over Finite Field of size 17] sage: E = EllipticCurve(GF(13^4, 'a'),[2,8]) sage: E.isogenies_prime_degree(2) [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 7*x + 4 over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (8*a^3+2*a^2+7*a+5)*x + (12*a^3+3*a^2+4*a+4) over Finite Field in a of size 13^4, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + (5*a^3+11*a^2+6*a+11)*x + (a^3+10*a^2+9*a) over Finite Field in a of size 13^4] sage: E.isogenies_prime_degree(3) [Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 9*x + 11 over Finite Field in a of size 13^4] Example to show that separable isogenies of degree equal to the characteristic are now implemented:: sage: E.isogenies_prime_degree(13) [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 2*x + 8 over Finite Field in a of size 13^4 to Elliptic Curve defined by y^2 = x^3 + 6*x + 5 over Finite Field in a of size 13^4] Examples over number fields (other than QQ):: sage: QQroot2.<e> = NumberField(x^2-2) sage: E = EllipticCurve(QQroot2, j=8000) sage: E.isogenies_prime_degree() [Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-36750)*x + 2401000 over Number Field in e with defining polynomial x^2 - 2, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (220500*e-257250)*x + (54022500*e-88837000) over Number Field in e with defining polynomial x^2 - 2, Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + (-150528000)*x + (-629407744000) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 = x^3 + (-220500*e-257250)*x + (-54022500*e-88837000) over Number Field in e with defining polynomial x^2 - 2] sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 sage: E.isogenies_prime_degree(2) [Isogeny of degree 2 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-36)*x + (-70) over Number Field in e with defining polynomial x^2 - 2] sage: E.isogenies_prime_degree(3) [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-1)*x over Number Field in e with defining polynomial x^2 - 2, Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x + (-6) over Number Field in e with defining polynomial x^2 - 2 to Elliptic Curve defined by y^2 + x*y + y = x^3 + (-171)*x + (-874) over Number Field in e with defining polynomial x^2 - 2] """ F = self.base_ring() if is_RealField(F): raise NotImplementedError( "This code could be implemented for general real fields, but has not been yet." ) if is_ComplexField(F): raise NotImplementedError( "This code could be implemented for general complex fields, but has not been yet." ) if F == rings.QQbar: raise NotImplementedError( "This code could be implemented for QQbar, but has not been yet." ) from isogeny_small_degree import isogenies_prime_degree if l is None: from sage.rings.all import prime_range l = prime_range(max_l + 1) if not isinstance(l, list): try: l = rings.ZZ(l) except TypeError: raise ValueError("%s is not prime." % l) if l.is_prime(): return isogenies_prime_degree(self, l) else: raise ValueError("%s is not prime." % l) L = list(set(l)) try: L = [rings.ZZ(l) for l in L] except TypeError: raise ValueError("%s is not a list of primes." % l) L.sort() return sum([isogenies_prime_degree(self, l) for l in L], [])
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