Ticket #13615: trac_13615_combined.patch

File trac_13615_combined.patch, 216.8 KB (added by cremona, 6 years ago)

Replaces all previous patches

  • doc/en/reference/plane_curves/index.rst

    # HG changeset patch
    # User John Cremona <john.cremona@gmail.com>
    # Date 1378312143 -3600
    # Node ID 3d8271960c10b64ce986723e355115f4d16b4c23
    # Parent  645aed29c48b6d5115f9d8795e426d3b6873522b
    #13615: implement isogenies for many small prime degrees
    
    diff --git a/doc/en/reference/plane_curves/index.rst b/doc/en/reference/plane_curves/index.rst
    a b  
    3131   sage/schemes/elliptic_curves/kodaira_symbol
    3232   sage/schemes/elliptic_curves/weierstrass_morphism
    3333   sage/schemes/elliptic_curves/ell_curve_isogeny
     34   sage/schemes/elliptic_curves/isogeny_small_degree
    3435   sage/schemes/elliptic_curves/ell_wp
    3536   sage/schemes/elliptic_curves/period_lattice
    3637   sage/schemes/elliptic_curves/formal_group
  • sage/schemes/elliptic_curves/ell_curve_isogeny.py

    diff --git a/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/sage/schemes/elliptic_curves/ell_curve_isogeny.py
    a b  
    4040
    4141.. Warning::
    4242
    43    Only cyclic isogenies are implemented (except for [2]). Some
     43   Only cyclic, separable isogenies are implemented (except for [2]). Some
    4444   algorithms may need the isogeny to be normalized.
    4545
    4646AUTHORS:
     
    5050- Chris Wuthrich : 7/09: changes: add check of input, not the full list is needed.
    5151  10/09: eliminating some bugs.
    5252
    53 - John Cremona and Jenny Cooley: 2009-07..11: implement `l`-isogenies
    54   for `l` = 2, 3, 5, 7 13 (the genus 0 cases) and also for `l` = 11,
    55   17, 19, 37, 43, 67 or 163 over `\QQ` (the sporadic cases with only
    56   finitely many `j`-invariants each).
    5753"""
    5854
    5955#*****************************************************************************
     
    38893885    return (pre_isom, post_isom, E1pr, E2pr, ker_poly)
    38903886
    38913887
    3892 ##########################################################################
    3893 # The following section is all about computing l-isogenies, where l is
    3894 # a prime.  The genus 0 cases `l` = 2, 3, 5, 7 and 13 are
    3895 # implemented over any field of characteristic not 2, 3 or `l`; over
    3896 # `\QQ` the "sporadic" cases `l` = 11, 17, 19, 37, 43, 67 or 163 with
    3897 # only finitely many `j`-invariants each. are also implemented.
    3898 ##########################################################################
    3899 
    3900 @cached_function
    3901 def Fricke_polynomial(l):
    3902     r"""
    3903     Fricke polynomial for ``l`` =2,3,5,7,13.
    3904 
    3905     For these primes (and these only) the modular curve `X_0(l)` has
    3906     genus zero, and its field is generated by a single modular
    3907     function called the Fricke module (or Hauptmodul), `t`.  There is
    3908     a classical choice of such a generator `t` in each case, and the
    3909     `j`-function is a rational function of `t` of degree `l+1` of the
    3910     form `P(t)/t` where `P` is a polynomial of degree `l+1`.  Up to
    3911     scaling, `t` is determined by the condition that the ramification
    3912     points above `j=\infty` are `t=0` (with ramification degree `1`)
    3913     and `t=\infty` (with degree `l`).  The ramification above `j=0`
    3914     and `j=1728` may be seen in the factorizations of `j(t)` and
    3915     `k(t)` where `k=j-1728`.
    3916 
    3917     OUTPUT:
    3918 
    3919     The polynomial `P(t)` as an element of `\ZZ[t]`.
    3920 
    3921     TESTS::
    3922 
    3923         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import Fricke_polynomial
    3924         sage: Fricke_polynomial(2)
    3925         t^3 + 48*t^2 + 768*t + 4096
    3926         sage: Fricke_polynomial(3)
    3927         t^4 + 36*t^3 + 270*t^2 + 756*t + 729
    3928         sage: Fricke_polynomial(5)
    3929         t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125
    3930         sage: Fricke_polynomial(7)
    3931         t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49
    3932         sage: Fricke_polynomial(13)
    3933         t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13
    3934     """
    3935     Zt = PolynomialRing(ZZ,'t')
    3936     t = Zt.gen()
    3937     if l==2: return (t+16)**3
    3938     elif l==3: return (t+3)**3*(t+27)
    3939     elif l==5: return (t**2+10*t+5)**3
    3940     elif l==7: return (t**2+5*t+1)**3 * (t**2+13*t+49)
    3941     elif l==13: return (t**2+5*t+13)*(t**4+7*t**3+20*t**2+19*t+1)**3
    3942     else:
    3943         raise ValueError, "The only genus zero primes are 2, 3, 5, 7 or 13."
    3944 
    3945 @cached_function
    3946 def Fricke_module(l):
    3947     r"""
    3948     Fricke module for ``l`` =2,3,5,7,13.
    3949 
    3950     For these primes (and these only) the modular curve `X_0(l)` has
    3951     genus zero, and its field is generated by a single modular
    3952     function called the Fricke module (or Hauptmodul), `t`.  There is
    3953     a classical choice of such a generator `t` in each case, and the
    3954     `j`-function is a rational function of `t` of degree `l+1` of the
    3955     form `P(t)/t` where `P` is a polynomial of degree `l+1`.  Up to
    3956     scaling, `t` is determined by the condition that the ramification
    3957     points above `j=\infty` are `t=0` (with ramification degree `1`)
    3958     and `t=\infty` (with degree `l`).  The ramification above `j=0`
    3959     and `j=1728` may be seen in the factorizations of `j(t)` and
    3960     `k(t)` where `k=j-1728`.
    3961 
    3962     OUTPUT:
    3963 
    3964     The rational function `P(t)/t`.
    3965 
    3966     TESTS::
    3967 
    3968         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import Fricke_module
    3969         sage: Fricke_module(2)
    3970         (t^3 + 48*t^2 + 768*t + 4096)/t
    3971         sage: Fricke_module(3)
    3972         (t^4 + 36*t^3 + 270*t^2 + 756*t + 729)/t
    3973         sage: Fricke_module(5)
    3974         (t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125)/t
    3975         sage: Fricke_module(7)
    3976         (t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49)/t
    3977         sage: Fricke_module(13)
    3978         (t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t
    3979     """
    3980     try:       
    3981         t = PolynomialRing(QQ,'t').gen()
    3982         return Fricke_polynomial(l) / t
    3983     except ValueError:
    3984         raise ValueError, "The only genus zero primes are 2, 3, 5, 7 or 13."
    3985 
    3986 @cached_function
    3987 def Psi(l, use_stored=True):
    3988     r"""
    3989     Generic kernel polynomial for genus one primes.
    3990 
    3991     For each of the primes `l` for which `X_0(l)` has genus zero
    3992     (namely `l=2,3,5,7,13`), we may define an elliptic curve `E_t`
    3993     over `\QQ(t)`, with coefficients in `\ZZ[t]`, which has good
    3994     reduction except at `t=0` and `t=\infty` (which lie above
    3995     `j=\infty`) and at certain other values of `t` above `j=0` when
    3996     `l=3` (one value) or `l\equiv1\pmod{3}` (two values) and above
    3997     `j=1728` when `l=2` (one value) or `l\equiv1 \pmod{4}` (two
    3998     values).  (These exceptional values correspond to endomorphisms of
    3999     `E_t` of degree `l`.)  The `l`-division polynomial of `E_t` has a
    4000     unique factor of degree `(l-1)/2` (or 1 when `l=2`), with
    4001     coefficients in `\ZZ[t]`, which we call the Generic Kernel
    4002     Polynomial for `l`.  These are used, by specialising `t`, in the
    4003     function :meth:`isogenies_prime_degree_genus_0`, which also has to
    4004     take into account the twisting factor between `E_t` for a specific
    4005     value of `t` and the short Weierstrass form of an elliptic curve
    4006     with `j`-invariant `j(t)`.  This enables the computation of the
    4007     kernel polynomials of isogenies without having to compute and
    4008     factor division polynomials.
    4009 
    4010     All of this data is quickly computed from the Fricke modules, except
    4011     that for `l=13` the factorization of the Generic Division Polynomial
    4012     takes a long time, so the value have been precomputed and cached; by
    4013     default the cached values are used, but the code here will recompute
    4014     them when ``use_stored`` is ``False``, as in the doctests.
    4015 
    4016     INPUT:
    4017 
    4018     - ``l`` -- either 2, 3, 5, 7, or 13.
    4019 
    4020     - ``use_stored`` (boolean, default True) -- If True, use
    4021       precomputed values, otherwise compute them on the fly.
    4022 
    4023     .. note:: 
    4024    
    4025        This computation takes a negligible time for `l=2,3,5,7'
    4026        but more than 100s for `l=13`.  The reason
    4027        for allowing dynamic computation here instead of just using
    4028        precomputed values is for testing.
    4029 
    4030     TESTS::
    4031 
    4032         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import Fricke_module, Psi
    4033         sage: assert Psi(2, use_stored=True) == Psi(2, use_stored=False)
    4034         sage: assert Psi(3, use_stored=True) == Psi(3, use_stored=False)
    4035         sage: assert Psi(5, use_stored=True) == Psi(5, use_stored=False)
    4036         sage: assert Psi(7, use_stored=True) == Psi(7, use_stored=False)
    4037         sage: assert Psi(13, use_stored=True) == Psi(13, use_stored=False) # not tested (very long time)
    4038     """
    4039     if not l in [2,3,5,7,13]:
    4040         raise ValueError, "Genus zero primes are 2, 3, 5, 7 or 13."
    4041 
    4042     R = PolynomialRing(ZZ,2,'Xt')
    4043     X,t = R.gens()
    4044 
    4045     if use_stored:
    4046         if l==2:
    4047             return X + t + 64
    4048         if l==3:
    4049             return X + t + 27
    4050         if l==5:
    4051             return X**2 + 2*X*(t**2 + 22*t + 125)+ (t**2 + 22*t + 89) * (t**2 + 22*t + 125)
    4052         if l==7:
    4053             return (X**3 + 3*(t**2 + 13*t + 49)*X**2
    4054                     + 3*(t**2 + 13*t + 33)*(t**2 + 13*t + 49)*X
    4055                     + (t**2 + 13*t + 49)*(t**4 + 26*t**3 + 219*t**2 + 778*t + 881))
    4056         if l==13:
    4057             return (t**24 + 66*t**23 + 2091*t**22 + 6*X*t**20 + 42582*t**21 + 330*X*t**19 + 627603*t**20 + 8700*X*t**18 + 7134744*t**19 + 15*X**2*t**16 + 146886*X*t**17 + 65042724*t**18 + 660*X**2*t**15 + 1784532*X*t**16 + 487778988*t**17 + 13890*X**2*t**14 + 16594230*X*t**15 + 3061861065*t**16 + 20*X**3*t**12 + 186024*X**2*t**13 + 122552328*X*t**14 + 16280123754*t**15 + 660*X**3*t**11 + 1774887*X**2*t**12 + 735836862*X*t**13 + 73911331425*t**14 + 10380*X**3*t**10 + 12787272*X**2*t**11 + 3646188342*X*t**12 + 287938949178*t**13 + 15*X**4*t**8 + 102576*X**3*t**9 + 71909658*X**2*t**10 + 15047141292*X*t**11 + 964903805434*t**12 + 330*X**4*t**7 + 707604*X**3*t**8 + 321704316*X**2*t**9 + 51955096824*X*t**10 + 2781843718722*t**11 + 3435*X**4*t**6 + 3582876*X**3*t**7 + 1155971196*X**2*t**8 + 150205315932*X*t**9 + 6885805359741*t**10 + 6*X**5*t**4 + 21714*X**4*t**5 + 13632168*X**3*t**6 + 3343499244*X**2*t**7 + 362526695094*X*t**8 + 14569390179114*t**9 + 66*X**5*t**3 + 90660*X**4*t**4 + 39215388*X**3*t**5 + 7747596090*X**2*t**6 + 725403501318*X*t**7 + 26165223178293*t**8 + 336*X**5*t**2 + 255090*X**4*t**3 + 84525732*X**3*t**4 + 14206132008*X**2*t**5 + 1189398495432*X*t**6 + 39474479008356*t**7 + X**6 + 858*X**5*t + 472143*X**4*t**2 + 132886992*X**3*t**3 + 20157510639*X**2*t**4 + 1569568001646*X*t**5 + 49303015587132*t**6 + 1014*X**5 + 525954*X**4*t + 144222780*X**3*t**2 + 21320908440*X**2*t**3 + 1622460290100*X*t**4 + 49941619724976*t**5 + 272259*X**4 + 96482100*X**3*t + 15765293778*X**2*t**2 + 1260038295438*X*t**3 + 39836631701295*t**4 + 29641924*X**3 + 7210949460*X**2*t + 686651250012*X*t**2 + 23947528862166*t**3 + 1506392823*X**2 + 231462513906*X*t + 10114876838391*t**2 + 35655266790*X + 2644809206442*t + 317295487717)
    4058 # The coefficients for l=13 are:
    4059 # X**6: 1
    4060 # X**5: (6) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)
    4061 # X**4: (3) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13) * (5*t**4 + 55*t**3 + 260*t**2 + 583*t + 537)
    4062 # X**3: (4) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)**2 * (5*t**6 + 80*t**5 + 560*t**4 + 2214*t**3 + 5128*t**2 + 6568*t + 3373)
    4063 # X**2: (3) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**2 * (5*t**8 + 110*t**7 + 1045*t**6 + 5798*t**5 + 20508*t**4 + 47134*t**3 + 67685*t**2 + 54406*t + 17581)
    4064 # X**1: (6) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**10 + 27*t**9 + 316*t**8 + 2225*t**7 + 10463*t**6 + 34232*t**5 + 78299*t**4 + 122305*t**3 + 122892*t**2 + 69427*t + 16005)
    4065 # X**0: (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**14 + 38*t**13 + 649*t**12 + 6844*t**11 + 50216*t**10 + 271612*t**9 + 1115174*t**8 + 3520132*t**7 + 8549270*t**6 + 15812476*t**5 + 21764840*t**4 + 21384124*t**3 + 13952929*t**2 + 5282630*t + 854569)
    4066 #
    4067 
    4068     # Here the generic kernel polynomials are actually calculated:
    4069     j = Fricke_module(l)
    4070     k = j-1728
    4071     from sage.misc.all import prod
    4072     f = prod( [p for p,e in j.factor() if e==3]
    4073              +[p for p,e in k.factor() if e==2])
    4074     A4 = -3*t**2*j*k // f**2
    4075     A6 = -2*t**3*j*k**2 // f**3
    4076     E = EllipticCurve([0,0,0,A4,A6])
    4077     assert E.j_invariant() == j
    4078     return E.division_polynomial(l,X).factor()[0][0]
    4079 
    4080 
    4081 def isogenies_prime_degree_genus_0(E, l=None):
    4082     """
    4083     Returns list of ``l`` -isogenies with domain ``E``.
    4084 
    4085     INPUT:
    4086 
    4087     - ``E`` -- an elliptic curve.
    4088 
    4089     - ``l`` -- either None or 2, 3, 5, 7, or 13.
    4090 
    4091     OUTPUT:
    4092 
    4093     (list) When ``l`` is None a list of all isogenies of degree 2, 3,
    4094     5, 7 and 13, otherwise a list of isogenies of the given degree.
    4095 
    4096     .. note::
    4097 
    4098        This function would normally be invoked indirectly via
    4099        ``E.isogenies_prime_degree(l)``, which automatically calls the
    4100        appropriate function.
    4101 
    4102     EXAMPLES::
    4103    
    4104         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_prime_degree_genus_0
    4105         sage: E = EllipticCurve([0,12])
    4106         sage: isogenies_prime_degree_genus_0(E, 5)
    4107         []
    4108 
    4109         sage: E = EllipticCurve('1450c1')   
    4110         sage: isogenies_prime_degree_genus_0(E)   
    4111         [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250 over Rational Field]
    4112 
    4113         sage: E = EllipticCurve('50a1')   
    4114         sage: isogenies_prime_degree_genus_0(E) 
    4115         [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field,
    4116         Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
    4117     """
    4118     if not l in [2, 3, 5, 7, 13, None]:
    4119         raise ValueError, "Isogenies must be of degree 2, 3, 5, 7 or 13."
    4120     F = E.base_ring()
    4121     j = E.j_invariant()
    4122     if F.characteristic() in [2, 3, l]:
    4123         raise NotImplementedError, "2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny."
    4124     if l==2:
    4125         return isogenies_2(E)
    4126     if l==3:
    4127         return isogenies_3(E)
    4128     if j==F(0):
    4129         if l==5:
    4130             return isogenies_5_0(E)
    4131         if l==7:
    4132             return isogenies_7_0(E)
    4133         if l==13:
    4134             return isogenies_13_0(E)
    4135     if j==F(1728):
    4136         if l==5:
    4137             return isogenies_5_1728(E)
    4138         if l==7:
    4139             return isogenies_7_1728(E)
    4140         if l==13:
    4141             return isogenies_13_1728(E)
    4142  
    4143     if l != None:
    4144         R = PolynomialRing(F,'t')
    4145         t = R.gen()
    4146         f = R(Fricke_polynomial(l))
    4147         t_list = (f-j*t).roots(multiplicities=False)
    4148         t_list.sort()
    4149         # The generic kernel polynomial applies to a standard curve
    4150         # E_t with the correct j-invariant; we must compute the
    4151         # appropriate twising factor to scale X by:
    4152         c4, c6 = E.c_invariants()
    4153         T = c4/(3*c6)
    4154         jt = Fricke_module(l)
    4155         kt = jt-1728
    4156         from sage.misc.all import prod
    4157         psi = Psi(l)
    4158         X = t
    4159         f = R(prod( [p for p,e in jt.factor() if e==3]
    4160                  +[p for p,e in kt.factor() if e==2]))
    4161         kernels = [R(psi(X*T*(j-1728)*t0/f(t0),t0)) for t0 in t_list]
    4162         kernels = [ker.monic() for ker in kernels]
    4163         E1 = EllipticCurve([-27*c4,-54*c6])
    4164         w = E.isomorphism_to(E1)
    4165         model = "minimal" if F is QQ else None
    4166         isogs = [E1.isogeny(kernel=ker, model=model) for ker in kernels]
    4167         [isog.set_pre_isomorphism(w) for isog in isogs]
    4168         return isogs
    4169 
    4170     if l == None:
    4171         return sum([isogenies_prime_degree_genus_0(E, l) for l in [2,3,5,7,13]],[])
    4172 
    4173 
    4174 # The following is data to be used in isogenies_sporadic_Q. Over Q
    4175 # there are only finitely many j-invariants of curves with l-isogenies
    4176 # where l is not equal to 2, 3, 5, 7 or 13. In these cases l is equal
    4177 # to 11, 17, 19, 37, 43, 67 or 163. We refer to these l as "sporadic".
    4178 #
    4179 # isog_table is indexed by the possible sporadic (l,j) pairs and lists
    4180 # ((a4,a6),f) where (a4,a6) are the invariants of a short Weierstrass
    4181 # model of one curve with that j-invariant,and f is the factor of
    4182 # degree (l-1)/2 of the l-division polynomial of that curve. Then
    4183 # whenever we have a curve of that j-invariant, we can compute the
    4184 # corresponding l-isogeny by just scaling f by the right twisting
    4185 # factor and using the result as a kernel-polynomial.
    4186 
    4187 # Sample code to precompute this data.  Note that working over ZZ
    4188 # instead of QQ is a lot faster (in Sage 4.2):
    4189 #
    4190 #sage: j = -297756989/2; l = 17
    4191 #sage: E = EllipticCurve(ZZ,EllipticCurve(j=j).short_weierstrass_model().ainvs())
    4192 #sage: E.division_polynomial(l,polygen(ZZ)).factor()[1][0].coefficients()
    4193 #
    4194 #sage: j = -884736000; l = 43
    4195 #sage: E = EllipticCurve(ZZ,EllipticCurve(j=j).short_weierstrass_model().ainvs())
    4196 #sage: E.division_polynomial(l,polygen(ZZ)).factor()[1][0].coefficients()
    4197 
    4198 
    4199 isog_table = dict()
    4200 
    4201 isog_table[(11,QQ('-32768'))] = ([-9504, 365904], [1294672896, -92835072, 1463616, 7920, -264, 1])
    4202 
    4203 isog_table[(11,QQ('-121'))] = ([-3267, -280962], [1480352841, -56169531, -2829222, 10890, 429, 1])
    4204 
    4205 isog_table[(11,QQ('-24729001'))] = ([-38907, -2953962], [-20349931239, -424530315, -134838, 53658, 429, 1])
    4206 
    4207 isog_table[(17,QQ('-297756989/2'))] = ([-3940515, 3010787550], [-6458213126940667330314375, 34699336325466068070000, -72461450055340471500, 68342601718080000, -15140380554450, -25802960400, 23981220, -8160, 1])
    4208 
    4209 isog_table[(17,QQ('-882216989/131072'))] = ([-856035, -341748450], [103687510635057329105625, 961598491955315190000, 1054634146768300500, -6553122389064000, -14554350284850, -2046589200, 13185540, 8160, 1])
    4210 
    4211 isog_table[(19,QQ('-884736'))] = ([-608, 5776], [-34162868224, -8540717056, 6405537792, -1123778560, 84283392, -2033152, -92416, 6992, -152, 1])
    4212 
    4213 isog_table[(37,QQ('-9317'))] = ([-10395, 444150],[-38324677699334121599624973029296875, -17868327793500376961572310472656250, 2569568362004197901139023084765625, -95128267987528547588017818750000, -822168183291347061312510937500, 134395594560592096297190625000, -2881389756919344324888937500, -2503855007083401977250000, 922779077075655997443750, -11503912310262102937500, -18237870962450291250, 1457822151548910000, -10087015556047500, -13677678063000, 490243338900, -2461460400, 5198445, -4410, 1])
    4214 
    4215 isog_table[(37,QQ('-162677523113838677'))] = ([-269675595, -1704553285050], [-31653754873248632711650187487655160190139073510876609346911928661154296875/37, -1469048260972089939455942042937882262144594798448952781325533511718750, -1171741935131505774747142644126089902595908234671576131857702734375, -574934780393177024547076427530739751753985644656221274606250000, -193516922725803688001809624711400287605136013195315374687500, -47085563820928456130325308223963045033502182349693125000, -8472233937388712980597845725196873697064639957437500, -1124815211213953261752081095348112305023653750000, -105684015609077608033913080859605951322531250, -5911406027236569746089675554748135312500, 22343907270397352965399097794968750, 43602171843758666292581116410000, 5054350766002463251474186500, 350135768194635636171000, 16633063574896677300, 549939627039600, 12182993865, 163170, 1])
    4216 
    4217 isog_table[(43,QQ('-884736000'))] = ([-13760, 621264],[-1961864562041980324821547425314935668736, 784270445793223959453256359333693751296, -120528107728500223255333768387027271680, 10335626145581464192664472924270362624, -568426570575654606865505142156820480, 21261993723422650574629752537088000, -544630471727787626557612832587776, 8870521306520473088172555763712, -54993059067301585878494740480, -1434261324709904840432549888, 50978938193065926383894528, -845761855773797582372864, 8627493611216601088000, -48299605284169187328, -32782260293713920, 3415534989828096, -34580115625984, 199359712512, -730488128, 1658080, -2064, 1])
    4218 
    4219 isog_table[(67,QQ('-147197952000'))] = ([-117920, 15585808], [426552448394636714720553816389274308035895411389805883034985546818882031845376, -55876556222880738651382959148329502876096075327084935039031884373558741172224, 3393295715290183821010552313572221545212247684503012173117764703828786020352, -125729166452196578653551230178028570067747190427221869867485520072257044480, 3121342502030777257351089270834971957072933779704445667351054593298530304, -52544031605544530265465344472543470442324636919759253720520768014516224, 532110915869155495738137756847596184665209453108323879594125221167104, -399031158106622651277981701966309467713625045637309782055519780864, -101914346170769215732007802723651742508893380955930030421292613632, 2296526155500449624398016447877283594461904009374321659789443072, -31950871094301541469458501953701002806003991982768349794795520, 329792235011603804948028315065667439678526339671142107709440, -2655636715955021784085217734679612378726442691190553837568, 16825164648840434987220620681420687654501026066872664064, -81705027839007003131400500185224450729843244954288128, 273656504606483403474090105104132405333665144373248, -320807702482945680116212224172370503903312084992, -3166683390779345463318656135338172047199043584, 27871349428383710305216046431806697565585408, -132774697798318602604125735604528772808704, 436096215568182871014215818309741314048, -964687143341252402362763535357837312, 942144169187362941776488535425024, 2794850106281773765892648206336, -17236916236678037389276086272, 50979778712911923486851072, -105035658611718440992768, 161833913559276412928, -188675698610077696, 163929317513984, -102098677888, 42387952, -10184, 1])
    4220 
    4221 isog_table[(163,QQ('-262537412640768000'))] = ([-34790720, 78984748304], [11937033609701771608400008302859181021419097217821452062564326844817505228663098831008549807845273606080544999996020379100442085010011180910986311230744539492209201267851475053850145465949031314131282944262561686476431332761205504055553653209756637748416809823347727611717499380045401030656, -195130071447306655273524569473852352290010571088570084255929596426827972913675959924834214553822436039185267072655230231264389277855757579340840680919752147359277865429131554516271296434318501723193704667609983954393732283396979741770275596479169906167026623493287956522391758781645062144, 1427502734760154784443139998885173873805698542265553947708985997014264802221336771918193375050938963016560184673026895611200993837000754187703921657388546609660768979949394789838000919808563779734300559653270446650866261801622261730386746625133970663551831816512698564779980290036596736, -5599207432852992026535855102327743354503965526118767584653806869099469434869389394471452436350209911401734358692516268244363981178003440912521398279843764610451103952982463228121628686179444592844803463454880601969041617668281227800515971090274318968755339891485627349912827843313664, 7275289443663173375117187980461451723630939807433676133488193878209459535146604043302393215325736700753114238886326617501903060793779318898498537340122928915051396994852249905774785383484964157718761647679761326405167986820403416875550489904598260809039588027484880575324789669888, 53852767252251176711316610474871670511285949778037067647446607721301053062542360857644949076379793988972999080753585666268471181395581176311086709516236139859119228114940726664020344711163961450649040900179940667704933096423082541578086102752168151408016128448757608609516355584, -441024601763314150109608522830440149169771622404264936395215000306188259683627792348927267455527449622616337194882061278315837263834842622422058957336768392927319786456429412773335490683756389242358011775192147290260088212928183893496023497385031567935590156495818971603271680, 1923729652470036657640234466480856403679261373466564217770510758620007251234737653848912112257887106718711179570266106782165127910894792855741763009046440188368346201617134183692667813264354753020558715833289878752200363206184231817927249353441775148372373391040829093576704, -6174291905252822700639099970860178217904525535465573253756653994759145320917644436646210500761314537511653465341404223911052812759676375813287317189557074876672717009913962857515263325087926781282727274494599622098970326546685474959128901831166082055481492871737587531776, 15963605433939241348215386312076502855685142708851007052060264896693306401589916424547272907372369971200908960298559196028000249867821387055883338894215055448441454208145184664251082508258481820123154014612667230187589409024581605410594578299015578613903351914203971584, -34687777075075826936035422448136670540047824478867437603900549472003349053758981331083701038247602826434094223697740838012005963350495346494192086319952577715870471857062004211165110944749546489357024333327851492892063261902845789001287880518909468079710544890691584, 64935614565701660925102862834870557968917923758048315817978089985628103203452108238400473842703675144415856702414743965076964752315718880263247146806212144113325233966196430978981658754610129252819800656290540439882400228191972297000590950499022332532802841477120, -106450113192928986500166510746460290010686605565802553549898115364953461571938149159855780359758326598170956839310849727549767334328481520722457671184262149140997347199434067316119593873464084542168958564857207310255104210252802288265107074620056433232296542208, 154588468341182819097156049664780175805765082709542906853062319968823210709884467518965950031344875777123989196305422245441384128571495551803479155842444104959551491130118809781140758556182128829570214830557657320822341658937375265326185627024588353675722752, -200559814675071715715147513664537685696543665835231560123119674695431140901874837885144270078673500682009909076723885595600964688749788075855566556738418513204701882392037282897429720984011892144438563658741417367819609826485149957684720592798005782904832, 233913230287794067984901680255098952718268709897211662836962202594844321932231309396660409956864579218254273924904394011519168528453166798219739516110916032144001430976170021740673624911101610999174313953331179592523559209806130064362331035786304028672, -246353703535830799051965068435640665615241585380168769205605419959931340172791084855084136413845436489354260626697043416419953596294256639939636661074827002386688825389366314922889935515780006872313799807871034941783710991661439846743406825846079488, 234982742638283161239147075499923192184558615040750093346909554959954534765162320677404212311317141015056956519607730625264033505832417237335526289717986324622989530401755659861160278474288472483456460761582961131223878005034852988312569782468608, -203278213565303083958289848507904983111914464281937008996800600743049033135780053019308180654889993715847194782810638377233384956677984229396984592095978852141937402724743415866647478390224972086303117541277057454016741537801255285401042550784, 159421011266364165773350759598961923468646295930442671951663830439105229019095602850806206849694626149081055860876320252885592409781300283802068036284087012054926328984117466238728138017296876920468741929209733382315316048593848804000661504, -113020918346823224387675962727710849438448560054728764538889949910907956081636084818673918939857811981198128625134001275445247927733612860826192033364144709296859805908448480126055187856540001252440723696556907592809391568682658983575552, 71945777186858148520189111385851657591994785437936790663752048596268908397761761228530149720647914698227096033298596468433406211022425872184679773706985835273196359946527329295352840585601589987654250252509940697181497393634479177728, -40553506248279853197899380016510447069205875473858373944916667311741237594752103405195544436215283638784303466518029972315361472909380024525230365389883507930702477745185560842399992120410631726800835247081534888734998176190169088, 19639696188973552762819015734509385187497753279018359326954702329472344393424778261565226791972589248949076879073752940457430177635689762236418319921157145929450429275277598105096782299310906043071624518383647513981402864418816, -7557145635717782395604678688732309739123765964398036300935902895029921544449817739871127195837816246027098669576710973724603305169613035210748794125702623638061784934800621663541549758981147547220745886014319375033833619456, 1657074863449131529294393850366914004166071540911557375298352670995793916631379837217699843183161870412953109096989706473414891817476345269315000071815674837414249807862563049048940888990780356828116926372826050377809920, 594537607406738614488647166334439665406200193881374352383582637957395810395355986219181323336507140663007282377906531198753011484726171889166159296232442266402815351908351664480142997422997116094990105400004717838336, -1063381335685557601789471169771716160614658527547206527560235661204306306147122486589145738731952820149525220010993135210540125800587297277176980780550749659568216404307556497848427558893515024809067113577642459136, 866504016710397283549081797838552191017551170056714418172658679484342314216337494688411296133019156758665490378562995489461120013841310945167448587950589192882728019730184100760635093600626150305226434294054912, -544456451437710104677464982275658569122639544706468906698603670935572135268235880234260773620839923609980624261711876187191086008709319550421652238153751371247896403810296918434808016324776218527300472274944, 291391938923983436973777049837536733140215048414562274102609644110225500962890424001140034799254161420207705596799832439286323749581485058440291289292376834767289200150488260103720502388531610043446984704, -137669336373928330264003425607593379960726875901008061728935571651808147336578784033262243606118618305155146994101199276509296485578362621442124562716722538959248783675765430495753630524650420015464448, 58305039769563586190846386880024028458953483779423358562963969531061253550565868881984384427294827940260948562007946246585988242539388915757370599713569828414708265704775708180369817440224330907648, -22263674613297409152475382098514675408629524088165884591926938276387287183647211206514841583522457779552325379611699721363009213935995055122374833256328128159685068070573439567341889102047870976, 7659525572873653643686667682470156611730287715779213959462404612107764289631014622079262434509991525269350939684751076168111178931547830737285816290499346814316593688339716060537705476390912, -2356369509601030092354164626593105564281508081035914666378162646456624099153984023946457193322861690246151591627985138670141283491665875837349056368982626874320059053912723460560567402496, 636306064623878566247238117586667093960745761448319133509756604897082306674457051834692637631208787669480579961449146859307914219525683813169045631019945325543755784485150162136596480, -144354698667964959131302121388611435649331689922451077357726958728526160763985021377919777057073652734054824995380136026354322489788621439866623621032883911971992887755746217820160, 24121955586756417060840806312875152536841537469465641066665477185642959713399102667004561835703554642486033432650174169972215286732914841507194929969333501923213681889898397696, -1062982554332400020436047718307967606435230424325029173087078414691100152298424407470637592479633445244263771003475924500470457802708388802132021409732119617604143984672768, -1289959173517591900879403877417447464323361120695839905879179383576917611515563011791770601288187258710836960962551744314331281738572022125094897455138775637822772609024, 713094034093241133139975542207369737377005379966568397923649557581354608722973890056780743426440880397949894405054289149004564424971813787111450018625163532324306944, -254627379967901645020979419858451704766383325190491161773871149760504423262065255127251316663797380198173202687716259997416292667070368594859769612820620832145408, 73141763506085097918144459824978126154049420184880822723900482544151820781804249152002290712777719695036970656528265835764223704583688284269989955443519127552, -17838537225679516940483486695156689114251551141417084228356667456567223074797422210814066353881812352204911178711536306766419580650031647883778868599848960, 3732949472404613028683276858400771022649020140479952475050562287824228475488013407594597423014344735572239887680502683815016952233794807477380489150464, -658090831088275932021697572468169724648153295038942023393017242911882324988827102897240587742441233130939688197251981440661637431663180512231424000, 91044773494274344573228085560493548892450695165631132364575161840790371925870648417274049055693061297980952723608086693629684733411639066361856, -7206875978668204173369106020317806614830036116031258178074085756310402308591937698714169573782276745187407867676712962154996289706219536384, -819751497058465540849522914081577930969395072622202448379227754265195552229316711754131018363430793506957620878700584807196119659446272, 524492219141524596329431820120551446539246304466694008535436881375050446937946483408452355745347329681867559263476448413099237572608, -144831995016562693238485974645571530330971707229081912571899541756458417275452663670185243929333997861822834344607487043313860608, 29914869637979316056234691641068533246353548074478964560456384907200155525359490145390698951538414992573246875654471802683392, -5051703199007242317980870828294675665554938059871421101373455640671888804716466166733214891733545898164243959713215021056, 704266224450794229753813389400889235502895246267920454892105495898823500254340026026030392861415807391779452916596736, -77090914220067457257437168730743598007998214624866646138957596697882331770536104168830311427039146990575867133952, 5185529715527985800186976473360862373518426289807725150611458977619779754244941008386724289180811582624497664, 253997773097193639890870939442154039645526260966991421810387625142025920490445698037959549218977356972032, -167663051891371188948811201282888303918118872228509878481620659513761819092806840088343319460416847872, 37111139278046773379558801627698801653586358926939257719148812112681156722739468064234356797865984, -6094794232647488071603134809336879629321484740792083961518604911291776122012806633249006682112, 837291566508665017874331015912241564512130987193765470835615200761060354034220082158108672, -100296887606046826616864046733353580911852480578758327196473644505408067503452896362496, 10671531126308719182671886696772003009468978048122050876385337250105289881860177920, -1017660211057522997139542974021461951590281854561469513981031668621068390629376, 87341651749945752980300268787472991750253192293865191008561736741703122944, -6755055811837604655292473395831392832731215030180150346004905802596352, 470435697396489049890276884918878813522261509046808135502735081472, -29431936259973770189795237369002643735145492537132570738950144, 1647955729708147681608319291051493831298410618099083509760, -82151504501901440318090519089275042334656836617109504, 3621394962905672351516373383975280471835697741824, -139946424433346723333934826799658073276284928, 4689146702972667351768128807176661303296, -134326059738838559898371882636836864, 3230090486862617839209120497664, -63628315178835325152092160, 992573003659549935360, -11668560578458368, 95539651616, -472048, 1])
    4222 
    4223 
    4224 
    4225 def isogenies_sporadic_Q(E, l=None):
    4226     """
    4227     Returns list of ``l`` -isogenies with domain ``E`` (defined over `\QQ`).
    4228 
    4229     Returns a list of sporadic l-isogenies from E (l = 11, 17, 19, 37,
    4230     43, 67 or 163). Only for elliptic curves over `\QQ`.
    4231 
    4232     INPUT:
    4233 
    4234     - ``E`` -- an elliptic curve defined over `\QQ`.
    4235 
    4236     - ``l`` -- either None or a prime number.
    4237 
    4238     OUTPUT:
    4239 
    4240     (list) If ``l`` is None, a list of all isogenies with domain ``E``
    4241     and of degree 11, 17, 19, 37, 43, 67 or 163; otherwise a list of
    4242     isogenies of the given degree.
    4243 
    4244     .. note::
    4245 
    4246        This function would normally be invoked indirectly via
    4247        ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate
    4248        function.
    4249 
    4250     EXAMPLES::
    4251 
    4252         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_sporadic_Q                                                                       
    4253         sage: E = EllipticCurve('121a1')   
    4254         sage: isogenies_sporadic_Q(E, 11)
    4255         [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field]
    4256         sage: isogenies_sporadic_Q(E, 13)
    4257         []
    4258         sage: isogenies_sporadic_Q(E, 17)
    4259         []
    4260         sage: isogenies_sporadic_Q(E)   
    4261         [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field]
    4262          
    4263         sage: E = EllipticCurve([1, 1, 0, -660, -7600])   
    4264         sage: isogenies_sporadic_Q(E, 17)
    4265         [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field]
    4266         sage: isogenies_sporadic_Q(E)   
    4267         [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field]
    4268         sage: isogenies_sporadic_Q(E, 11)
    4269         []
    4270        
    4271         sage: E = EllipticCurve([0, 0, 1, -1862, -30956])   
    4272         sage: isogenies_sporadic_Q(E, 11)
    4273         []
    4274         sage: isogenies_sporadic_Q(E, 19)
    4275         [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
    4276         sage: isogenies_sporadic_Q(E)   
    4277         [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
    4278 
    4279         sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
    4280         sage: E.conductor()
    4281         19600
    4282         sage: isogenies_sporadic_Q(E,37)
    4283         [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field]
    4284 
    4285         sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750])
    4286         sage: E.conductor()                                       
    4287         148225
    4288         sage: isogenies_sporadic_Q(E,37)
    4289         [Isogeny of degree 37 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075 over Rational Field]
    4290 
    4291         sage: E = EllipticCurve([-3440, 77658])         
    4292         sage: E.conductor()                   
    4293         118336
    4294         sage: isogenies_sporadic_Q(E,43)       
    4295         [Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 over Rational Field]
    4296 
    4297         sage: E = EllipticCurve([-29480, -1948226])     
    4298         sage: E.conductor()
    4299         287296
    4300         sage: isogenies_sporadic_Q(E,67)
    4301         [Isogeny of degree 67 from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438 over Rational Field]
    4302 
    4303         sage: E = EllipticCurve([-34790720, -78984748304])
    4304         sage: E.conductor()
    4305         425104
    4306         sage: isogenies_sporadic_Q(E,163)
    4307         [Isogeny of degree 163 from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088 over Rational Field]
    4308     """
    4309     if E.base_ring() != QQ:
    4310         raise ValueError, "The elliptic curve must be defined over QQ."
    4311     j = E.j_invariant()
    4312     j = QQ(j)
    4313     if l != None:
    4314         if not l.is_prime():
    4315             raise ValueError("%s is not prime."%l)
    4316         if not isog_table.has_key((l,j)):
    4317             return []
    4318         Ew = E.short_weierstrass_model()
    4319         E_to_Ew = E.isomorphism_to(Ew)
    4320         c4, c6 = Ew.c_invariants()
    4321         (a4,a6), f = isog_table[(l,j)]
    4322         d = (c6*a4)/(18*c4*a6) # twisting factor
    4323         R = PolynomialRing(E.base_field(),'X')
    4324         n = len(f)
    4325         ker = R([d**(n-i-1) * f[i] for i in range(n)])
    4326         isog = Ew.isogeny(kernel=ker, degree=l, model="minimal", check=False)
    4327         isog.set_pre_isomorphism(E_to_Ew)
    4328         return [isog]
    4329     if l is None:
    4330         if isog_table.has_key((11,j)):
    4331             return isogenies_sporadic_Q(E, Integer(11))
    4332         if isog_table.has_key((17,j)):
    4333             return isogenies_sporadic_Q(E, Integer(17))
    4334         if isog_table.has_key((19,j)):
    4335             return isogenies_sporadic_Q(E, Integer(19))
    4336         if isog_table.has_key((37,j)):
    4337             return isogenies_sporadic_Q(E, Integer(37))
    4338         if isog_table.has_key((43,j)):
    4339             return isogenies_sporadic_Q(E, Integer(43))
    4340         if isog_table.has_key((67,j)):
    4341             return isogenies_sporadic_Q(E, Integer(67))
    4342         if isog_table.has_key((163,j)):
    4343             return isogenies_sporadic_Q(E, Integer(163))
    4344         else:
    4345             return []
    4346 
    4347 def isogenies_2(E):
    4348     """
    4349     Returns a list of all 2-isogenies with domain ``E``.
    4350 
    4351     INPUT:
    4352 
    4353     - ``E`` -- an elliptic curve.
    4354 
    4355     OUTPUT:
    4356 
    4357     (list) 2-isogenies with domain ``E``.  In general these are
    4358     normalised, but over `\QQ` the codomain is a minimal model.
    4359 
    4360     EXAMPLES::
    4361 
    4362         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_2   
    4363         sage: E = EllipticCurve('14a1'); E
    4364         Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
    4365         sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
    4366         [(1, 0, 1, -36, -70)]
    4367 
    4368         sage: E = EllipticCurve([1,2,3,4,5]); E
    4369         Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
    4370         sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
    4371         []
    4372         sage: E = EllipticCurve(QQbar, [9,8]); E 
    4373         Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field
    4374         sage: isogenies_2(E) # not implemented
    4375     """
    4376     f2 = E.division_polynomial(2)
    4377     x2 = f2.roots(multiplicities=False)
    4378     x2.sort()
    4379     x = f2.parent().gen()
    4380     ff = [x-x2i for x2i in x2]
    4381     model = "minimal" if E.base_field() is QQ else None
    4382     isogs = [E.isogeny(f, model=model) for f in ff]
    4383     return isogs
    4384    
    4385 def isogenies_3(E):
    4386     """
    4387     Returns a list of all 3-isogenies with domain ``E``.
    4388 
    4389     INPUT:
    4390 
    4391     - ``E`` -- an elliptic curve.
    4392 
    4393     OUTPUT:
    4394 
    4395     (list) 3-isogenies with domain ``E``.  In general these are
    4396     normalised, but over `\QQ` the codomain is a minimal model.
    4397 
    4398     EXAMPLES::
    4399 
    4400         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_3
    4401         sage: E = EllipticCurve(GF(17), [1,1])
    4402         sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
    4403         [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)]
    4404 
    4405         sage: E = EllipticCurve(GF(17^2,'a'), [1,1])
    4406         sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
    4407         [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1), (0, 0, 0, 5*a + 1, a + 13), (0, 0, 0, 12*a + 6, 16*a + 14)]
    4408 
    4409         sage: E = EllipticCurve('19a1')   
    4410         sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
    4411         [(0, 1, 1, 1, 0), (0, 1, 1, -769, -8470)]
    4412 
    4413         sage: E = EllipticCurve([1,1])
    4414         sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
    4415         []
    4416     """
    4417     f3 = E.division_polynomial(3)
    4418     x3 = f3.roots(multiplicities=False)
    4419     x3.sort()
    4420     x = f3.parent().gen()
    4421     ff = [x-x3i for x3i in x3]
    4422     model = "minimal" if E.base_field() is QQ else None
    4423     isogs = [E.isogeny(f, model=model) for f in ff]
    4424     return isogs
    4425 
    4426 # 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728.
    4427 
    4428 def isogenies_5_0(E):
    4429     """
    4430     Returns a list of all the 5-isogenies  with domain ``E`` when the
    4431     j-invariant is 0.
    4432 
    4433     OUTPUT:
    4434 
    4435     (list) 5-isogenies with codomain E.  In general these are
    4436     normalised, but over `\QQ` the codomain is a minimal model.
    4437 
    4438     .. note::
    4439 
    4440        This implementation requires that the characteristic is not 2,
    4441        3 or 5.
    4442 
    4443     .. note::
    4444 
    4445        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
    4446 
    4447     EXAMPLES::
    4448 
    4449         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_5_0
    4450         sage: E = EllipticCurve([0,12])
    4451         sage: isogenies_5_0(E)                             
    4452         []
    4453 
    4454         sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
    4455         sage: isogenies_5_0(E)
    4456         [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12) over Finite Field in a of size 13^2]
    4457 
    4458         sage: K.<a> = NumberField(x**6-320*x**3-320)
    4459         sage: E = EllipticCurve(K,[0,0,1,0,0])
    4460         sage: isogenies_5_0(E)                     
    4461         [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 = x^3 + (a^5-400*a^2)*x + (280*a^3-3120) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320,
    4462         Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 = x^3 + (23/2*a^5-3700*a^2)*x + (-280*a^3+86480) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320]
    4463 
    4464     """
    4465     F = E.base_field()
    4466     if E.j_invariant() != 0:
    4467         raise ValueError, "j-invariant must be 0."
    4468     if F.characteristic() in [2,3,5]:
    4469         raise NotImplementedError, "Not implemented in characteristic 2, 3 or 5."
    4470     if not F(5).is_square():
    4471         return []
    4472     Ew = E.short_weierstrass_model()
    4473     a = Ew.a6()
    4474     x = polygen(F)
    4475     betas = (x**6-160*a*x**3-80*a**2).roots(multiplicities=False)
    4476     betas.sort()
    4477     if len(betas)==0:
    4478         return []
    4479     gammas = [(beta**2 *(beta**3-140*a))/(120*a) for beta in betas]
    4480     model = "minimal" if F is QQ else None
    4481     isogs = [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
    4482     iso = E.isomorphism_to(Ew)
    4483     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4484     return isogs
    4485 
    4486 def isogenies_5_1728(E):
    4487     """
    4488     Returns a list of 5-isogenies with domain ``E`` when the j-invariant is
    4489     1728.
    4490 
    4491     OUTPUT:
    4492 
    4493     (list) 5-isogenies with codomain E.  In general these are
    4494     normalised; but if `-1` is a square then there are two
    4495     endomorphisms of degree `5`, for which the codomain is the same as
    4496     the domain curve; and over `\QQ`, the codomain is a minimal model.
    4497 
    4498     .. note::
    4499 
    4500        This implementation requires that the characteristic is not 2,
    4501        3 or 5.
    4502 
    4503     .. note::
    4504 
    4505        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
    4506 
    4507     EXAMPLES::
    4508        
    4509         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_5_1728
    4510         sage: E = EllipticCurve([7,0])   
    4511         sage: isogenies_5_1728(E)
    4512         []
    4513 
    4514         sage: E = EllipticCurve(GF(13),[11,0])
    4515         sage: isogenies_5_1728(E)       
    4516         [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13,
    4517         Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13]
    4518 
    4519     An example of endomorphisms of degree 5::
    4520 
    4521         sage: K.<i> = QuadraticField(-1)                   
    4522         sage: E = EllipticCurve(K,[0,0,0,1,0])
    4523         sage: isogenies_5_1728(E)             
    4524         [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1,
    4525         Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1]
    4526         sage: _[0].rational_maps()
    4527         (((4/25*i + 3/25)*x^5 + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)),
    4528          ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + (141/125*i + 162/125)*x^2*y + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125)))
    4529 
    4530     An example of 5-isogenies over a number field::
    4531 
    4532         sage: K.<a> = NumberField(x**4+20*x**2-80)
    4533         sage: K(5).is_square() #necessary but not sufficient!                   
    4534         True
    4535         sage: E = EllipticCurve(K,[0,0,0,1,0])   
    4536         sage: isogenies_5_1728(E)                 
    4537         [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-20*a^2-39)*x + (35*a^3+112*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80,
    4538         Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-20*a^2-39)*x + (-35*a^3-112*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80]
    4539    
    4540     """
    4541     F = E.base_field()
    4542     if E.j_invariant() != 1728:
    4543         raise ValueError, "j-invariant must be 1728."
    4544     if F.characteristic() in [2,3,5]:
    4545         raise NotImplementedError, "Not implemented in characteristic 2, 3 or 5."
    4546     model = "minimal" if F is QQ else None
    4547     # quick test for a negative answer (from Fricke module)
    4548     square5 = F(5).is_square()
    4549     square1 = F(-1).is_square()
    4550     if not square5 and not square1:
    4551         return []
    4552     Ew = E.short_weierstrass_model()
    4553     iso = E.isomorphism_to(Ew)
    4554     a = Ew.a4()
    4555     x = polygen(F)
    4556     isogs = []
    4557     # 2 cases
    4558     # Type 1: if -1 is a square we have 2 endomorphisms
    4559     if square1:
    4560         i = F(-1).sqrt()
    4561         isogs = [Ew.isogeny(f) for f in [x**2+a/(1+2*i), x**2+a/(1-2*i)]]
    4562         [isog.set_post_isomorphism(isog.codomain().isomorphism_to(E)) for isog in isogs]
    4563     # Type 2: if 5 is a square we have up to 4 (non-endomorphism) isogenies
    4564     if square5:
    4565         betas = (x**4+20*a*x**2-80*a**2).roots(multiplicities=False)
    4566         betas.sort()
    4567         gammas = [a*(beta**2-2)/6 for beta in betas]
    4568         isogs += [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
    4569     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4570     return isogs
    4571 
    4572 def isogenies_7_0(E):
    4573     """
    4574     Returns list of all 7-isogenies from E when the j-invariant is 0.
    4575 
    4576     OUTPUT:
    4577 
    4578     (list) 7-isogenies with codomain E.  In general these are
    4579     normalised; but if `-3` is a square then there are two
    4580     endomorphisms of degree `7`, for which the codomain is the same as
    4581     the domain; and over `\QQ`, the codomain is a minimal model.
    4582 
    4583     .. note::
    4584 
    4585        This implementation requires that the characteristic is not 2,
    4586        3 or 7.
    4587 
    4588     .. note::
    4589 
    4590        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
    4591 
    4592     EXAMPLES:
    4593 
    4594     First some examples of endomorphisms::
    4595 
    4596         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_7_0   
    4597         sage: K.<r> = QuadraticField(-3)
    4598         sage: E = EllipticCurve(K, [0,1]) 
    4599         sage: isogenies_7_0(E)
    4600         [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3,
    4601         Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3]
    4602 
    4603         sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
    4604         sage: isogenies_7_0(E)       
    4605         [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2]
    4606 
    4607     Now some examples of 7-isogenies which are not endomorphisms::
    4608 
    4609         sage: K = GF(101)               
    4610         sage: E = EllipticCurve(K, [0,1])
    4611         sage: isogenies_7_0(E)           
    4612         [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101]
    4613 
    4614     Examples over a number field::
    4615 
    4616         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_7_0
    4617         sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r'))
    4618         sage: isogenies_7_0(E)
    4619         [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3,
    4620         Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3]
    4621 
    4622         sage: K.<a> = NumberField(x^6 + 1512*x^3 - 21168)
    4623         sage: E = EllipticCurve(K, [0,1])
    4624         sage: isogs = isogenies_7_0(E)
    4625         sage: [phi.codomain().a_invariants() for phi in isogs]
    4626         [(0, 0, 0, -5/294*a^5 - 300/7*a^2, -55/2*a^3 - 1133),
    4627         (0, 0, 0, -295/1176*a^5 - 5385/14*a^2, 55/2*a^3 + 40447)]
    4628         sage: [phi.codomain().j_invariant() for phi in isogs]
    4629         [158428486656000/7*a^3 - 313976217600000,
    4630         -158428486656000/7*a^3 - 34534529335296000]
    4631     """
    4632     if E.j_invariant()!=0:
    4633         raise ValueError, "j-invariant must be 0."
    4634     F = E.base_field()
    4635     if F.characteristic() in [2,3,7]:
    4636         raise NotImplementedError, "Not implemented when the characteristic of the base field is 2, 3 or 7."
    4637     x = polygen(F)
    4638     Ew = E.short_weierstrass_model()
    4639     iso = E.isomorphism_to(Ew)
    4640     a = Ew.a6()
    4641     model = "minimal" if F is QQ else None
    4642 
    4643     # there will be 2 endomorphisms if -3 is a square:
    4644 
    4645     ts = (x**2+3).roots(multiplicities=False)
    4646     ts.sort()
    4647     kers = [7*x-(2+6*t) for t in ts]
    4648     kers = [k(x**3/a).monic() for k in kers]
    4649     isogs = [Ew.isogeny(k,model=model) for k in kers]
    4650     if len(isogs)>0:
    4651         [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
    4652 
    4653     # we may have up to 6 other isogenies:
    4654     ts = (x**2-21).roots(multiplicities=False)
    4655     for t0 in ts:
    4656         s3 = a/(28+6*t0)
    4657         ss = (x**3-s3).roots(multiplicities=False)
    4658         ss.sort()
    4659         ker = x**3 - 2*t0*x**2 - 4*t0*x + 4*t0 + 28
    4660         kers = [ker(x/s).monic() for s in ss]
    4661         isogs += [Ew.isogeny(k, model=model) for k in kers]
    4662    
    4663     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4664     return isogs
    4665 
    4666 def isogenies_7_1728(E):
    4667     """
    4668     Returns list of all 7-isogenies from E when the j-invariant is 1728.
    4669 
    4670     OUTPUT:
    4671 
    4672     (list) 7-isogenies with codomain E.  In general these are
    4673     normalised; but over `\QQ` the codomain is a minimal model.
    4674 
    4675     .. note::
    4676 
    4677        This implementation requires that the characteristic is not 2,
    4678        3, or 7.
    4679 
    4680     .. note::
    4681 
    4682        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
    4683 
    4684     EXAMPLES::
    4685 
    4686         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_7_1728                                                                           
    4687         sage: E = EllipticCurve(GF(47), [1, 0])
    4688         sage: isogenies_7_1728(E)             
    4689         [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47,
    4690         Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47]
    4691 
    4692     An example in characteristic 53 (for which an earlier implementation did not work)::   
    4693 
    4694         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_7_1728
    4695         sage: E = EllipticCurve(GF(53), [1, 0])
    4696         sage: isogenies_7_1728(E)
    4697         []
    4698         sage: E = EllipticCurve(GF(53^2,'a'), [1, 0])
    4699         sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)]
    4700         [(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28), (0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37), (0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)]
    4701 
    4702     ::   
    4703 
    4704         sage: K.<a> = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567)
    4705         sage: E = EllipticCurve(K, [1, 0])                               
    4706         sage: isogs = isogenies_7_1728(E)
    4707         sage: [phi.codomain().a_invariants() for phi in isogs]
    4708         [(0,
    4709         0,
    4710         0,
    4711         35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
    4712         155/636*a^7 + 245/12*a^5 - 313355/636*a^3 - 3577/636*a),
    4713         (0,
    4714         0,
    4715         0,
    4716         35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
    4717         -155/636*a^7 - 245/12*a^5 + 313355/636*a^3 + 3577/636*a)]
    4718         sage: [phi.codomain().j_invariant() for phi in isogs]
    4719         [-526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53,
    4720         -526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53]
    4721         sage: E1 = isogs[0].codomain()
    4722         sage: E2 = isogs[1].codomain()
    4723         sage: E1.is_isomorphic(E2)
    4724         False
    4725         sage: E1.is_quadratic_twist(E2)
    4726         -1
    4727     """
    4728     if E.j_invariant()!=1728:
    4729         raise ValueError, "j_invariant must be 1728 (in base field)."
    4730     F = E.base_field()
    4731     if F.characteristic() in [2,3,7]:
    4732         raise NotImplementedError, "Not implemented when the characteristic of the base field is 2, 3 or 7."
    4733     Ew = E.short_weierstrass_model()
    4734     iso = E.isomorphism_to(Ew)
    4735     a = Ew.a4()
    4736 
    4737     ts = (Fricke_module(7)-1728).numerator().roots(F,multiplicities=False)
    4738     if len(ts)==0:
    4739         return []
    4740     ts.sort()
    4741     isogs = []
    4742     model = "minimal" if F is QQ else None
    4743     x = polygen(F)
    4744     for t0 in ts:
    4745         s2 = a/t0
    4746         ss = (x**2-s2).roots(multiplicities=False)
    4747         ss.sort()
    4748         ker = 9*x**3 + (-3*t0**3 - 36*t0**2 - 123*t0)*x**2 + (-8*t0**3 - 101*t0**2 - 346*t0 + 35)*x - 7*t0**3 - 88*t0**2 - 296*t0 + 28
    4749 
    4750         kers = [ker(x/s) for s in ss]
    4751         isogs += [Ew.isogeny(k.monic(), model=model) for k in kers]
    4752     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4753     return isogs
    4754 
    4755 def isogenies_13_0(E):
    4756     """
    4757     Returns list of all 13-isogenies from E when the j-invariant is 0.
    4758 
    4759     OUTPUT:
    4760 
    4761     (list) 13-isogenies with codomain E.  In general these are
    4762     normalised; but if `-3` is a square then there are two
    4763     endomorphisms of degree `13`, for which the codomain is the same
    4764     as the domain.
    4765 
    4766     .. note::
    4767 
    4768        This implementation requires that the characteristic is not 2,
    4769        3 or 13.
    4770 
    4771     .. note::
    4772 
    4773        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
    4774 
    4775     EXAMPLES::
    4776 
    4777         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_13_0 
    4778 
    4779     Endomorphisms of degree 13 will exist when -3 is a square::   
    4780 
    4781         sage: K.<r> = QuadraticField(-3)
    4782         sage: E = EllipticCurve(K, [0, r]); E
    4783         Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3
    4784         sage: isogenies_13_0(E)
    4785         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3,
    4786         Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3]
    4787         sage: isogenies_13_0(E)[0].rational_maps()
    4788         (((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10 + (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4 + (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6 + (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)), ((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y + (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y + (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y + (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15 + (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9 + (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3 + (1990656/2197*r + 3870720/2197)))
    4789 
    4790     An example of endomorphisms over a finite field::
    4791    
    4792         sage: K = GF(19^2,'a')
    4793         sage: E = EllipticCurve(j=K(0)); E
    4794         Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
    4795         sage: isogenies_13_0(E)                   
    4796         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2,
    4797         Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2]
    4798         sage: isogenies_13_0(E)[0].rational_maps()
    4799         ((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5), (-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y + 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7))
    4800 
    4801     A previous implementation did not work in some characteristics::   
    4802 
    4803         sage: K = GF(29)
    4804         sage: E = EllipticCurve(j=K(0))
    4805         sage: isogenies_13_0(E)
    4806         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29]
    4807 
    4808     ::
    4809 
    4810         sage: K = GF(101)                                         
    4811         sage: E = EllipticCurve(j=K(0)); E.ainvs()                 
    4812         (0, 0, 0, 0, 1)
    4813         sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
    4814         [(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)]
    4815 
    4816     ::
    4817 
    4818         sage: x = polygen(QQ)
    4819         sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968
    4820         sage: K.<a> = NumberField(f)     
    4821         sage: E = EllipticCurve(j=K(0)); E.ainvs()
    4822         (0, 0, 0, 0, 1)
    4823         sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
    4824         [(0, 0, 0, -739946459/23857162861049856*a^11 - 2591641747/1062017577504*a^8 + 16583647773233/4248070310016*a^5 - 14310911337/378211388*a^2, 26146225/4248070310016*a^9 + 7327668845/14750244132*a^6 + 174618431365/756422776*a^3 - 378332499709/94552847), (0, 0, 0, 3501275/5964290715262464*a^11 + 24721025/531008788752*a^8 - 47974903745/1062017577504*a^5 - 6773483100/94552847*a^2, 6699581/4248070310016*a^9 + 1826193509/14750244132*a^6 - 182763866047/756422776*a^3 - 321460597/94552847)]
    4825     """
    4826     if E.j_invariant()!=0:
    4827         raise ValueError, "j-invariant must be 0."
    4828     F = E.base_field()
    4829     if F.characteristic() in [2,3,13]:
    4830         raise NotImplementedError, "Not implemented when the characteristic of the base field is 2, 3 or 13."
    4831     Ew = E.short_weierstrass_model()
    4832     iso = E.isomorphism_to(Ew)
    4833     a = Ew.a6()
    4834     model = "minimal" if F is QQ else None
    4835     x = polygen(F)
    4836 
    4837     # there will be 2 endomorphisms if -3 is a square:
    4838     ts = (x**2+3).roots(multiplicities=False)
    4839     ts.sort()
    4840     kers = [13*x**2 + (78*t + 26)*x + 24*t + 40 for t in ts]
    4841     kers = [k(x**3/a).monic() for k in kers]
    4842     isogs = [Ew.isogeny(k,model=model) for k in kers]
    4843     if len(isogs)>0:
    4844         [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
    4845  
    4846     # we may have up to 12 other isogenies:
    4847     ts = (x**4 + 7*x**3 + 20*x**2 + 19*x + 1).roots(multiplicities=False)
    4848     ts.sort()
    4849     for t0 in ts:
    4850         s3 = a / (6*t0**3 + 32*t0**2 + 68*t0 + 4)
    4851         ss = (x**3-s3).roots(multiplicities=False)
    4852         ss.sort()
    4853         ker = (x**6 + (20*t0**3 + 106*t0**2 + 218*t0 + 4)*x**5
    4854             + (-826*t0**3 - 4424*t0**2 - 9244*t0 - 494)*x**4
    4855             + (13514*t0**3 + 72416*t0**2 + 151416*t0 + 8238)*x**3
    4856             + (-101948*t0**3 - 546304*t0**2 - 1142288*t0 - 62116)*x**2
    4857             + (354472*t0**3 + 1899488*t0**2 + 3971680*t0 + 215960)*x
    4858             - 459424*t0**3 - 2461888*t0**2 - 5147648*t0 - 279904)
    4859         kers = [ker(x/s).monic() for s in ss]
    4860         isogs += [Ew.isogeny(k, model=model) for k in kers]
    4861    
    4862     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4863 
    4864     return isogs
    4865 
    4866 def isogenies_13_1728(E):
    4867     """
    4868     Returns list of all 13-isogenies from E when the j-invariant is 1728.
    4869 
    4870     OUTPUT:
    4871 
    4872     (list) 13-isogenies with codomain E.  In general these are
    4873     normalised; but if `-1` is a square then there are two
    4874     endomorphisms of degree `13`, for which the codomain is the same
    4875     as the domain; and over `\QQ`, the codomain is a minimal model.
    4876 
    4877     .. note::
    4878 
    4879        This implementation requires that the characteristic is not
    4880        2, 3 or 13.
    4881 
    4882     .. note::
    4883 
    4884        This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
    4885 
    4886     EXAMPLES::
    4887 
    4888         sage: from sage.schemes.elliptic_curves.ell_curve_isogeny import isogenies_13_1728
    4889 
    4890         sage: K.<i> = QuadraticField(-1)
    4891         sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs()
    4892         (0, 0, 0, i, 0)
    4893         sage: isogenies_13_1728(E)
    4894         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1,
    4895         Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1]
    4896 
    4897     ::
    4898 
    4899         sage: K = GF(83)
    4900         sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
    4901         (0, 0, 0, 5, 0)
    4902         sage: isogenies_13_1728(E)                       
    4903         []
    4904         sage: K = GF(89)                                 
    4905         sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
    4906         (0, 0, 0, 5, 0)
    4907         sage: isogenies_13_1728(E)                       
    4908         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89,
    4909         Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89]
    4910 
    4911     ::
    4912 
    4913         sage: K = GF(23)                                     
    4914         sage: E = EllipticCurve(K, [1,0])                     
    4915         sage: isogenies_13_1728(E)                           
    4916         [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23]
    4917 
    4918     ::
    4919 
    4920         sage: x = polygen(QQ)
    4921         sage: f = x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6 - 282896640*x^4 - 149879808*x^2 - 349360128
    4922         sage: K.<a> = NumberField(f)
    4923         sage: E = EllipticCurve(K, [1,0])
    4924         sage: [phi.codomain().ainvs() for phi in isogenies_13_1728(E)]
    4925         [(0,
    4926         0,
    4927         0,
    4928         11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
    4929         214217013065/82065216155553792*a^11 + 1217882637605/427423000810176*a^9 - 214645003230565/189965778137856*a^7 + 22973355421236025/1282269002430528*a^5 - 2059145797340695/2544184528632*a^3 - 23198483147321/989405094468*a),
    4930         (0,
    4931         0,
    4932         0,
    4933         11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
    4934         -214217013065/82065216155553792*a^11 - 1217882637605/427423000810176*a^9 + 214645003230565/189965778137856*a^7 - 22973355421236025/1282269002430528*a^5 + 2059145797340695/2544184528632*a^3 + 23198483147321/989405094468*a)]
    4935    
    4936     """
    4937     if E.j_invariant()!=1728:
    4938         raise ValueError, "j-invariant must be 1728."
    4939     F = E.base_field()
    4940     if F.characteristic() in [2, 3, 7, 13, 167, 233, 271, 1117]:
    4941         raise NotImplementedError, "Not implemented when the characteristic of the base field is 2, 3 or 13."
    4942     Ew = E.short_weierstrass_model()
    4943     iso = E.isomorphism_to(Ew)
    4944     a = Ew.a4()
    4945     model = "minimal" if F is QQ else None
    4946     x = polygen(F)
    4947 
    4948     # we will have two endomorphisms if -1 is a square:
    4949     ts = (x**2+1).roots(multiplicities=False)
    4950     ts.sort()
    4951     kers = [13*x**3 + (-26*i - 13)*x**2 + (-52*i - 13)*x - 2*i - 3 for i in ts]
    4952     kers = [k(x**2/a).monic() for k in kers]
    4953     isogs = [Ew.isogeny(k,model=model) for k in kers]
    4954     if len(isogs)>0:
    4955         [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
    4956 
    4957     # we may have up to 12 other isogenies:
    4958 
    4959     ts = (x**6 + 10*x**5 + 46*x**4 + 108*x**3 + 122*x**2 + 38*x - 1).roots(multiplicities=False)
    4960     ts.sort()
    4961     for t0 in ts:
    4962         s2 = a/(66*t0**5 + 630*t0**4 + 2750*t0**3 + 5882*t0**2 + 5414*t0 + 162)
    4963         ss = (x**2-s2).roots(multiplicities=False)
    4964         ss.sort()
    4965         ker = (x**6 + (-66*t0**5 - 630*t0**4 - 2750*t0**3 - 5882*t0**2
    4966               - 5414*t0 - 162)*x**5 + (-21722*t0**5 - 205718*t0**4 -
    4967               890146*t0**3 - 1873338*t0**2 - 1652478*t0 + 61610)*x**4
    4968               + (-3391376*t0**5 - 32162416*t0**4 - 139397232*t0**3 -
    4969               294310576*t0**2 - 261885968*t0 + 6105552)*x**3 +
    4970               (-241695080*t0**5 - 2291695976*t0**4 - 9930313256*t0**3
    4971               - 20956609720*t0**2 - 18625380856*t0 + 469971320)*x**2 +
    4972               (-8085170432*t0**5 - 76663232384*t0**4 -
    4973               332202985024*t0**3 - 701103233152*t0**2 -
    4974               623190845440*t0 + 15598973056)*x - 101980510208*t0**5 -
    4975               966973468160*t0**4 - 4190156868352*t0**3 -
    4976               8843158270336*t0**2 - 7860368751232*t0 + 196854655936)
    4977        
    4978         kers = [ker(x/s).monic() for s in ss]
    4979         isogs += [Ew.isogeny(k, model=model) for k in kers]
    4980 
    4981     [isog.set_pre_isomorphism(iso) for isog in isogs]
    4982    
    4983     return isogs
    4984 
    49853888# Utility function for manipulating isogeny degree matrices
    49863889
    49873890def fill_isogeny_matrix(M):
  • sage/schemes/elliptic_curves/ell_field.py

    diff --git a/sage/schemes/elliptic_curves/ell_field.py b/sage/schemes/elliptic_curves/ell_field.py
    a b  
    835835        """
    836836        return isogeny_codomain_from_kernel(self, kernel, degree=None)
    837837
    838     def isogenies_prime_degree(self, l=None):
     838    def isogenies_prime_degree(self, l=None, max_l=31):
    839839        """
    840         Generic code, valid for all fields, for those l for which the
    841         modular curve has genus 0.
     840        Generic code, valid for all fields, for arbitrary prime `l` not equal to the characteristic.
    842841
    843842        INPUT:
    844843
    845         - ``l`` -- either None, a prime or a list of primes, from [2,3,5,7,13].
     844        - ``l`` -- either None, a prime or a list of primes.
     845        - ``max_l`` -- a bound on the primes to be tested (ignored unless `l` is None).
    846846
    847847        OUTPUT:
    848848
     
    851851        METHOD:
    852852
    853853        Calls the generic function
    854         ``isogenies_prime_degree_genus_0()``.  This requires that
     854        ``isogenies_prime_degree()``.  This requires that
    855855        certain operations have been implemented over the base field,
    856856        such as root-finding for univariate polynomials.
    857857
     
    860860            sage: F = QQbar                     
    861861            sage: E = EllipticCurve(F, [1,18]); E
    862862            Elliptic Curve defined by y^2 = x^3 + x + 18 over Algebraic Field
    863            
     863            sage: E.isogenies_prime_degree()
     864            Traceback (most recent call last):
     865            ...
     866            NotImplementedError: This code could be implemented for QQbar, but has not been yet.
     867
    864868            sage: F = CC
    865869            sage: E = EllipticCurve(F, [1,18]); E
    866870            Elliptic Curve defined by y^2 = x^3 + 1.00000000000000*x + 18.0000000000000 over Complex Field with 53 bits of precision
     
    873877
    874878            sage: E = EllipticCurve(GF(next_prime(1000000)), [7,8])
    875879            sage: E.isogenies_prime_degree()
    876             [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]
     880            [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]
    877881            sage: E.isogenies_prime_degree(2)           
    878882            [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]           
    879883            sage: E.isogenies_prime_degree(3)
     
    892896            Traceback (most recent call last):
    893897            ...
    894898            ValueError: 4 is not prime.
    895             sage: E.isogenies_prime_degree([2, 29])
    896             Traceback (most recent call last):
    897             ...
    898             NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
    899899            sage: E.isogenies_prime_degree(4)
    900900            Traceback (most recent call last):
    901901            ...
    902902            ValueError: 4 is not prime.
    903903            sage: E.isogenies_prime_degree(11)
    904             Traceback (most recent call last):
    905             ...
    906             NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
    907            
     904            []
    908905            sage: E = EllipticCurve(GF(17),[2,0])                     
    909906            sage: E.isogenies_prime_degree(3)
    910907            []
     
    917914
    918915            sage: E.isogenies_prime_degree(3)
    919916            [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]
    920             sage: E.isogenies_prime_degree([2, 3, 5, 7, 13])
    921             Traceback (most recent call last):
    922             ...
    923             NotImplementedError: 2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.
    924             sage: E.isogenies_prime_degree([2, 3, 5, 7])               
    925             [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, 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, Isogeny of degree 7 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 + 3*x + 11 over Finite Field in a of size 13^4, Isogeny of degree 7 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 + 2 over Finite Field in a of size 13^4]
     917
     918        Example to show that separable isogenies of degree equal to the characteristic are now implemented::
     919
     920            sage: E.isogenies_prime_degree(13)
     921            [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]
    926922
    927923        Examples over number fields (other than QQ)::
    928924
    929925            sage: QQroot2.<e> = NumberField(x^2-2)
    930             sage: E = EllipticCurve(QQroot2,[1,1])
    931             sage: E.isogenies_prime_degree(11)
    932             Traceback (most recent call last):
    933             ...
    934             NotImplementedError: Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented.
    935             sage: E.isogenies_prime_degree(5)
    936             []
     926            sage: E = EllipticCurve(QQroot2, j=8000)
     927            sage: E.isogenies_prime_degree()
     928            [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 + (-602112000)*x + 5035261952000 over Number Field in e with defining polynomial x^2 - 2,
     929            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 + (903168000*e-1053696000)*x + (14161674240000*e-23288086528000) over Number Field in e with defining polynomial x^2 - 2,
     930            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 + (-903168000*e-1053696000)*x + (-14161674240000*e-23288086528000) over Number Field in e with defining polynomial x^2 - 2]
    937931
    938932            sage: E = EllipticCurve(QQroot2, [1,0,1,4, -6]); E
    939933            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
     
    950944        if F == rings.QQbar:
    951945            raise NotImplementedError, "This code could be implemented for QQbar, but has not been yet."
    952946
    953         from ell_curve_isogeny import isogenies_prime_degree_genus_0
     947        from isogeny_small_degree import isogenies_prime_degree
    954948        if l is None:
    955             l = [2, 3, 5, 7, 13]
    956         if l in [2, 3, 5, 7, 13]:
    957             return isogenies_prime_degree_genus_0(self, l)
     949            from sage.rings.all import prime_range
     950            l = prime_range(max_l+1)
     951
    958952        if type(l) != list:
     953            try:
     954                l = rings.ZZ(l)
     955            except TypeError:
     956                raise ValueError, "%s is not prime."%l
    959957            if l.is_prime():
    960                 raise NotImplementedError, "Over general fields, only isogenies of degree 2, 3, 5, 7 or 13 have been implemented."
     958                return isogenies_prime_degree(self, l)
    961959            else:
    962960                raise ValueError, "%s is not prime."%l
    963         isogs = []
    964         i = 0
    965         while i<len(l):
    966             isogenies = [f for f in self.isogenies_prime_degree(l[i]) if not f in isogs]
    967             isogs.extend(isogenies)
    968             i = i+1
    969         return isogs
     961
     962        L = list(set(l))
     963        try:
     964            L = [rings.ZZ(l) for l in L]
     965        except TypeError:
     966            raise ValueError, "%s is not a list of primes."%l
     967
     968        L.sort()
     969        return sum([isogenies_prime_degree(self,l) for l in L],[])
    970970
    971971    def is_isogenous(self, other, field=None):
    972972        """
  • sage/schemes/elliptic_curves/ell_rational_field.py

    diff --git a/sage/schemes/elliptic_curves/ell_rational_field.py b/sage/schemes/elliptic_curves/ell_rational_field.py
    a b  
    41944194            ValueError: 4 is not prime.
    41954195
    41964196        """
    4197         from ell_curve_isogeny import isogenies_prime_degree_genus_0, isogenies_sporadic_Q
     4197        from isogeny_small_degree import isogenies_prime_degree_genus_0, isogenies_sporadic_Q
    41984198       
    41994199        if l in [2, 3, 5, 7, 13]:
    42004200            return isogenies_prime_degree_genus_0(self, l)
  • new file sage/schemes/elliptic_curves/isogeny_small_degree.py

    diff --git a/sage/schemes/elliptic_curves/isogeny_small_degree.py b/sage/schemes/elliptic_curves/isogeny_small_degree.py
    new file mode 100644
    - +  
     1r"""
     2Isogenies of small prime degree.
     3
     4Functions for the computation of isogenies of small primes
     5degree. First: `l` = 2, 3, 5, 7, or 13, where the modular curve
     6`X_0(l)` has genus 0.  Second: `l` = 11, 17, 19, 23, 29, 31, 41, 47,
     759, or 71, where `X_0^+(l)` has genus 0 and `X_0(l)` is elliptic or
     8hyperelliptic.  Also: `l` = 11, 17, 19, 37, 43, 67 or 163 over `\QQ`
     9(the sporadic cases with only finitely many `j`-invariants each).  All
     10the above only require factorization of a polynomial of degree `l+1`.
     11Finally, a generic function which works for arbitrary odd primes `l`
     12(including the characteristic), but requires factorization of the
     13`l`-division polynomial, of degree `(l^2-1)/2`.
     14
     15
     16AUTHORS:
     17
     18- John Cremona and Jenny Cooley: 2009-07..11: the genus 0 cases the sporadic cases over `\QQ`.
     19
     20- Kimi Tsukazaki and John Cremona: 2013-07: The 10 (hyper)-elliptic
     21  cases and the generic algorithm.  See [KT2013]_.
     22
     23REFERENCES:
     24
     25.. [CW2005] J. E. Cremona and M. Watkins. Computing isogenies of elliptic curves. preprint, 2005.
     26.. [KT2013] K. Tsukazaki, Explicit Isogenies of Elliptic Curves,
     27   PhD thesis, University of Warwick, 2013.
     28
     29
     30"""
     31
     32#*****************************************************************************
     33#       Copyright (C) 2012-2013 John Cremona, Jenny Cooley, Kimi Tsukazaki
     34#
     35#  Distributed under the terms of the GNU General Public License (GPL)
     36#  as published by the Free Software Foundation; either version 2 of
     37#  the License, or (at your option) any later version.
     38#                  http://www.gnu.org/licenses/
     39#*****************************************************************************
     40
     41from sage.categories import homset
     42
     43from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
     44from sage.rings.polynomial.polynomial_ring import polygen
     45from sage.rings.all import Integer, ZZ, QQ
     46from sage.schemes.elliptic_curves.all import EllipticCurve
     47
     48from sage.misc.cachefunc import cached_function
     49
     50##########################################################################
     51# The following section is all about computing l-isogenies, where l is
     52# a prime.  The genus 0 cases `l` = 2, 3, 5, 7 and 13 are
     53# implemented over any field of characteristic not 2, 3 or `l`; over
     54# `\QQ` the "sporadic" cases `l` = 11, 17, 19, 37, 43, 67 or 163 with
     55# only finitely many `j`-invariants each. are also implemented.
     56##########################################################################
     57
     58@cached_function
     59def Fricke_polynomial(l):
     60    r"""
     61    Fricke polynomial for ``l`` =2,3,5,7,13.
     62
     63    For these primes (and these only) the modular curve `X_0(l)` has
     64    genus zero, and its field is generated by a single modular
     65    function called the Fricke module (or Hauptmodul), `t`.  There is
     66    a classical choice of such a generator `t` in each case, and the
     67    `j`-function is a rational function of `t` of degree `l+1` of the
     68    form `P(t)/t` where `P` is a polynomial of degree `l+1`.  Up to
     69    scaling, `t` is determined by the condition that the ramification
     70    points above `j=\infty` are `t=0` (with ramification degree `1`)
     71    and `t=\infty` (with degree `l`).  The ramification above `j=0`
     72    and `j=1728` may be seen in the factorizations of `j(t)` and
     73    `k(t)` where `k=j-1728`.
     74
     75    OUTPUT:
     76
     77    The polynomial `P(t)` as an element of `\ZZ[t]`.
     78
     79    TESTS::
     80
     81        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_polynomial
     82        sage: Fricke_polynomial(2)
     83        t^3 + 48*t^2 + 768*t + 4096
     84        sage: Fricke_polynomial(3)
     85        t^4 + 36*t^3 + 270*t^2 + 756*t + 729
     86        sage: Fricke_polynomial(5)
     87        t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125
     88        sage: Fricke_polynomial(7)
     89        t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49
     90        sage: Fricke_polynomial(13)
     91        t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13
     92    """
     93    Zt = PolynomialRing(ZZ,'t')
     94    t = Zt.gen()
     95    if l==2: return (t+16)**3
     96    elif l==3: return (t+3)**3*(t+27)
     97    elif l==5: return (t**2+10*t+5)**3
     98    elif l==7: return (t**2+5*t+1)**3 * (t**2+13*t+49)
     99    elif l==13: return (t**2+5*t+13)*(t**4+7*t**3+20*t**2+19*t+1)**3
     100    else:
     101        raise ValueError("The only genus zero primes are 2, 3, 5, 7 or 13.")
     102
     103@cached_function
     104def Fricke_module(l):
     105    r"""
     106    Fricke module for ``l`` =2,3,5,7,13.
     107
     108    For these primes (and these only) the modular curve `X_0(l)` has
     109    genus zero, and its field is generated by a single modular
     110    function called the Fricke module (or Hauptmodul), `t`.  There is
     111    a classical choice of such a generator `t` in each case, and the
     112    `j`-function is a rational function of `t` of degree `l+1` of the
     113    form `P(t)/t` where `P` is a polynomial of degree `l+1`.  Up to
     114    scaling, `t` is determined by the condition that the ramification
     115    points above `j=\infty` are `t=0` (with ramification degree `1`)
     116    and `t=\infty` (with degree `l`).  The ramification above `j=0`
     117    and `j=1728` may be seen in the factorizations of `j(t)` and
     118    `k(t)` where `k=j-1728`.
     119
     120    OUTPUT:
     121
     122    The rational function `P(t)/t`.
     123
     124    TESTS::
     125
     126        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module
     127        sage: Fricke_module(2)
     128        (t^3 + 48*t^2 + 768*t + 4096)/t
     129        sage: Fricke_module(3)
     130        (t^4 + 36*t^3 + 270*t^2 + 756*t + 729)/t
     131        sage: Fricke_module(5)
     132        (t^6 + 30*t^5 + 315*t^4 + 1300*t^3 + 1575*t^2 + 750*t + 125)/t
     133        sage: Fricke_module(7)
     134        (t^8 + 28*t^7 + 322*t^6 + 1904*t^5 + 5915*t^4 + 8624*t^3 + 4018*t^2 + 748*t + 49)/t
     135        sage: Fricke_module(13)
     136        (t^14 + 26*t^13 + 325*t^12 + 2548*t^11 + 13832*t^10 + 54340*t^9 + 157118*t^8 + 333580*t^7 + 509366*t^6 + 534820*t^5 + 354536*t^4 + 124852*t^3 + 15145*t^2 + 746*t + 13)/t
     137    """
     138    try:
     139        t = PolynomialRing(QQ,'t').gen()
     140        return Fricke_polynomial(l) / t
     141    except ValueError:
     142        raise ValueError("The only genus zero primes are 2, 3, 5, 7 or 13.")
     143
     144@cached_function
     145def Psi(l, use_stored=True):
     146    r"""
     147    Generic kernel polynomial for genus zero primes.
     148
     149    For each of the primes `l` for which `X_0(l)` has genus zero
     150    (namely `l=2,3,5,7,13`), we may define an elliptic curve `E_t`
     151    over `\QQ(t)`, with coefficients in `\ZZ[t]`, which has good
     152    reduction except at `t=0` and `t=\infty` (which lie above
     153    `j=\infty`) and at certain other values of `t` above `j=0` when
     154    `l=3` (one value) or `l\equiv1\pmod{3}` (two values) and above
     155    `j=1728` when `l=2` (one value) or `l\equiv1 \pmod{4}` (two
     156    values).  (These exceptional values correspond to endomorphisms of
     157    `E_t` of degree `l`.)  The `l`-division polynomial of `E_t` has a
     158    unique factor of degree `(l-1)/2` (or 1 when `l=2`), with
     159    coefficients in `\ZZ[t]`, which we call the Generic Kernel
     160    Polynomial for `l`.  These are used, by specialising `t`, in the
     161    function :meth:`isogenies_prime_degree_genus_0`, which also has to
     162    take into account the twisting factor between `E_t` for a specific
     163    value of `t` and the short Weierstrass form of an elliptic curve
     164    with `j`-invariant `j(t)`.  This enables the computation of the
     165    kernel polynomials of isogenies without having to compute and
     166    factor division polynomials.
     167
     168    All of this data is quickly computed from the Fricke modules, except
     169    that for `l=13` the factorization of the Generic Division Polynomial
     170    takes a long time, so the value have been precomputed and cached; by
     171    default the cached values are used, but the code here will recompute
     172    them when ``use_stored`` is ``False``, as in the doctests.
     173
     174    INPUT:
     175
     176    - ``l`` -- either 2, 3, 5, 7, or 13.
     177
     178    - ``use_stored`` (boolean, default True) -- If True, use
     179      precomputed values, otherwise compute them on the fly.
     180
     181    .. note:: 
     182   
     183       This computation takes a negligible time for `l=2,3,5,7`
     184       but more than 100s for `l=13`.  The reason
     185       for allowing dynamic computation here instead of just using
     186       precomputed values is for testing.
     187
     188    TESTS::
     189
     190        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Fricke_module, Psi
     191        sage: assert Psi(2, use_stored=True) == Psi(2, use_stored=False)
     192        sage: assert Psi(3, use_stored=True) == Psi(3, use_stored=False)
     193        sage: assert Psi(5, use_stored=True) == Psi(5, use_stored=False)
     194        sage: assert Psi(7, use_stored=True) == Psi(7, use_stored=False)
     195        sage: assert Psi(13, use_stored=True) == Psi(13, use_stored=False) # not tested (very long time)
     196    """
     197    if not l in [2,3,5,7,13]:
     198        raise ValueError("Genus zero primes are 2, 3, 5, 7 or 13.")
     199
     200    R = PolynomialRing(ZZ,2,'Xt')
     201    X,t = R.gens()
     202
     203    if use_stored:
     204        if l==2:
     205            return X + t + 64
     206        if l==3:
     207            return X + t + 27
     208        if l==5:
     209            return X**2 + 2*X*(t**2 + 22*t + 125)+ (t**2 + 22*t + 89) * (t**2 + 22*t + 125)
     210        if l==7:
     211            return (X**3 + 3*(t**2 + 13*t + 49)*X**2
     212                    + 3*(t**2 + 13*t + 33)*(t**2 + 13*t + 49)*X
     213                    + (t**2 + 13*t + 49)*(t**4 + 26*t**3 + 219*t**2 + 778*t + 881))
     214        if l==13:
     215            return (t**24 + 66*t**23 + 2091*t**22 + 6*X*t**20 + 42582*t**21 + 330*X*t**19 + 627603*t**20 + 8700*X*t**18 + 7134744*t**19 + 15*X**2*t**16 + 146886*X*t**17 + 65042724*t**18 + 660*X**2*t**15 + 1784532*X*t**16 + 487778988*t**17 + 13890*X**2*t**14 + 16594230*X*t**15 + 3061861065*t**16 + 20*X**3*t**12 + 186024*X**2*t**13 + 122552328*X*t**14 + 16280123754*t**15 + 660*X**3*t**11 + 1774887*X**2*t**12 + 735836862*X*t**13 + 73911331425*t**14 + 10380*X**3*t**10 + 12787272*X**2*t**11 + 3646188342*X*t**12 + 287938949178*t**13 + 15*X**4*t**8 + 102576*X**3*t**9 + 71909658*X**2*t**10 + 15047141292*X*t**11 + 964903805434*t**12 + 330*X**4*t**7 + 707604*X**3*t**8 + 321704316*X**2*t**9 + 51955096824*X*t**10 + 2781843718722*t**11 + 3435*X**4*t**6 + 3582876*X**3*t**7 + 1155971196*X**2*t**8 + 150205315932*X*t**9 + 6885805359741*t**10 + 6*X**5*t**4 + 21714*X**4*t**5 + 13632168*X**3*t**6 + 3343499244*X**2*t**7 + 362526695094*X*t**8 + 14569390179114*t**9 + 66*X**5*t**3 + 90660*X**4*t**4 + 39215388*X**3*t**5 + 7747596090*X**2*t**6 + 725403501318*X*t**7 + 26165223178293*t**8 + 336*X**5*t**2 + 255090*X**4*t**3 + 84525732*X**3*t**4 + 14206132008*X**2*t**5 + 1189398495432*X*t**6 + 39474479008356*t**7 + X**6 + 858*X**5*t + 472143*X**4*t**2 + 132886992*X**3*t**3 + 20157510639*X**2*t**4 + 1569568001646*X*t**5 + 49303015587132*t**6 + 1014*X**5 + 525954*X**4*t + 144222780*X**3*t**2 + 21320908440*X**2*t**3 + 1622460290100*X*t**4 + 49941619724976*t**5 + 272259*X**4 + 96482100*X**3*t + 15765293778*X**2*t**2 + 1260038295438*X*t**3 + 39836631701295*t**4 + 29641924*X**3 + 7210949460*X**2*t + 686651250012*X*t**2 + 23947528862166*t**3 + 1506392823*X**2 + 231462513906*X*t + 10114876838391*t**2 + 35655266790*X + 2644809206442*t + 317295487717)
     216# The coefficients for l=13 are:
     217# X**6: 1
     218# X**5: (6) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)
     219# X**4: (3) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13) * (5*t**4 + 55*t**3 + 260*t**2 + 583*t + 537)
     220# X**3: (4) * (t**2 + 5*t + 13) * (t**2 + 6*t + 13)**2 * (5*t**6 + 80*t**5 + 560*t**4 + 2214*t**3 + 5128*t**2 + 6568*t + 3373)
     221# X**2: (3) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**2 * (5*t**8 + 110*t**7 + 1045*t**6 + 5798*t**5 + 20508*t**4 + 47134*t**3 + 67685*t**2 + 54406*t + 17581)
     222# X**1: (6) * (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**10 + 27*t**9 + 316*t**8 + 2225*t**7 + 10463*t**6 + 34232*t**5 + 78299*t**4 + 122305*t**3 + 122892*t**2 + 69427*t + 16005)
     223# X**0: (t**2 + 5*t + 13)**2 * (t**2 + 6*t + 13)**3 * (t**14 + 38*t**13 + 649*t**12 + 6844*t**11 + 50216*t**10 + 271612*t**9 + 1115174*t**8 + 3520132*t**7 + 8549270*t**6 + 15812476*t**5 + 21764840*t**4 + 21384124*t**3 + 13952929*t**2 + 5282630*t + 854569)
     224#
     225
     226    # Here the generic kernel polynomials are actually calculated:
     227    j = Fricke_module(l)
     228    k = j-1728
     229    from sage.misc.all import prod
     230    f = prod( [p for p,e in j.factor() if e==3]
     231             +[p for p,e in k.factor() if e==2])
     232    A4 = -3*t**2*j*k // f**2
     233    A6 = -2*t**3*j*k**2 // f**3
     234    E = EllipticCurve([0,0,0,A4,A6])
     235    assert E.j_invariant() == j
     236    return E.division_polynomial(l,X).factor()[0][0]
     237
     238
     239def isogenies_prime_degree_genus_0(E, l=None):
     240    """
     241    Returns list of ``l`` -isogenies with domain ``E``.
     242
     243    INPUT:
     244
     245    - ``E`` -- an elliptic curve.
     246
     247    - ``l`` -- either None or 2, 3, 5, 7, or 13.
     248
     249    OUTPUT:
     250
     251    (list) When ``l`` is None a list of all isogenies of degree 2, 3,
     252    5, 7 and 13, otherwise a list of isogenies of the given degree.
     253
     254    .. note::
     255
     256       This function would normally be invoked indirectly via
     257       ``E.isogenies_prime_degree(l)``, which automatically calls the
     258       appropriate function.
     259
     260    ALGORITHM::
     261
     262    Cremona and Watkins [CW2005]_. See also [KT2013]_, Chapter 4.
     263
     264    EXAMPLES::
     265   
     266        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_0
     267        sage: E = EllipticCurve([0,12])
     268        sage: isogenies_prime_degree_genus_0(E, 5)
     269        []
     270
     271        sage: E = EllipticCurve('1450c1')   
     272        sage: isogenies_prime_degree_genus_0(E)   
     273        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 + 300*x - 1000 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 5950*x - 182250 over Rational Field]
     274
     275        sage: E = EllipticCurve('50a1')   
     276        sage: isogenies_prime_degree_genus_0(E) 
     277        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field,
     278        Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
     279    """
     280    if not l in [2, 3, 5, 7, 13, None]:
     281        raise ValueError("%s is not a genus 0 prime."%l)
     282    F = E.base_ring()
     283    j = E.j_invariant()
     284    if F.characteristic() in [2, 3, l]:
     285        raise NotImplementedError("2, 3, 5, 7 and 13-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
     286    if l==2:
     287        return isogenies_2(E)
     288    if l==3:
     289        return isogenies_3(E)
     290    if j==F(0):
     291        if l==5:
     292            return isogenies_5_0(E)
     293        if l==7:
     294            return isogenies_7_0(E)
     295        if l==13:
     296            return isogenies_13_0(E)
     297    if j==F(1728):
     298        if l==5:
     299            return isogenies_5_1728(E)
     300        if l==7:
     301            return isogenies_7_1728(E)
     302        if l==13:
     303            return isogenies_13_1728(E)
     304 
     305    if l != None:
     306        R = PolynomialRing(F,'t')
     307        t = R.gen()
     308        f = R(Fricke_polynomial(l))
     309        t_list = (f-j*t).roots(multiplicities=False)
     310        t_list.sort()
     311        # The generic kernel polynomial applies to a standard curve
     312        # E_t with the correct j-invariant; we must compute the
     313        # appropriate twising factor to scale X by:
     314        c4, c6 = E.c_invariants()
     315        T = c4/(3*c6)
     316        jt = Fricke_module(l)
     317        kt = jt-1728
     318        from sage.misc.all import prod
     319        psi = Psi(l)
     320        X = t
     321        f = R(prod( [p for p,e in jt.factor() if e==3]
     322                 +[p for p,e in kt.factor() if e==2]))
     323        kernels = [R(psi(X*T*(j-1728)*t0/f(t0),t0)) for t0 in t_list]
     324        kernels = [ker.monic() for ker in kernels]
     325        E1 = EllipticCurve([-27*c4,-54*c6])
     326        w = E.isomorphism_to(E1)
     327        model = "minimal" if F is QQ else None
     328        isogs = [E1.isogeny(kernel=ker, model=model) for ker in kernels]
     329        [isog.set_pre_isomorphism(w) for isog in isogs]
     330        return isogs
     331
     332    if l == None:
     333        return sum([isogenies_prime_degree_genus_0(E, l) for l in [2,3,5,7,13]],[])
     334
     335
     336# The function _sporadic_Q_data() returns precomputed data
     337# to be used in isogenies_sporadic_Q. Over Q there are only finitely
     338# many j-invariants of curves with l-isogenies where l is not equal to
     339# 2, 3, 5, 7 or 13. In these cases l is equal to 11, 17, 19, 37, 43,
     340# 67 or 163. We refer to these l as "sporadic".
     341
     342# The values here contain an index as well as the prime l, for ease of use later.
     343
     344_sporadic_Q_pairs = {
     345 -121: (11,0),
     346 -32768: (11,1),
     347 -24729001: (11,2),
     348 -QQ(297756989)/2: (17,3),
     349 -QQ(882216989)/131072: (17,4),
     350 -884736: (19,5),
     351 -9317: (37,6),
     352 -162677523113838677: (37,7),
     353 -884736000: (43,8),
     354 -147197952000: (67,9),
     355 -262537412640768000: (163,10)
     356}
     357
     358#
     359# For each possible sporadic (l,j) pair, _sporadic_Q_data return
     360# ([a4,a6],f) where [a4,a6] are the invariants of a short Weierstrass
     361# model of one curve with that j-invariant,and f is the factor of
     362# degree (l-1)/2 of the l-division polynomial of that curve defining
     363# the kernel of the associated l-isogeny. Whenever we have a curve of
     364# this j-invariant, we can compute the corresponding l-isogeny by just
     365# scaling f by the right twisting factor and using the result as a
     366# kernel-polynomial.
     367
     368# We have precomputed the values of this function for all 11 possible
     369# (l,j) pairs, and by default these precomputed values are returned.
     370# However by calling the function with parameter use_stored=False,
     371# they are recomputed from scratch, allowing for doctesting and also
     372# reproducibility, and to show the method.  For small l it works fine
     373# to factor the l-division polynomial, but this takes a long time for
     374# the larger l and is a very bad idea for l=163; hence we use floating
     375# point arithmetic with a precision which is known to work.  This idea
     376# was suggested by Samir Siksek.
     377
     378def _sporadic_Q_data(elljay, use_stored=True):
     379    """
     380    Returns technical data used in computing sporadic isogenies over `\QQ`.
     381
     382    INPUT:
     383
     384    - ``elljay`` -- a tuple `(l,j)` where `l` is a prime and `j` a
     385      rational number such that elliptic curves with `j`-invariant `j`
     386      possess rational `l`-isogenies.
     387
     388    - ``use_stored`` -- boolean, default True.  If True, return
     389      precomputed values, otherwise compute from scratch.
     390
     391    OUTPUT:
     392
     393    ([a4,a6],coeffs) where [a4,a6] are the coefficients of a short
     394    Weierstrass equation of an elliptic curve E with j(E)=j, and
     395    coeffs is a list of coefficients of a polynomial defining the
     396    kernel of an l-isogeny from E.
     397
     398    TESTS::
     399
     400        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _sporadic_Q_data
     401        sage: elljay = (11, -121)
     402        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     403        True
     404        sage: elljay = (11, -32768)
     405        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     406        True
     407        sage: elljay = (11, -24729001)
     408        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     409        True
     410        sage: elljay = (17, -297756989/2)
     411        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     412        True
     413        sage: elljay = (17, -882216989/131072)
     414        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     415        True
     416        sage: elljay = (19, -884736)
     417        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     418        True
     419        sage: elljay = (37, -9317)
     420        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     421        True
     422        sage: elljay = (37, -162677523113838677)
     423        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     424        True
     425        sage: elljay = (43, -884736000)
     426        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     427        True
     428        sage: elljay = (67, -147197952000)
     429        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     430        True
     431        sage: elljay = (163, -262537412640768000)
     432        sage: _sporadic_Q_data(elljay,False) == _sporadic_Q_data(elljay,True)
     433        True
     434    """
     435    if not use_stored:
     436        from sage.rings.all import RealField
     437        from sage.misc.all import prod
     438        ell,jay = elljay
     439        E = EllipticCurve(j=jay).short_weierstrass_model()
     440        a4a6 = list(E.ainvs())[3:]
     441        L = E.period_lattice()
     442        pr = 100
     443        if ell==163:
     444            pr=1000
     445        elif ell>30:
     446            pr=300
     447        w1, w2 = L.basis(prec=pr)
     448        X = polygen(RealField(pr),'X')
     449        w = w1 # real period
     450        if jay in [-121, -24729001, -162677523113838677, QQ(-882216989)/131072]:
     451            w = 2*w2-w1 # imaginary period
     452        kerpol = prod(([X-L.elliptic_exponential(n*w/ell)[0] for n in range(1,(ell+1)//2)]))
     453        kerpolcoeffs = [c.real().round() for c in list(kerpol)]
     454        return (a4a6,kerpolcoeffs)
     455   
     456    ell, jay = elljay
     457    data = _sporadic_Q_pairs.get(jay,False)
     458    if not data: # not a sporadic j-invariant
     459        return False
     460    if data[0]!=ell: # a sporadic j-invariant, but for a different l
     461        return False
     462    i = data[1]
     463    if i==0:
     464        return ([-3267, -280962], [1480352841, -56169531, -2829222, 10890, 429, 1])
     465    if i==1:
     466        return ([-9504, 365904], [1294672896, -92835072, 1463616, 7920, -264, 1])
     467    if i==2:
     468        return ([-38907, -2953962], [-20349931239, -424530315, -134838, 53658, 429, 1])
     469    if i==3:
     470        return ([-3940515, 3010787550], [-6458213126940667330314375, 34699336325466068070000, -72461450055340471500, 68342601718080000, -15140380554450, -25802960400, 23981220, -8160, 1])
     471    if i==4:
     472        return ([-856035, -341748450], [103687510635057329105625, 961598491955315190000, 1054634146768300500, -6553122389064000, -14554350284850, -2046589200, 13185540, 8160, 1])
     473    if i==5:
     474        return ([-608, 5776], [-34162868224, -8540717056, 6405537792, -1123778560, 84283392, -2033152, -92416, 6992, -152, 1])
     475    if i==6:
     476        return ([-10395, 444150],[-38324677699334121599624973029296875, -17868327793500376961572310472656250, 2569568362004197901139023084765625, -95128267987528547588017818750000, -822168183291347061312510937500, 134395594560592096297190625000, -2881389756919344324888937500, -2503855007083401977250000, 922779077075655997443750, -11503912310262102937500, -18237870962450291250, 1457822151548910000, -10087015556047500, -13677678063000, 490243338900, -2461460400, 5198445, -4410, 1])
     477    if i==7:
     478        return ([-269675595, -1704553285050], [-31653754873248632711650187487655160190139073510876609346911928661154296875/37, -1469048260972089939455942042937882262144594798448952781325533511718750, -1171741935131505774747142644126089902595908234671576131857702734375, -574934780393177024547076427530739751753985644656221274606250000, -193516922725803688001809624711400287605136013195315374687500, -47085563820928456130325308223963045033502182349693125000, -8472233937388712980597845725196873697064639957437500, -1124815211213953261752081095348112305023653750000, -105684015609077608033913080859605951322531250, -5911406027236569746089675554748135312500, 22343907270397352965399097794968750, 43602171843758666292581116410000, 5054350766002463251474186500, 350135768194635636171000, 16633063574896677300, 549939627039600, 12182993865, 163170, 1])
     479    if i==8:
     480        return ([-13760, 621264],[-1961864562041980324821547425314935668736, 784270445793223959453256359333693751296, -120528107728500223255333768387027271680, 10335626145581464192664472924270362624, -568426570575654606865505142156820480, 21261993723422650574629752537088000, -544630471727787626557612832587776, 8870521306520473088172555763712, -54993059067301585878494740480, -1434261324709904840432549888, 50978938193065926383894528, -845761855773797582372864, 8627493611216601088000, -48299605284169187328, -32782260293713920, 3415534989828096, -34580115625984, 199359712512, -730488128, 1658080, -2064, 1])
     481
     482    if i==9:
     483        return ([-117920, 15585808], [426552448394636714720553816389274308035895411389805883034985546818882031845376, -55876556222880738651382959148329502876096075327084935039031884373558741172224, 3393295715290183821010552313572221545212247684503012173117764703828786020352, -125729166452196578653551230178028570067747190427221869867485520072257044480, 3121342502030777257351089270834971957072933779704445667351054593298530304, -52544031605544530265465344472543470442324636919759253720520768014516224, 532110915869155495738137756847596184665209453108323879594125221167104, -399031158106622651277981701966309467713625045637309782055519780864, -101914346170769215732007802723651742508893380955930030421292613632, 2296526155500449624398016447877283594461904009374321659789443072, -31950871094301541469458501953701002806003991982768349794795520, 329792235011603804948028315065667439678526339671142107709440, -2655636715955021784085217734679612378726442691190553837568, 16825164648840434987220620681420687654501026066872664064, -81705027839007003131400500185224450729843244954288128, 273656504606483403474090105104132405333665144373248, -320807702482945680116212224172370503903312084992, -3166683390779345463318656135338172047199043584, 27871349428383710305216046431806697565585408, -132774697798318602604125735604528772808704, 436096215568182871014215818309741314048, -964687143341252402362763535357837312, 942144169187362941776488535425024, 2794850106281773765892648206336, -17236916236678037389276086272, 50979778712911923486851072, -105035658611718440992768, 161833913559276412928, -188675698610077696, 163929317513984, -102098677888, 42387952, -10184, 1])
     484
     485    if i==10:
     486        return ([-34790720, 78984748304], [11937033609701771608400008302859181021419097217821452062564326844817505228663098831008549807845273606080544999996020379100442085010011180910986311230744539492209201267851475053850145465949031314131282944262561686476431332761205504055553653209756637748416809823347727611717499380045401030656, -195130071447306655273524569473852352290010571088570084255929596426827972913675959924834214553822436039185267072655230231264389277855757579340840680919752147359277865429131554516271296434318501723193704667609983954393732283396979741770275596479169906167026623493287956522391758781645062144, 1427502734760154784443139998885173873805698542265553947708985997014264802221336771918193375050938963016560184673026895611200993837000754187703921657388546609660768979949394789838000919808563779734300559653270446650866261801622261730386746625133970663551831816512698564779980290036596736, -5599207432852992026535855102327743354503965526118767584653806869099469434869389394471452436350209911401734358692516268244363981178003440912521398279843764610451103952982463228121628686179444592844803463454880601969041617668281227800515971090274318968755339891485627349912827843313664, 7275289443663173375117187980461451723630939807433676133488193878209459535146604043302393215325736700753114238886326617501903060793779318898498537340122928915051396994852249905774785383484964157718761647679761326405167986820403416875550489904598260809039588027484880575324789669888, 53852767252251176711316610474871670511285949778037067647446607721301053062542360857644949076379793988972999080753585666268471181395581176311086709516236139859119228114940726664020344711163961450649040900179940667704933096423082541578086102752168151408016128448757608609516355584, -441024601763314150109608522830440149169771622404264936395215000306188259683627792348927267455527449622616337194882061278315837263834842622422058957336768392927319786456429412773335490683756389242358011775192147290260088212928183893496023497385031567935590156495818971603271680, 1923729652470036657640234466480856403679261373466564217770510758620007251234737653848912112257887106718711179570266106782165127910894792855741763009046440188368346201617134183692667813264354753020558715833289878752200363206184231817927249353441775148372373391040829093576704, -6174291905252822700639099970860178217904525535465573253756653994759145320917644436646210500761314537511653465341404223911052812759676375813287317189557074876672717009913962857515263325087926781282727274494599622098970326546685474959128901831166082055481492871737587531776, 15963605433939241348215386312076502855685142708851007052060264896693306401589916424547272907372369971200908960298559196028000249867821387055883338894215055448441454208145184664251082508258481820123154014612667230187589409024581605410594578299015578613903351914203971584, -34687777075075826936035422448136670540047824478867437603900549472003349053758981331083701038247602826434094223697740838012005963350495346494192086319952577715870471857062004211165110944749546489357024333327851492892063261902845789001287880518909468079710544890691584, 64935614565701660925102862834870557968917923758048315817978089985628103203452108238400473842703675144415856702414743965076964752315718880263247146806212144113325233966196430978981658754610129252819800656290540439882400228191972297000590950499022332532802841477120, -106450113192928986500166510746460290010686605565802553549898115364953461571938149159855780359758326598170956839310849727549767334328481520722457671184262149140997347199434067316119593873464084542168958564857207310255104210252802288265107074620056433232296542208, 154588468341182819097156049664780175805765082709542906853062319968823210709884467518965950031344875777123989196305422245441384128571495551803479155842444104959551491130118809781140758556182128829570214830557657320822341658937375265326185627024588353675722752, -200559814675071715715147513664537685696543665835231560123119674695431140901874837885144270078673500682009909076723885595600964688749788075855566556738418513204701882392037282897429720984011892144438563658741417367819609826485149957684720592798005782904832, 233913230287794067984901680255098952718268709897211662836962202594844321932231309396660409956864579218254273924904394011519168528453166798219739516110916032144001430976170021740673624911101610999174313953331179592523559209806130064362331035786304028672, -246353703535830799051965068435640665615241585380168769205605419959931340172791084855084136413845436489354260626697043416419953596294256639939636661074827002386688825389366314922889935515780006872313799807871034941783710991661439846743406825846079488, 234982742638283161239147075499923192184558615040750093346909554959954534765162320677404212311317141015056956519607730625264033505832417237335526289717986324622989530401755659861160278474288472483456460761582961131223878005034852988312569782468608, -203278213565303083958289848507904983111914464281937008996800600743049033135780053019308180654889993715847194782810638377233384956677984229396984592095978852141937402724743415866647478390224972086303117541277057454016741537801255285401042550784, 159421011266364165773350759598961923468646295930442671951663830439105229019095602850806206849694626149081055860876320252885592409781300283802068036284087012054926328984117466238728138017296876920468741929209733382315316048593848804000661504, -113020918346823224387675962727710849438448560054728764538889949910907956081636084818673918939857811981198128625134001275445247927733612860826192033364144709296859805908448480126055187856540001252440723696556907592809391568682658983575552, 71945777186858148520189111385851657591994785437936790663752048596268908397761761228530149720647914698227096033298596468433406211022425872184679773706985835273196359946527329295352840585601589987654250252509940697181497393634479177728, -40553506248279853197899380016510447069205875473858373944916667311741237594752103405195544436215283638784303466518029972315361472909380024525230365389883507930702477745185560842399992120410631726800835247081534888734998176190169088, 19639696188973552762819015734509385187497753279018359326954702329472344393424778261565226791972589248949076879073752940457430177635689762236418319921157145929450429275277598105096782299310906043071624518383647513981402864418816, -7557145635717782395604678688732309739123765964398036300935902895029921544449817739871127195837816246027098669576710973724603305169613035210748794125702623638061784934800621663541549758981147547220745886014319375033833619456, 1657074863449131529294393850366914004166071540911557375298352670995793916631379837217699843183161870412953109096989706473414891817476345269315000071815674837414249807862563049048940888990780356828116926372826050377809920, 594537607406738614488647166334439665406200193881374352383582637957395810395355986219181323336507140663007282377906531198753011484726171889166159296232442266402815351908351664480142997422997116094990105400004717838336, -1063381335685557601789471169771716160614658527547206527560235661204306306147122486589145738731952820149525220010993135210540125800587297277176980780550749659568216404307556497848427558893515024809067113577642459136, 866504016710397283549081797838552191017551170056714418172658679484342314216337494688411296133019156758665490378562995489461120013841310945167448587950589192882728019730184100760635093600626150305226434294054912, -544456451437710104677464982275658569122639544706468906698603670935572135268235880234260773620839923609980624261711876187191086008709319550421652238153751371247896403810296918434808016324776218527300472274944, 291391938923983436973777049837536733140215048414562274102609644110225500962890424001140034799254161420207705596799832439286323749581485058440291289292376834767289200150488260103720502388531610043446984704, -137669336373928330264003425607593379960726875901008061728935571651808147336578784033262243606118618305155146994101199276509296485578362621442124562716722538959248783675765430495753630524650420015464448, 58305039769563586190846386880024028458953483779423358562963969531061253550565868881984384427294827940260948562007946246585988242539388915757370599713569828414708265704775708180369817440224330907648, -22263674613297409152475382098514675408629524088165884591926938276387287183647211206514841583522457779552325379611699721363009213935995055122374833256328128159685068070573439567341889102047870976, 7659525572873653643686667682470156611730287715779213959462404612107764289631014622079262434509991525269350939684751076168111178931547830737285816290499346814316593688339716060537705476390912, -2356369509601030092354164626593105564281508081035914666378162646456624099153984023946457193322861690246151591627985138670141283491665875837349056368982626874320059053912723460560567402496, 636306064623878566247238117586667093960745761448319133509756604897082306674457051834692637631208787669480579961449146859307914219525683813169045631019945325543755784485150162136596480, -144354698667964959131302121388611435649331689922451077357726958728526160763985021377919777057073652734054824995380136026354322489788621439866623621032883911971992887755746217820160, 24121955586756417060840806312875152536841537469465641066665477185642959713399102667004561835703554642486033432650174169972215286732914841507194929969333501923213681889898397696, -1062982554332400020436047718307967606435230424325029173087078414691100152298424407470637592479633445244263771003475924500470457802708388802132021409732119617604143984672768, -1289959173517591900879403877417447464323361120695839905879179383576917611515563011791770601288187258710836960962551744314331281738572022125094897455138775637822772609024, 713094034093241133139975542207369737377005379966568397923649557581354608722973890056780743426440880397949894405054289149004564424971813787111450018625163532324306944, -254627379967901645020979419858451704766383325190491161773871149760504423262065255127251316663797380198173202687716259997416292667070368594859769612820620832145408, 73141763506085097918144459824978126154049420184880822723900482544151820781804249152002290712777719695036970656528265835764223704583688284269989955443519127552, -17838537225679516940483486695156689114251551141417084228356667456567223074797422210814066353881812352204911178711536306766419580650031647883778868599848960, 3732949472404613028683276858400771022649020140479952475050562287824228475488013407594597423014344735572239887680502683815016952233794807477380489150464, -658090831088275932021697572468169724648153295038942023393017242911882324988827102897240587742441233130939688197251981440661637431663180512231424000, 91044773494274344573228085560493548892450695165631132364575161840790371925870648417274049055693061297980952723608086693629684733411639066361856, -7206875978668204173369106020317806614830036116031258178074085756310402308591937698714169573782276745187407867676712962154996289706219536384, -819751497058465540849522914081577930969395072622202448379227754265195552229316711754131018363430793506957620878700584807196119659446272, 524492219141524596329431820120551446539246304466694008535436881375050446937946483408452355745347329681867559263476448413099237572608, -144831995016562693238485974645571530330971707229081912571899541756458417275452663670185243929333997861822834344607487043313860608, 29914869637979316056234691641068533246353548074478964560456384907200155525359490145390698951538414992573246875654471802683392, -5051703199007242317980870828294675665554938059871421101373455640671888804716466166733214891733545898164243959713215021056, 704266224450794229753813389400889235502895246267920454892105495898823500254340026026030392861415807391779452916596736, -77090914220067457257437168730743598007998214624866646138957596697882331770536104168830311427039146990575867133952, 5185529715527985800186976473360862373518426289807725150611458977619779754244941008386724289180811582624497664, 253997773097193639890870939442154039645526260966991421810387625142025920490445698037959549218977356972032, -167663051891371188948811201282888303918118872228509878481620659513761819092806840088343319460416847872, 37111139278046773379558801627698801653586358926939257719148812112681156722739468064234356797865984, -6094794232647488071603134809336879629321484740792083961518604911291776122012806633249006682112, 837291566508665017874331015912241564512130987193765470835615200761060354034220082158108672, -100296887606046826616864046733353580911852480578758327196473644505408067503452896362496, 10671531126308719182671886696772003009468978048122050876385337250105289881860177920, -1017660211057522997139542974021461951590281854561469513981031668621068390629376, 87341651749945752980300268787472991750253192293865191008561736741703122944, -6755055811837604655292473395831392832731215030180150346004905802596352, 470435697396489049890276884918878813522261509046808135502735081472, -29431936259973770189795237369002643735145492537132570738950144, 1647955729708147681608319291051493831298410618099083509760, -82151504501901440318090519089275042334656836617109504, 3621394962905672351516373383975280471835697741824, -139946424433346723333934826799658073276284928, 4689146702972667351768128807176661303296, -134326059738838559898371882636836864, 3230090486862617839209120497664, -63628315178835325152092160, 992573003659549935360, -11668560578458368, 95539651616, -472048, 1])
     487    return False
     488
     489
     490def isogenies_sporadic_Q(E, l=None):
     491    """
     492    Returns list of ``l`` -isogenies with domain ``E`` (defined over `\QQ`).
     493
     494    Returns a list of sporadic l-isogenies from E (l = 11, 17, 19, 37,
     495    43, 67 or 163). Only for elliptic curves over `\QQ`.
     496
     497    INPUT:
     498
     499    - ``E`` -- an elliptic curve defined over `\QQ`.
     500
     501    - ``l`` -- either None or a prime number.
     502
     503    OUTPUT:
     504
     505    (list) If ``l`` is None, a list of all isogenies with domain ``E``
     506    and of degree 11, 17, 19, 37, 43, 67 or 163; otherwise a list of
     507    isogenies of the given degree.
     508
     509    .. note::
     510
     511       This function would normally be invoked indirectly via
     512       ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate
     513       function.
     514
     515    EXAMPLES::
     516
     517        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_sporadic_Q                                                                       
     518        sage: E = EllipticCurve('121a1')   
     519        sage: isogenies_sporadic_Q(E, 11)
     520        [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field]
     521        sage: isogenies_sporadic_Q(E, 13)
     522        []
     523        sage: isogenies_sporadic_Q(E, 17)
     524        []
     525        sage: isogenies_sporadic_Q(E)   
     526        [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field]
     527         
     528        sage: E = EllipticCurve([1, 1, 0, -660, -7600])   
     529        sage: isogenies_sporadic_Q(E, 17)
     530        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field]
     531        sage: isogenies_sporadic_Q(E)   
     532        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field]
     533        sage: isogenies_sporadic_Q(E, 11)
     534        []
     535       
     536        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])   
     537        sage: isogenies_sporadic_Q(E, 11)
     538        []
     539        sage: isogenies_sporadic_Q(E, 19)
     540        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
     541        sage: isogenies_sporadic_Q(E)   
     542        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
     543
     544        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     545        sage: E.conductor()
     546        19600
     547        sage: isogenies_sporadic_Q(E,37)
     548        [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field]
     549
     550        sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750])
     551        sage: E.conductor()                                       
     552        148225
     553        sage: isogenies_sporadic_Q(E,37)
     554        [Isogeny of degree 37 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 25178045*x + 48616918750 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 970*x - 13075 over Rational Field]
     555
     556        sage: E = EllipticCurve([-3440, 77658])         
     557        sage: E.conductor()                   
     558        118336
     559        sage: isogenies_sporadic_Q(E,43)       
     560        [Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 over Rational Field]
     561
     562        sage: E = EllipticCurve([-29480, -1948226])     
     563        sage: E.conductor()
     564        287296
     565        sage: isogenies_sporadic_Q(E,67)
     566        [Isogeny of degree 67 from Elliptic Curve defined by y^2 = x^3 - 29480*x - 1948226 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 132335720*x + 585954296438 over Rational Field]
     567
     568        sage: E = EllipticCurve([-34790720, -78984748304])
     569        sage: E.conductor()
     570        425104
     571        sage: isogenies_sporadic_Q(E,163)
     572        [Isogeny of degree 163 from Elliptic Curve defined by y^2 = x^3 - 34790720*x - 78984748304 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 924354639680*x + 342062961763303088 over Rational Field]
     573    """
     574    if E.base_ring() != QQ:
     575        raise ValueError("The elliptic curve must be defined over QQ.")
     576    j = E.j_invariant()
     577    j = QQ(j)
     578    if l != None:
     579        if not l.is_prime():
     580            raise ValueError("%s is not prime."%l)
     581        data = _sporadic_Q_data((l,j))
     582        if not data:
     583            return []
     584        Ew = E.short_weierstrass_model()
     585        E_to_Ew = E.isomorphism_to(Ew)
     586        c4, c6 = Ew.c_invariants()
     587        (a4,a6), f = data
     588        d = (c6*a4)/(18*c4*a6) # twisting factor
     589        R = PolynomialRing(E.base_field(),'X')
     590        n = len(f)
     591        ker = R([d**(n-i-1) * f[i] for i in range(n)])
     592        isog = Ew.isogeny(kernel=ker, degree=l, model="minimal", check=False)
     593        isog.set_pre_isomorphism(E_to_Ew)
     594        return [isog]
     595    if l is None:
     596        data = _sporadic_Q_pairs.get(j,False)
     597        if not data:
     598            return []
     599        return isogenies_sporadic_Q(E, Integer(data[0]))
     600
     601def isogenies_2(E):
     602    """
     603    Returns a list of all 2-isogenies with domain ``E``.
     604
     605    INPUT:
     606
     607    - ``E`` -- an elliptic curve.
     608
     609    OUTPUT:
     610
     611    (list) 2-isogenies with domain ``E``.  In general these are
     612    normalised, but over `\QQ` the codomain is a minimal model.
     613
     614    EXAMPLES::
     615
     616        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_2   
     617        sage: E = EllipticCurve('14a1'); E
     618        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
     619        sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
     620        [(1, 0, 1, -36, -70)]
     621
     622        sage: E = EllipticCurve([1,2,3,4,5]); E
     623        Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
     624        sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
     625        []
     626        sage: E = EllipticCurve(QQbar, [9,8]); E 
     627        Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field
     628        sage: isogenies_2(E) # not implemented
     629    """
     630    f2 = E.division_polynomial(2)
     631    x2 = f2.roots(multiplicities=False)
     632    x2.sort()
     633    x = f2.parent().gen()
     634    ff = [x-x2i for x2i in x2]
     635    model = "minimal" if E.base_field() is QQ else None
     636    isogs = [E.isogeny(f, model=model) for f in ff]
     637    return isogs
     638   
     639def isogenies_3(E):
     640    """
     641    Returns a list of all 3-isogenies with domain ``E``.
     642
     643    INPUT:
     644
     645    - ``E`` -- an elliptic curve.
     646
     647    OUTPUT:
     648
     649    (list) 3-isogenies with domain ``E``.  In general these are
     650    normalised, but over `\QQ` the codomain is a minimal model.
     651
     652    EXAMPLES::
     653
     654        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_3
     655        sage: E = EllipticCurve(GF(17), [1,1])
     656        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     657        [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)]
     658
     659        sage: E = EllipticCurve(GF(17^2,'a'), [1,1])
     660        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     661        [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1), (0, 0, 0, 5*a + 1, a + 13), (0, 0, 0, 12*a + 6, 16*a + 14)]
     662
     663        sage: E = EllipticCurve('19a1')   
     664        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     665        [(0, 1, 1, 1, 0), (0, 1, 1, -769, -8470)]
     666
     667        sage: E = EllipticCurve([1,1])
     668        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     669        []
     670    """
     671    f3 = E.division_polynomial(3)
     672    x3 = f3.roots(multiplicities=False)
     673    x3.sort()
     674    x = f3.parent().gen()
     675    ff = [x-x3i for x3i in x3]
     676    model = "minimal" if E.base_field() is QQ else None
     677    isogs = [E.isogeny(f, model=model) for f in ff]
     678    return isogs
     679
     680# 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728.
     681
     682def isogenies_5_0(E):
     683    """
     684    Returns a list of all the 5-isogenies  with domain ``E`` when the
     685    j-invariant is 0.
     686
     687    OUTPUT:
     688
     689    (list) 5-isogenies with codomain E.  In general these are
     690    normalised, but over `\QQ` the codomain is a minimal model.
     691
     692    .. note::
     693
     694       This implementation requires that the characteristic is not 2,
     695       3 or 5.
     696
     697    .. note::
     698
     699       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
     700
     701    EXAMPLES::
     702
     703        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_0
     704        sage: E = EllipticCurve([0,12])
     705        sage: isogenies_5_0(E)                             
     706        []
     707
     708        sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
     709        sage: isogenies_5_0(E)
     710        [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (4*a+6)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (12*a+5)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (10*a+2)*x + (2*a+10) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (3*a+12)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (a+4)*x + (11*a+12) over Finite Field in a of size 13^2, Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + (9*a+10)*x + (11*a+12) over Finite Field in a of size 13^2]
     711
     712        sage: K.<a> = NumberField(x**6-320*x**3-320)
     713        sage: E = EllipticCurve(K,[0,0,1,0,0])
     714        sage: isogenies_5_0(E)                     
     715        [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 = x^3 + (a^5-400*a^2)*x + (280*a^3-3120) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320,
     716        Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 over Number Field in a with defining polynomial x^6 - 320*x^3 - 320 to Elliptic Curve defined by y^2 = x^3 + (23/2*a^5-3700*a^2)*x + (-280*a^3+86480) over Number Field in a with defining polynomial x^6 - 320*x^3 - 320]
     717
     718    """
     719    F = E.base_field()
     720    if E.j_invariant() != 0:
     721        raise ValueError("j-invariant must be 0.")
     722    if F.characteristic() in [2,3,5]:
     723        raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
     724    if not F(5).is_square():
     725        return []
     726    Ew = E.short_weierstrass_model()
     727    a = Ew.a6()
     728    x = polygen(F)
     729    betas = (x**6-160*a*x**3-80*a**2).roots(multiplicities=False)
     730    betas.sort()
     731    if len(betas)==0:
     732        return []
     733    gammas = [(beta**2 *(beta**3-140*a))/(120*a) for beta in betas]
     734    model = "minimal" if F is QQ else None
     735    isogs = [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
     736    iso = E.isomorphism_to(Ew)
     737    [isog.set_pre_isomorphism(iso) for isog in isogs]
     738    return isogs
     739
     740def isogenies_5_1728(E):
     741    """
     742    Returns a list of 5-isogenies with domain ``E`` when the j-invariant is
     743    1728.
     744
     745    OUTPUT:
     746
     747    (list) 5-isogenies with codomain E.  In general these are
     748    normalised; but if `-1` is a square then there are two
     749    endomorphisms of degree `5`, for which the codomain is the same as
     750    the domain curve; and over `\QQ`, the codomain is a minimal model.
     751
     752    .. note::
     753
     754       This implementation requires that the characteristic is not 2,
     755       3 or 5.
     756
     757    .. note::
     758
     759       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
     760
     761    EXAMPLES::
     762       
     763        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
     764        sage: E = EllipticCurve([7,0])   
     765        sage: isogenies_5_1728(E)
     766        []
     767
     768        sage: E = EllipticCurve(GF(13),[11,0])
     769        sage: isogenies_5_1728(E)       
     770        [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13,
     771        Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 11*x over Finite Field of size 13]
     772
     773    An example of endomorphisms of degree 5::
     774
     775        sage: K.<i> = QuadraticField(-1)                   
     776        sage: E = EllipticCurve(K,[0,0,0,1,0])
     777        sage: isogenies_5_1728(E)             
     778        [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1,
     779        Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + x over Number Field in i with defining polynomial x^2 + 1]
     780        sage: _[0].rational_maps()
     781        (((4/25*i + 3/25)*x^5 + (4/5*i - 2/5)*x^3 - x)/(x^4 + (-4/5*i + 2/5)*x^2 + (-4/25*i - 3/25)),
     782         ((11/125*i + 2/125)*x^6*y + (-23/125*i + 64/125)*x^4*y + (141/125*i + 162/125)*x^2*y + (3/25*i - 4/25)*y)/(x^6 + (-6/5*i + 3/5)*x^4 + (-12/25*i - 9/25)*x^2 + (2/125*i - 11/125)))
     783
     784    An example of 5-isogenies over a number field::
     785
     786        sage: K.<a> = NumberField(x**4+20*x**2-80)
     787        sage: K(5).is_square() #necessary but not sufficient!       
     788        True
     789        sage: E = EllipticCurve(K,[0,0,0,1,0])   
     790        sage: isogenies_5_1728(E)                 
     791        [Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-20*a^2-39)*x + (35*a^3+112*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80,
     792        Isogeny of degree 5 from Elliptic Curve defined by y^2 = x^3 + x over Number Field in a with defining polynomial x^4 + 20*x^2 - 80 to Elliptic Curve defined by y^2 = x^3 + (-20*a^2-39)*x + (-35*a^3-112*a) over Number Field in a with defining polynomial x^4 + 20*x^2 - 80]   
     793    """
     794    F = E.base_field()
     795    if E.j_invariant() != 1728:
     796        raise ValueError("j-invariant must be 1728.")
     797    if F.characteristic() in [2,3,5]:
     798        raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
     799    model = "minimal" if F is QQ else None
     800    # quick test for a negative answer (from Fricke module)
     801    square5 = F(5).is_square()
     802    square1 = F(-1).is_square()
     803    if not square5 and not square1:
     804        return []
     805    Ew = E.short_weierstrass_model()
     806    iso = E.isomorphism_to(Ew)
     807    a = Ew.a4()
     808    x = polygen(F)
     809    isogs = []
     810    # 2 cases
     811    # Type 1: if -1 is a square we have 2 endomorphisms
     812    if square1:
     813        i = F(-1).sqrt()
     814        isogs = [Ew.isogeny(f) for f in [x**2+a/(1+2*i), x**2+a/(1-2*i)]]
     815        [isog.set_post_isomorphism(isog.codomain().isomorphism_to(E)) for isog in isogs]
     816    # Type 2: if 5 is a square we have up to 4 (non-endomorphism) isogenies
     817    if square5:
     818        betas = (x**4+20*a*x**2-80*a**2).roots(multiplicities=False)
     819        betas.sort()
     820        gammas = [a*(beta**2-2)/6 for beta in betas]
     821        isogs += [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
     822    [isog.set_pre_isomorphism(iso) for isog in isogs]
     823    return isogs
     824
     825def isogenies_7_0(E):
     826    """
     827    Returns list of all 7-isogenies from E when the j-invariant is 0.
     828
     829    OUTPUT:
     830
     831    (list) 7-isogenies with codomain E.  In general these are
     832    normalised; but if `-3` is a square then there are two
     833    endomorphisms of degree `7`, for which the codomain is the same as
     834    the domain; and over `\QQ`, the codomain is a minimal model.
     835
     836    .. note::
     837
     838       This implementation requires that the characteristic is not 2,
     839       3 or 7.
     840
     841    .. note::
     842
     843       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
     844
     845    EXAMPLES:
     846
     847    First some examples of endomorphisms::
     848
     849        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0   
     850        sage: K.<r> = QuadraticField(-3)
     851        sage: E = EllipticCurve(K, [0,1]) 
     852        sage: isogenies_7_0(E)
     853        [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3,
     854        Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + 1 over Number Field in r with defining polynomial x^2 + 3]
     855
     856        sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
     857        sage: isogenies_7_0(E)       
     858        [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2 to Elliptic Curve defined by y^2 = x^3 + 10 over Finite Field in a of size 13^2]
     859
     860    Now some examples of 7-isogenies which are not endomorphisms::
     861
     862        sage: K = GF(101)               
     863        sage: E = EllipticCurve(K, [0,1])
     864        sage: isogenies_7_0(E)           
     865        [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 55*x + 100 over Finite Field of size 101, Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 101 to Elliptic Curve defined by y^2 = x^3 + 83*x + 26 over Finite Field of size 101]
     866
     867    Examples over a number field::
     868
     869        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
     870        sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r'))
     871        sage: isogenies_7_0(E)
     872        [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3,
     873        Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 + y = x^3 + (-7) over Number Field in r with defining polynomial x^2 + 3]
     874
     875        sage: K.<a> = NumberField(x^6 + 1512*x^3 - 21168)
     876        sage: E = EllipticCurve(K, [0,1])
     877        sage: isogs = isogenies_7_0(E)
     878        sage: [phi.codomain().a_invariants() for phi in isogs]
     879        [(0, 0, 0, -5/294*a^5 - 300/7*a^2, -55/2*a^3 - 1133),
     880        (0, 0, 0, -295/1176*a^5 - 5385/14*a^2, 55/2*a^3 + 40447)]
     881        sage: [phi.codomain().j_invariant() for phi in isogs]
     882        [158428486656000/7*a^3 - 313976217600000,
     883        -158428486656000/7*a^3 - 34534529335296000]
     884    """
     885    if E.j_invariant()!=0:
     886        raise ValueError("j-invariant must be 0.")
     887    F = E.base_field()
     888    if F.characteristic() in [2,3,7]:
     889        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
     890    x = polygen(F)
     891    Ew = E.short_weierstrass_model()
     892    iso = E.isomorphism_to(Ew)
     893    a = Ew.a6()
     894    model = "minimal" if F is QQ else None
     895
     896    # there will be 2 endomorphisms if -3 is a square:
     897
     898    ts = (x**2+3).roots(multiplicities=False)
     899    ts.sort()
     900    kers = [7*x-(2+6*t) for t in ts]
     901    kers = [k(x**3/a).monic() for k in kers]
     902    isogs = [Ew.isogeny(k,model=model) for k in kers]
     903    if len(isogs)>0:
     904        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     905
     906    # we may have up to 6 other isogenies:
     907    ts = (x**2-21).roots(multiplicities=False)
     908    for t0 in ts:
     909        s3 = a/(28+6*t0)
     910        ss = (x**3-s3).roots(multiplicities=False)
     911        ss.sort()
     912        ker = x**3 - 2*t0*x**2 - 4*t0*x + 4*t0 + 28
     913        kers = [ker(x/s).monic() for s in ss]
     914        isogs += [Ew.isogeny(k, model=model) for k in kers]
     915   
     916    [isog.set_pre_isomorphism(iso) for isog in isogs]
     917    return isogs
     918
     919def isogenies_7_1728(E):
     920    """
     921    Returns list of all 7-isogenies from E when the j-invariant is 1728.
     922
     923    OUTPUT:
     924
     925    (list) 7-isogenies with codomain E.  In general these are
     926    normalised; but over `\QQ` the codomain is a minimal model.
     927
     928    .. note::
     929
     930       This implementation requires that the characteristic is not 2,
     931       3, or 7.
     932
     933    .. note::
     934
     935       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
     936
     937    EXAMPLES::
     938
     939        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728                                                                           
     940        sage: E = EllipticCurve(GF(47), [1, 0])
     941        sage: isogenies_7_1728(E)             
     942        [Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 26 over Finite Field of size 47,
     943        Isogeny of degree 7 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 47 to Elliptic Curve defined by y^2 = x^3 + 21 over Finite Field of size 47]
     944
     945    An example in characteristic 53 (for which an earlier implementation did not work)::   
     946
     947        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
     948        sage: E = EllipticCurve(GF(53), [1, 0])
     949        sage: isogenies_7_1728(E)
     950        []
     951        sage: E = EllipticCurve(GF(53^2,'a'), [1, 0])
     952        sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)]
     953        [(0, 0, 0, 36, 19*a + 15), (0, 0, 0, 36, 34*a + 38), (0, 0, 0, 33, 39*a + 28), (0, 0, 0, 33, 14*a + 25), (0, 0, 0, 19, 45*a + 16), (0, 0, 0, 19, 8*a + 37), (0, 0, 0, 3, 45*a + 16), (0, 0, 0, 3, 8*a + 37)]
     954
     955    ::   
     956
     957        sage: K.<a> = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567)
     958        sage: E = EllipticCurve(K, [1, 0])                               
     959        sage: isogs = isogenies_7_1728(E)
     960        sage: [phi.codomain().a_invariants() for phi in isogs]
     961        [(0,
     962        0,
     963        0,
     964        35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
     965        155/636*a^7 + 245/12*a^5 - 313355/636*a^3 - 3577/636*a),
     966        (0,
     967        0,
     968        0,
     969        35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
     970        -155/636*a^7 - 245/12*a^5 + 313355/636*a^3 + 3577/636*a)]
     971        sage: [phi.codomain().j_invariant() for phi in isogs]
     972        [-526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53,
     973        -526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53]
     974        sage: E1 = isogs[0].codomain()
     975        sage: E2 = isogs[1].codomain()
     976        sage: E1.is_isomorphic(E2)
     977        False
     978        sage: E1.is_quadratic_twist(E2)
     979        -1
     980    """
     981    if E.j_invariant()!=1728:
     982        raise ValueError("j_invariant must be 1728 (in base field).")
     983    F = E.base_field()
     984    if F.characteristic() in [2,3,7]:
     985        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
     986    Ew = E.short_weierstrass_model()
     987    iso = E.isomorphism_to(Ew)
     988    a = Ew.a4()
     989
     990    ts = (Fricke_module(7)-1728).numerator().roots(F,multiplicities=False)
     991    if len(ts)==0:
     992        return []
     993    ts.sort()
     994    isogs = []
     995    model = "minimal" if F is QQ else None
     996    x = polygen(F)
     997    for t0 in ts:
     998        s2 = a/t0
     999        ss = (x**2-s2).roots(multiplicities=False)
     1000        ss.sort()
     1001        ker = 9*x**3 + (-3*t0**3 - 36*t0**2 - 123*t0)*x**2 + (-8*t0**3 - 101*t0**2 - 346*t0 + 35)*x - 7*t0**3 - 88*t0**2 - 296*t0 + 28
     1002
     1003        kers = [ker(x/s) for s in ss]
     1004        isogs += [Ew.isogeny(k.monic(), model=model) for k in kers]
     1005    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1006    return isogs
     1007
     1008def isogenies_13_0(E):
     1009    """
     1010    Returns list of all 13-isogenies from E when the j-invariant is 0.
     1011
     1012    OUTPUT:
     1013
     1014    (list) 13-isogenies with codomain E.  In general these are
     1015    normalised; but if `-3` is a square then there are two
     1016    endomorphisms of degree `13`, for which the codomain is the same
     1017    as the domain.
     1018
     1019    .. note::
     1020
     1021       This implementation requires that the characteristic is not 2,
     1022       3 or 13.
     1023
     1024    .. note::
     1025
     1026       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
     1027
     1028    EXAMPLES::
     1029
     1030        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_0 
     1031
     1032    Endomorphisms of degree 13 will exist when -3 is a square::   
     1033
     1034        sage: K.<r> = QuadraticField(-3)
     1035        sage: E = EllipticCurve(K, [0, r]); E
     1036        Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3
     1037        sage: isogenies_13_0(E)
     1038        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3,
     1039        Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3 to Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3]
     1040        sage: isogenies_13_0(E)[0].rational_maps()
     1041        (((7/338*r + 23/338)*x^13 + (-164/13*r - 420/13)*x^10 + (720/13*r + 3168/13)*x^7 + (3840/13*r - 576/13)*x^4 + (4608/13*r + 2304/13)*x)/(x^12 + (4*r + 36)*x^9 + (1080/13*r + 3816/13)*x^6 + (2112/13*r - 5184/13)*x^3 + (-17280/169*r - 1152/169)), ((18/2197*r + 35/2197)*x^18*y + (23142/2197*r + 35478/2197)*x^15*y + (-1127520/2197*r - 1559664/2197)*x^12*y + (-87744/2197*r + 5992704/2197)*x^9*y + (-6625152/2197*r - 9085824/2197)*x^6*y + (-28919808/2197*r - 2239488/2197)*x^3*y + (-1990656/2197*r - 3870720/2197)*y)/(x^18 + (6*r + 54)*x^15 + (3024/13*r + 11808/13)*x^12 + (31296/13*r + 51840/13)*x^9 + (487296/169*r - 2070144/169)*x^6 + (-940032/169*r + 248832/169)*x^3 + (1990656/2197*r + 3870720/2197)))
     1042
     1043    An example of endomorphisms over a finite field::
     1044   
     1045        sage: K = GF(19^2,'a')
     1046        sage: E = EllipticCurve(j=K(0)); E
     1047        Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
     1048        sage: isogenies_13_0(E)                   
     1049        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2,
     1050        Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2 to Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2]
     1051        sage: isogenies_13_0(E)[0].rational_maps()
     1052        ((6*x^13 - 6*x^10 - 3*x^7 + 6*x^4 + x)/(x^12 - 5*x^9 - 9*x^6 - 7*x^3 + 5), (-8*x^18*y - 9*x^15*y + 9*x^12*y - 5*x^9*y + 5*x^6*y - 7*x^3*y + 7*y)/(x^18 + 2*x^15 + 3*x^12 - x^9 + 8*x^6 - 9*x^3 + 7))
     1053
     1054    A previous implementation did not work in some characteristics::   
     1055
     1056        sage: K = GF(29)
     1057        sage: E = EllipticCurve(j=K(0))
     1058        sage: isogenies_13_0(E)
     1059        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 26*x + 12 over Finite Field of size 29, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 29 to Elliptic Curve defined by y^2 = x^3 + 16*x + 28 over Finite Field of size 29]
     1060
     1061    ::
     1062
     1063        sage: K = GF(101)                                         
     1064        sage: E = EllipticCurve(j=K(0)); E.ainvs()                 
     1065        (0, 0, 0, 0, 1)
     1066        sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
     1067        [(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)]
     1068
     1069    ::
     1070
     1071        sage: x = polygen(QQ)
     1072        sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968
     1073        sage: K.<a> = NumberField(f)     
     1074        sage: E = EllipticCurve(j=K(0)); E.ainvs()
     1075        (0, 0, 0, 0, 1)
     1076        sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
     1077        [(0, 0, 0, -739946459/23857162861049856*a^11 - 2591641747/1062017577504*a^8 + 16583647773233/4248070310016*a^5 - 14310911337/378211388*a^2, 26146225/4248070310016*a^9 + 7327668845/14750244132*a^6 + 174618431365/756422776*a^3 - 378332499709/94552847), (0, 0, 0, 3501275/5964290715262464*a^11 + 24721025/531008788752*a^8 - 47974903745/1062017577504*a^5 - 6773483100/94552847*a^2, 6699581/4248070310016*a^9 + 1826193509/14750244132*a^6 - 182763866047/756422776*a^3 - 321460597/94552847)]
     1078    """
     1079    if E.j_invariant()!=0:
     1080        raise ValueError("j-invariant must be 0.")
     1081    F = E.base_field()
     1082    if F.characteristic() in [2,3,13]:
     1083        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
     1084    Ew = E.short_weierstrass_model()
     1085    iso = E.isomorphism_to(Ew)
     1086    a = Ew.a6()
     1087    model = "minimal" if F is QQ else None
     1088    x = polygen(F)
     1089
     1090    # there will be 2 endomorphisms if -3 is a square:
     1091    ts = (x**2+3).roots(multiplicities=False)
     1092    ts.sort()
     1093    kers = [13*x**2 + (78*t + 26)*x + 24*t + 40 for t in ts]
     1094    kers = [k(x**3/a).monic() for k in kers]
     1095    isogs = [Ew.isogeny(k,model=model) for k in kers]
     1096    if len(isogs)>0:
     1097        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     1098 
     1099    # we may have up to 12 other isogenies:
     1100    ts = (x**4 + 7*x**3 + 20*x**2 + 19*x + 1).roots(multiplicities=False)
     1101    ts.sort()
     1102    for t0 in ts:
     1103        s3 = a / (6*t0**3 + 32*t0**2 + 68*t0 + 4)
     1104        ss = (x**3-s3).roots(multiplicities=False)
     1105        ss.sort()
     1106        ker = (x**6 + (20*t0**3 + 106*t0**2 + 218*t0 + 4)*x**5
     1107            + (-826*t0**3 - 4424*t0**2 - 9244*t0 - 494)*x**4
     1108            + (13514*t0**3 + 72416*t0**2 + 151416*t0 + 8238)*x**3
     1109            + (-101948*t0**3 - 546304*t0**2 - 1142288*t0 - 62116)*x**2
     1110            + (354472*t0**3 + 1899488*t0**2 + 3971680*t0 + 215960)*x
     1111            - 459424*t0**3 - 2461888*t0**2 - 5147648*t0 - 279904)
     1112        kers = [ker(x/s).monic() for s in ss]
     1113        isogs += [Ew.isogeny(k, model=model) for k in kers]
     1114   
     1115    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1116
     1117    return isogs
     1118
     1119def isogenies_13_1728(E):
     1120    """
     1121    Returns list of all 13-isogenies from E when the j-invariant is 1728.
     1122
     1123    OUTPUT:
     1124
     1125    (list) 13-isogenies with codomain E.  In general these are
     1126    normalised; but if `-1` is a square then there are two
     1127    endomorphisms of degree `13`, for which the codomain is the same
     1128    as the domain; and over `\QQ`, the codomain is a minimal model.
     1129
     1130    .. note::
     1131
     1132       This implementation requires that the characteristic is not
     1133       2, 3 or 13.
     1134
     1135    .. note::
     1136
     1137       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
     1138
     1139    EXAMPLES::
     1140
     1141        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_1728
     1142
     1143        sage: K.<i> = QuadraticField(-1)
     1144        sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs()
     1145        (0, 0, 0, i, 0)
     1146        sage: isogenies_13_1728(E)
     1147        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1,
     1148        Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1 to Elliptic Curve defined by y^2 = x^3 + i*x over Number Field in i with defining polynomial x^2 + 1]
     1149
     1150    ::
     1151
     1152        sage: K = GF(83)
     1153        sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
     1154        (0, 0, 0, 5, 0)
     1155        sage: isogenies_13_1728(E)                       
     1156        []
     1157        sage: K = GF(89)                                 
     1158        sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
     1159        (0, 0, 0, 5, 0)
     1160        sage: isogenies_13_1728(E)                       
     1161        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89,
     1162        Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89 to Elliptic Curve defined by y^2 = x^3 + 5*x over Finite Field of size 89]
     1163
     1164    ::
     1165
     1166        sage: K = GF(23)                                     
     1167        sage: E = EllipticCurve(K, [1,0])                     
     1168        sage: isogenies_13_1728(E)                           
     1169        [Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 16 over Finite Field of size 23, Isogeny of degree 13 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 23 to Elliptic Curve defined by y^2 = x^3 + 7 over Finite Field of size 23]
     1170
     1171    ::
     1172
     1173        sage: x = polygen(QQ)
     1174        sage: f = x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6 - 282896640*x^4 - 149879808*x^2 - 349360128
     1175        sage: K.<a> = NumberField(f)
     1176        sage: E = EllipticCurve(K, [1,0])
     1177        sage: [phi.codomain().ainvs() for phi in isogenies_13_1728(E)]
     1178        [(0,
     1179        0,
     1180        0,
     1181        11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
     1182        214217013065/82065216155553792*a^11 + 1217882637605/427423000810176*a^9 - 214645003230565/189965778137856*a^7 + 22973355421236025/1282269002430528*a^5 - 2059145797340695/2544184528632*a^3 - 23198483147321/989405094468*a),
     1183        (0,
     1184        0,
     1185        0,
     1186        11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
     1187        -214217013065/82065216155553792*a^11 - 1217882637605/427423000810176*a^9 + 214645003230565/189965778137856*a^7 - 22973355421236025/1282269002430528*a^5 + 2059145797340695/2544184528632*a^3 + 23198483147321/989405094468*a)]
     1188   
     1189    """
     1190    if E.j_invariant()!=1728:
     1191        raise ValueError("j-invariant must be 1728.")
     1192    F = E.base_field()
     1193    if F.characteristic() in [2, 3, 13]:
     1194        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
     1195    Ew = E.short_weierstrass_model()
     1196    iso = E.isomorphism_to(Ew)
     1197    a = Ew.a4()
     1198    model = "minimal" if F is QQ else None
     1199    x = polygen(F)
     1200
     1201    # we will have two endomorphisms if -1 is a square:
     1202    ts = (x**2+1).roots(multiplicities=False)
     1203    ts.sort()
     1204    kers = [13*x**3 + (-26*i - 13)*x**2 + (-52*i - 13)*x - 2*i - 3 for i in ts]
     1205    kers = [k(x**2/a).monic() for k in kers]
     1206    isogs = [Ew.isogeny(k,model=model) for k in kers]
     1207    if len(isogs)>0:
     1208        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     1209
     1210    # we may have up to 12 other isogenies:
     1211
     1212    ts = (x**6 + 10*x**5 + 46*x**4 + 108*x**3 + 122*x**2 + 38*x - 1).roots(multiplicities=False)
     1213    ts.sort()
     1214    for t0 in ts:
     1215        s2 = a/(66*t0**5 + 630*t0**4 + 2750*t0**3 + 5882*t0**2 + 5414*t0 + 162)
     1216        ss = (x**2-s2).roots(multiplicities=False)
     1217        ss.sort()
     1218        ker = (x**6 + (-66*t0**5 - 630*t0**4 - 2750*t0**3 - 5882*t0**2
     1219              - 5414*t0 - 162)*x**5 + (-21722*t0**5 - 205718*t0**4 -
     1220              890146*t0**3 - 1873338*t0**2 - 1652478*t0 + 61610)*x**4
     1221              + (-3391376*t0**5 - 32162416*t0**4 - 139397232*t0**3 -
     1222              294310576*t0**2 - 261885968*t0 + 6105552)*x**3 +
     1223              (-241695080*t0**5 - 2291695976*t0**4 - 9930313256*t0**3
     1224              - 20956609720*t0**2 - 18625380856*t0 + 469971320)*x**2 +
     1225              (-8085170432*t0**5 - 76663232384*t0**4 -
     1226              332202985024*t0**3 - 701103233152*t0**2 -
     1227              623190845440*t0 + 15598973056)*x - 101980510208*t0**5 -
     1228              966973468160*t0**4 - 4190156868352*t0**3 -
     1229              8843158270336*t0**2 - 7860368751232*t0 + 196854655936)
     1230       
     1231        kers = [ker(x/s).monic() for s in ss]
     1232        isogs += [Ew.isogeny(k, model=model) for k in kers]
     1233
     1234    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1235   
     1236    return isogs
     1237
     1238# List of primes l for which X_0(l) is (hyper)elliptic and X_0^+(l) has genus 0
     1239
     1240hyperelliptic_primes = [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
     1241
     1242@cached_function
     1243def _hyperelliptic_isogeny_data(l):
     1244    r"""
     1245    Helper function for elliptic curve isogenies.
     1246
     1247    INPUT:
     1248
     1249    - ``l`` -- a prime in [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
     1250
     1251    OUTPUT:
     1252
     1253    - A dict holding a collection of precomputed data needed for computing `l`-isogenies.
     1254
     1255    EXAMPLES::
     1256
     1257        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _hyperelliptic_isogeny_data
     1258        sage: HID = _hyperelliptic_isogeny_data(11)
     1259        sage: HID['A2']
     1260        55*u - 33
     1261        sage: HID['A4']
     1262        -183*u^2 + 738*u - 180*v - 135
     1263        sage: HID['A6']
     1264        1330*u^3 - 11466*u^2 + 1332*u*v + 2646*u - 1836*v + 1890
     1265        sage: HID['alpha']
     1266        u^11 - 55*u^10 + 1188*u^9 - 12716*u^8 + 69630*u^7 - 177408*u^6 + 133056*u^5 + 132066*u^4 - 187407*u^3 + 40095*u^2 + 24300*u - 6750
     1267        sage: HID['beta']
     1268        u^9 - 47*u^8 + 843*u^7 - 7187*u^6 + 29313*u^5 - 48573*u^4 + 10665*u^3 + 27135*u^2 - 12150*u
     1269        sage: HID['hyper_poly']
     1270        u^4 - 16*u^3 + 2*u^2 + 12*u - 7
     1271
     1272        sage: _hyperelliptic_isogeny_data(37)
     1273        Traceback (most recent call last):
     1274        ...
     1275        ValueError: 37 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
     1276
     1277    """
     1278    if not l in hyperelliptic_primes:
     1279        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1280    data = {}
     1281    Zu = PolynomialRing(ZZ,'u')
     1282    Zuv = PolynomialRing(ZZ,['u','v'])
     1283    Zxuv = PolynomialRing(ZZ,['x','u','v'])
     1284    x,u,v = Zxuv.gens()
     1285    if l == 11:
     1286        data['hyper_poly'] = Zu([-7, 12, 2, -16, 1])
     1287        data['A2'] = Zu([-33, 55])
     1288        data['A4'] = Zuv(Zu([-135, 738, -183])+v*Zu([-180]))
     1289        data['A6'] = Zuv(Zu([1890, 2646, -11466, 1330]) + v*Zu([-1836, 1332]))
     1290        data['alpha'] = Zu([-6750, 24300, 40095, -187407, 132066, 133056, -177408, 69630, -12716, 1188, -55, 1])
     1291        data['beta'] = Zu([0, -12150, 27135, 10665, -48573, 29313, -7187, 843, -47, 1])
     1292        #beta factors as (u - 15) * (u - 6) * (u - 3) * (u - 1) * u * (u**2 - 12*u - 9) * (u**2 - 10*u + 5)
     1293        return data
     1294    if l == 17:
     1295        data['hyper_poly'] = Zu([-8, 4, -3, -10, 1])
     1296        data['A2'] = Zu([68, -204, 136])
     1297        data['A4'] = Zuv(Zu([60, 720, -2595, 2250, -435]) + v*Zu([-360, 792, -432]))
     1298        data['A6'] = Zuv(Zu([-8512, 22608, -5064, -57528, 87288, -43704, 4912] ) + v*Zu( [2520, -15372, 28098, -20160, 4914]))
     1299        data['alpha'] = Zu([16000, -67200, 2720, 557600, -1392232, 1073992, 1104830, -3131026, 2450210, 73746, -1454945, 1110355, -424065, 95659, -13243, 1105, -51, 1])
     1300        data['beta'] = Zu([0, 22400, -105920, 146208, 111616, -593800, 680948, -102282, -457950, 468035, -219274, 58549, -9374, 889, -46, 1])
     1301        #beta factors as (u - 10) * (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 10*u + 7) * (u**2 - 6*u - 4) * (u**2 - 4*u + 2) * (u**3 - 9*u**2 + 8*u - 4)
     1302        data['endo'] = 17*x**8 + 17*(-4*u + 4)*v*x**6 + 17*(4*u + 6)*v**2*x**4 + 17*(4*u + 4)*v**3*x**2 + (-4*u + 1)*v**4
     1303        data['endo_u'] = 1
     1304        return data
     1305    if l == 19:
     1306        data['hyper_poly'] = Zu([-8, 20, -8, -8, 1])
     1307        data['A2'] = Zu([-114, 57, 171])
     1308        data['A4'] = Zuv(Zu([-1020, 444, 2733, 726, -543]) + v*Zu([-180, -720, -540]))
     1309        data['A6'] = Zuv(Zu([-10080, 21816, 54324, -37386, -86742, -20070, 6858]) + v*Zu([-2968, -13748, -11284, 6356, 6860]))
     1310        data['alpha'] = Zu([16000, -22400, -337440, 475456, 1562104, -1988616, -3025294, 3245960, 2833014, -2420087, -1140950, 932406, 129580, -180443, 21090, 11153, -4066, 570, -38, 1])
     1311        data['beta'] = Zu([0, 33600, -8160, -292400, 23472, 791244, 39282, -847909, -47024, 392654, -24046, -82469, 19162, 4833, -2652, 446, -34, 1])
     1312        #beta factors as (u - 7) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u - 4) * (u**2 - 6*u - 15) * (u**2 - 5*u - 5) * (u**2 - 5*u + 2) * (u**2 - 2*u - 4) * (u**2 + u - 1)
     1313        data['endo'] = 19*x**9 + 19*(-12*u - 24)*v*x**6 + 19*(-24*u - 24)*v**2*x**3 + (96*u - 224)*v**3
     1314        data['endo_u'] = -1
     1315        return data
     1316    if l == 23:
     1317        data['hyper_poly'] = Zu([-7, 10, -11, 2, 2, -8, 1])
     1318        data['A2'] = Zu([69, -230, 253])
     1319        data['A4'] = Zuv(Zu([405, 180, -930, 2820, -795]) + v*Zu([360, -792]))
     1320        data['A6'] = Zuv(Zu([-15498, 34020, -36918, -8120, 51114, -72492, 12166]) + v*Zu([-1080, 7704, -24840, 12168]))
     1321        data['alpha'] = Zu([-6750, 48600, -83835, -170775, 1115109, -2492280, 2732814, -116403, -4877702, 8362616, -6612454, 302266, 5423124, -6447728, 3209696, 336674, -1470068, 953856, -336927, 74221, -10465, 920, -46, 1])
     1322        data['beta'] = Zu( [0, 12150, -72495, 168588, -144045, -254034, 930982, -1256170, 604358, 693650, -1563176, 1271974, -225188, -444070, 421050, -184350, 47754, -7696, 759, -42, 1])
     1323        #beta factors as (u - 5) * (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 3) * (u**2 - 6*u - 9) * (u**3 - 7*u**2 + 3*u - 5) * (u**3 - 7*u**2 + 7*u - 3) * (u**4 - 4*u**3 - 1)
     1324        return data
     1325    if l == 29:
     1326        data['hyper_poly'] = Zu([-7, 8, 8, 2, -12, -4, 1])
     1327        data['A2'] = Zu([-174, -232, 348, 406])
     1328        data['A4'] = Zuv(Zu([-1215, -3096, 132, 7614, 6504, -360, -1263] ) + v*Zu( [180, -720, -2160, -1260]))
     1329        data['A6'] = Zuv(Zu([-18900, -63504, 24696, 285068, 285264, -185136, -506268, -275520, 504, 24388] ) + v*Zu( [4482, -2448, -59868, -94968, -18144, 48276, 24390]))
     1330        data['alpha'] = Zu([-6750, -12150, 281880, 570024, -1754181, -5229135, 2357613, 19103721, 9708910, -31795426, -38397537, 19207947, 54103270, 9216142, -37142939, -18871083, 14041394, 10954634, -3592085, -3427365, 853818, 622398, -189399, -53679, 26680, -580, -1421, 319, -29, 1])
     1331        data['beta'] = Zu([0, -24300, -57510, 257850, 839187, -373185, -3602119, -2371192, 5865017, 8434433, -2363779, -10263744, -2746015, 5976011, 3151075, -2093854, -1356433, 569525, 299477, -129484, -28279, 19043, -895, -1076, 273, -27, 1])
     1332        #beta factors as (u - 3) * (u - 1) * u * (u + 1) * (u + 2) * (u**2 - 6*u + 2) * (u**2 - 5*u - 5) * (u**2 - 5*u + 3) * (u**2 - 3*u - 9) * (u**2 - u - 3) * (u**2 - u - 1) * (u**2 + u - 1) * (u**3 - 4*u**2 - 6*u - 5) * (u**4 - 2*u**3 - 5*u**2 - 4*u - 1)
     1333        data['endo'] = 29*x**14 + 29*(-14*u + 3)*v*x**12 + 29*(-20*u + 73)*v**2*x**10 + 29*(-58*u + 115)*v**3*x**8 + 29*(-56*u + 59)*v**4*x**6 + 29*(30*u + 1)*v**5*x**4 + 29*(12*u - 5)*v**6*x**2 + (2*u + 5)*v**7
     1334        data['endo_u'] = -1
     1335        return data
     1336    if l == 31:
     1337        data['hyper_poly'] = Zu([-3, -14, -11, 18, 6, -8, 1])
     1338        data['A2'] = Zu([558, 837, -1488, 465])
     1339        data['A4'] = Zuv(Zu([-4140, -12468, 15189, 16956, -27054, 11184, -1443]) + v*Zu([2160, -7560, 6120, -1440]))
     1340        data['A6'] = Zuv(Zu([71280, 592056, -108324, -2609730, 2373048, 1282266, -2793204, 1530882, -356976, 29790]) + v*Zu([-81312, 181664, 294728, -868392, 701400, -238840, 29792]))
     1341        data['alpha'] = Zu([108000, 475200, -7053120, -27353408, 90884374, 303670296, -665806437, -1361301729, 3259359840, 2249261823, -9368721606, 2279583264, 13054272515, -12759480061, -4169029296, 14390047139, -7803693550, -2988803682, 6239473912, -3296588360, 134066754, 908915598, -685615437, 294482733, -87483178, 18983315, -3052818, 361336, -30659, 1767, -62, 1])
     1342        data['beta'] = Zu([0, 712800, 1216080, -18430560, -15262464, 168899202, -12931221, -720077416, 624871714, 1239052988, -2259335558, 68648452, 2679085427, -2318039014, -229246628, 1710545918, -1243026758, 211524870, 296674626, -291810274, 145889932, -48916468, 11793961, -2085662, 269348, -24778, 1540, -58, 1])
     1343        #beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 8*u + 11) * (u**2 - 7*u + 2) * (u**2 - 5*u - 2) * (u**2 - 5*u + 5) * (u**2 - 4*u - 4) * (u**2 - 4*u - 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 9*u**2 + 21*u - 15) * (u**4 - 8*u**3 + 8*u**2 + 12*u - 9)
     1344        data['endo'] = 31*x**15 + 31*(-66*u + 86)*v*x**12 + 31*(168*u + 280)*v**2*x**9 + 31*(576*u + 1792)*v**3*x**6 + 31*(384*u + 896)*v**4*x**3 + (-3072*u - 2048)*v**5
     1345        data['endo_u'] = 2
     1346        return data
     1347    if l == 41:
     1348        data['hyper_poly'] = Zu([-8, -20, -15, 8, 20, 10, -8, -4, 1])
     1349        data['A2'] = Zu([328, 656, -656, -1148, 820])
     1350        data['A4'] = Zuv(Zu([-1380, -4008, 1701, 10872, 6144, -18378, -2160, 9732, -2523]) + v*Zu([720, -1440, -2160, 5400, -2520]))
     1351        data['A6'] = Zuv(Zu([4480, 155616, 16080, -550720, -343968, 832680, 938632, -621648, -1468608, 953920, 427632, -413016, 68920]) + v*Zu([-14616, 6804, 96390, -2016, -324324, 184464, 260568, -276192, 68922]))
     1352        data['alpha'] = Zu([16000, 67200, -465760, -2966432, -1742664, 20985112, 46140990, -31732934, -217030548, -147139488, 436080674, 745775322, -271341362, -1542677562, -605560447, 1832223375, 1772593672, -1270633050, -2400692229, 343522723, 2179745361, 282422801, -1503727029, -421357697, 879637411, 261059095, -462271351, -61715127, 193718727, -24135265, -49355103, 20512341, 3613289, -4706595, 1099661, 163057, -162483, 46617, -7544, 738, -41, 1])
     1353        data['beta'] = Zu([0, 44800, 167040, -447040, -2734272, -1104272, 13488360, 21067652, -24681704, -83929974, -8986886, 169059382, 127641266, -196479899, -283039783, 124573790, 366614063, -12946368, -332987597, -58867672, 241909907, 60568430, -155045647, -17919564, 79114945, -12025938, -24060781, 11190142, 1979597, -2931764, 750233, 110144, -122263, 37484, -6439, 666, -39, 1])
     1354        #beta factors as (u - 5) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u - 7) * (u**2 - 2*u - 4) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**2 - 2) * (u**2 + u - 1) * (u**3 - 3*u**2 - 5*u - 2) * (u**3 - 2*u**2 - 2*u - 1) * (u**4 - 6*u**3 + 5*u**2 + 2*u - 1) * (u**4 - 5*u**3 + u**2 + 4) * (u**4 - 4*u**3 + 2)
     1355        data['endo'] = 41*x**20 + 41*(-12*u - 22)*v*x**18 + 41*(-252*u - 247)*v**2*x**16 + 41*(-176*u - 424)*v**3*x**14 + 41*(464*u - 254)*v**4*x**12 + 41*(1688*u - 868)*v**5*x**10 + 41*(1720*u - 1190)*v**6*x**8 + 41*(528*u - 232)*v**7*x**6 + 41*(16*u + 29)*v**8*x**4 + 41*(20*u + 10)*v**9*x**2 + (4*u + 5)*v**10
     1356        data['endo_u'] = 1
     1357        return data
     1358    if l == 47:
     1359        data['hyper_poly'] = Zu([-11, 28, -38, 30, -13, -16, 19, -24, 11, -6, 1])
     1360        data['A2'] = Zu([376, -1504, 2209, -1598, 1081])
     1361        data['A4'] = Zuv(Zu([2400, -4080, -1440, 18000, -26355, 34740, -22050, 12900, -3315]) + v*Zu([1152, -3384, 3672, -3312]))
     1362        data['A6'] = Zuv(Zu([-119504, 606336, -1505280, 2109392, -1509360, -515808, 2920702, -4614012, 4334322, -3260312, 1571442, -622428, 103822]) + v*Zu([2016, 48384, -235872, 438984, -627480, 503496, -311976, 103824]))
     1363        data['alpha'] = Zu([-65536, 688128, -2502656, -96256, 38598656, -187217920, 508021120, -845669120, 552981696, 1469334304, -5945275904, 11705275552, -14673798654, 9100068184, 8421580132, -34288012648, 56657584158, -60426283952, 36612252089, 9942017442, -60791892299, 93046207239, -92028642340, 59196883097, -10454018992, -33364599371, 57280402355, -57873890484, 41879296232, -20241250112, 2065827049, 8435506655, -11611941072, 10182603298, -7040645261, 4071881378, -2013138357, 856757031, -313468474, 97893151, -25770006, 5617769, -990431, 136864, -14194, 1034, -47, 1])
     1364        data['beta'] = Zu([0, 114688, -1114112, 4854784, -11205632, 7426048, 42663936, -182555136, 394092544, -508851472, 213245648, 743315936, -2203729384, 3409478688, -3280008936, 1139839970, 2576264698, -6272528962, 8005203155, -6671665088, 2744569094, 1996771588, -5520074039, 6637395180, -5455622885, 3028415830, -601645255, -1012737914, 1632999370, -1525982346, 1093778952, -644352392, 319489974, -134176208, 47566499, -14083902, 3424200, -667810, 101271, -11438, 901, -44, 1])
     1365        #beta factors as (u - 4) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 2) * (u**2 - 2*u - 1) * (u**3 - 5*u**2 + 5*u - 7) * (u**3 - 4*u**2 + 3*u - 4) * (u**3 - 4*u**2 + 3*u - 1) * (u**3 - 3*u**2 + 2*u - 4) * (u**3 - 2*u**2 + 2*u - 2) * (u**3 + u + 1) * (u**4 - 4*u**3 - 2*u**2 - 4) * (u**5 - 5*u**4 + 5*u**3 - 11*u**2 + 6*u - 4) * (u**6 - 4*u**5 + 2*u**4 - 4*u**3 - u**2 + 4*u - 2)
     1366        return data
     1367    if l == 59:
     1368        data['hyper_poly'] = Zu([-8, -4, 20, -24, -3, 40, -62, 40, 3, -28, 22, -8, 1])
     1369        data['A2'] = Zu([590, -1475, -295, 4130, -4425, 1711])
     1370        data['A4'] = Zuv(Zu([-2460, 8844, -3843, -20718, 57153, -50418, -12600, 72762, -69339, 30978, -5223]) + v*Zu([900, 360, -7560, 10800, -5220]))
     1371        data['A6'] = Zuv(Zu([25760, -373560, 568020, 1147870, -4634370, 5318070, 1631996, -14270202, 21535998, -14119408, -2820102, 14275410, -13535292, 6790074, -1847898, 205378]) + v*Zu([-23688, 27972, 183708, -696024, 721980, 453600, -1925028, 2039184, -1027404, 205380]))
     1372        data['alpha'] = Zu([16000, -67200, -783520, 5573376, -5127336, -60792184, 241324042, -170978932, -1262437160, 4310971231, -3953349811, -10887235780, 41679530185, -51342089572, -33068562195, 230682514316, -372641172307, 121615007703, 682044179678, -1549365239197, 1373184591667, 614906882627, -3566756201696, 4920423266916, -2342393877496, -3589340274442, 8772457933356, -8488557160148, 1742977715620, 7131088674129, -11643540780203, 8512399456274, -315658868113, -6917286294515, 8713332734648, -5190227733987, -54249978263, 3397583328372, -3658171840037, 1987950394792, -179519591637, -748989116551, 800595050760, -459184355769, 134398080099, 28871590941, -64236756338, 46651654354, -23352309386, 9059054346, -2830320860, 721829600, -150487052, 25475079, -3452149, 365800, -29205, 1652, -59, 1])
     1373        data['beta'] = Zu([0, -56000, 320800, 391440, -7693120, 21125500, 11515130, -204780145, 486681785, -102547033, -2147060784, 5552726794, -4419031758, -9431888681, 33728080307, -42367773552, -2994127157, 105330637610, -188172973931, 127559513693, 123083802224, -421097252069, 490425751691, -161944881372, -408669953969, 799965143719, -668167261718, 69589638764, 563644022562, -787681290965, 505670881115, 2900924856, -364669742737, 407962360532, -223582547975, 9985786664, 102435489491, -105519055992, 58212400117, -14331637533, -6742538722, 10205452686, -6853903214, 3244679736, -1188153136, 347102566, -81626216, 15409226, -2307408, 268126, -23322, 1429, -55, 1])
     1374        #beta factors as (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 4*u - 1) * (u**2 - 3*u - 5) * (u**2 - 3*u - 2) * (u**2 - 3*u + 1) * (u**2 - u - 1) * (u**3 - 6*u**2 + 10*u - 7) * (u**3 - 5*u**2 + 7*u - 5) * (u**3 - 3*u**2 + 2*u - 1) * (u**3 - u**2 + 1) * (u**4 - 5*u**3 + 4*u**2 - 1) * (u**4 - 4*u**3 + 3*u**2 + 2*u - 4) * (u**4 - 3*u**3 - u - 1) * (u**4 - u**3 + 2*u - 1) * (u**5 - 6*u**4 + 10*u**3 - 11*u**2 + 8*u - 4) * (u**6 - 5*u**5 + 5*u**4 - 5*u**2 + 5*u - 5)
     1375        return data
     1376    if l == 71:
     1377        data['hyper_poly'] = Zu([-7, 6, -27, 40, -58, 66, -66, 40, 15, -48, 66, -66, 37, -10, 1])
     1378        data['A2'] = Zu([213, -1420, 4260, -4970, 9940, -9088, 2485])
     1379        data['A4'] = Zuv(Zu([2565, -10008, 18024, -26532, 23208, 7584, -104418, 189432, -251736, 275148, -182232, 60144, -7563]) + v*Zu([720, -4320, 7560, -20160, 23040, -7560]))
     1380        data['A6'] = Zuv(Zu([-69930, 382536, -1898568, 5206124, -11813256, 23115792, -35705670, 44318064, -41531952, 20674360, 23881872, -77986944, 114989770, -124612152, 103122936, -59431204, 21485688, -4294416, 357910]) + v*Zu([18576, -53856, 57672, 161856, -961920, 3199176, -5706288, 8032896, -9352584, 6786720, -2505888, 357912]))
     1381        data['alpha'] = Zu([-6750, 97200, -603855, 2263977, -4854483, -2486349, 75190491, -399596520, 1441975423, -4089818964, 9450153463, -17516526653, 23635982289, -11859874932, -53385529273, 230566737711, -585283867605, 1136695427037, -1753961304140, 2020891913264, -1147488305875, -1930304898882, 8102336330029, -17218530732347, 27006964902986, -32365758791872, 25902000374138, -468390635342, -46332664858222, 107139839089502, -162234735929274, 182582147217312, -140033523896938, 22513210292184, 152367877270246, -334009986053250, 451855980915164, -443144048889720, 284518400252142, -11142427766850, -289840331821002, 512373447321402, -576967281819172, 466024421705696, -230395084854230, -36287337331916, 241209603962570, -330646545417814, 304702155703516, -205131886553392, 87504290135653, 5131997859077, -54867900326127, 66216047255551, -54817285755105, 36239054778472, -20052219750661, 9464634765852, -3841191816845, 1343947848527, -405138280373, 104923131180, -23228729413, 4364552115, -689157169, 90223321, -9613968, 812240, -52327, 2414, -71, 1])
     1382        data['beta'] = Zu([0, 12150, -163215, 1115640, -5311143, 18820224, -50700172, 99823812, -102454041, -183909134, 1354660714, -4462311942, 10695310224, -20015395554, 28262441676, -23240987282, -17879387475, 124501604946, -315187724212, 564766450688, -765154573538, 705985549104, -115433273216, -1206098873334, 3175185881748, -5228317292044, 6292310032120, -5077451367560, 719644756530, 6451571564682, -14460150103020, 19999710623352, -19681838601268, 11819712227412, 2180981559572, -17790742756618, 29025463386612, -31179247603548, 23207078145510, -8345354986332, -7468523752270, 18486966963350, -21719818051100, 17831212433536, -10100011266030, 2336962513536, 2906983627184, -4989755986066, 4711466210012, -3361479243242, 1952316811463, -948555371584, 389878900245, -136099552242, 40341734984, -10121407164, 2136756509, -376218102, 54551634, -6399080, 591884, -41538, 2078, -66, 1])
     1383        #beta factors as (u - 3) * (u - 2) * (u - 1) * u * (u + 1) * (u**2 - 5*u + 5) * (u**2 - 3*u + 1) * (u**2 - 2*u - 1) * (u**2 - u - 1) * (u**3 - 5*u**2 + 5*u - 3) * (u**3 - 4*u**2 - 1) * (u**3 - 2*u**2 - 1) * (u**4 - 6*u**3 + 7*u**2 + 6*u - 9) * (u**4 - 5*u**3 + 4*u**2 + u + 3) * (u**4 - 5*u**3 + 6*u**2 - 3*u + 5) * (u**4 - 4*u**3 + u**2 - 4*u + 1) * (u**4 - 4*u**3 + 2*u**2 - u + 1) * (u**4 - 2*u**3 - 3*u**2 - 2*u - 1) * (u**4 - 2*u**3 + u - 1) * (u**6 - 5*u**5 + 8*u**4 - 7*u**3 + 6*u**2 - 3*u + 1) * (u**8 - 6*u**7 + 9*u**6 - 2*u**5 + 2*u**3 - 9*u**2 + 2*u - 1)
     1384        return data
     1385
     1386@cached_function
     1387def Psi2(l):
     1388    """
     1389    Returns the generic kernel polynomial for hyperelliptic `l`-isogenies.
     1390
     1391    INPUT:
     1392
     1393    - ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1394
     1395    OUTPUT:
     1396
     1397    The generic `l`-kernel polynomial.
     1398
     1399    TESTS::
     1400
     1401        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
     1402        sage: Psi2(11)
     1403        x^5 - 55*x^4*u + 994*x^3*u^2 - 8774*x^2*u^3 + 41453*x*u^4 - 928945/11*u^5 + 33*x^4 + 276*x^3*u - 7794*x^2*u^2 + 4452*x*u^3 + 1319331/11*u^4 + 216*x^3*v - 4536*x^2*u*v + 31752*x*u^2*v - 842616/11*u^3*v + 162*x^3 + 38718*x^2*u - 610578*x*u^2 + 33434694/11*u^3 - 4536*x^2*v + 73872*x*u*v - 2745576/11*u^2*v - 16470*x^2 + 580068*x*u - 67821354/11*u^2 - 185976*x*v + 14143896/11*u*v + 7533*x - 20437029/11*u - 12389112/11*v + 19964151/11
     1404
     1405    """
     1406    if not l in hyperelliptic_primes:
     1407        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1408
     1409    data = _hyperelliptic_isogeny_data(l)
     1410    R = PolynomialRing(QQ,['x','u'])
     1411    x, u = R.gens()
     1412    L = PolynomialRing(R,'y')
     1413    y = L.gen()
     1414    K = R.extension(y**2-R(data['hyper_poly']),name = 'v')
     1415    v = K.gen()
     1416    from sage.categories.homset import Hom
     1417    h = Hom(K,K)(-v)
     1418
     1419    A = K(data['A4'])
     1420    B = K(data['A6'])
     1421    Abar = h(A)*l**2
     1422    Bbar = -h(B)*l**3
     1423    s1 = K(data['A2'])
     1424
     1425    d = (l-1)//2
     1426    s = [1]
     1427    t = [d,s1,((1-10*d)*A - Abar)*(1/QQ(30))]
     1428    t += [((1-28*d)*B - 42*t[1]*A - Bbar)*(1/QQ(70))]
     1429    c = [0,6*t[2] + 2*A*t[0],10*t[3] + 6*A*t[1] + 4*B*t[0]]
     1430    for n in range(2,d):
     1431        k = sum(c[i]*c[n-i] for i in range(1,n))
     1432        c += [(3*k-(2*n-1)*(n-1)*A*c[n-1]-(2*n-2)*(n-2)*B*c[n-2])*(1/QQ((n-1)*(2*n+5)))]
     1433    for n in range(3,d):
     1434        t += [(c[n]-(4*n-2)*A*t[n-1]-(4*n-4)*B*t[n-2])*(1/QQ(4*n+2))]
     1435    for n in range(1,d+1):
     1436        s += [(-1/QQ(n))*sum((-1)**i*t[i]*s[n-i] for i in range(1,n+1))]
     1437    psi = sum((-1)**i*s[i]*x**(d-i) for i in range(0,d+1))
     1438    R = PolynomialRing(QQ,['x','u','v'])
     1439    return R(psi)
     1440
     1441
     1442def isogenies_prime_degree_genus_plus_0(E, l=None):
     1443    """
     1444    Returns list of ``l`` -isogenies with domain ``E``.
     1445
     1446    INPUT:
     1447
     1448    - ``E`` -- an elliptic curve.
     1449
     1450    - ``l`` -- either None or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1451
     1452    OUTPUT:
     1453
     1454    (list) When ``l`` is None a list of all isogenies of degree 11, 17, 19, 23,
     1455    29, 31, 41, 47, 59, or 71, otherwise a list of isogenies of the given degree.
     1456
     1457    .. note::
     1458
     1459       This function would normally be invoked indirectly via
     1460       ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate function.
     1461
     1462    ALGORITHM::
     1463
     1464    See [KT2013]_, Chapter 5.
     1465
     1466    EXAMPLES::
     1467
     1468        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0
     1469
     1470        sage: E = EllipticCurve('121a1')
     1471        sage: isogenies_prime_degree_genus_plus_0(E, 11)
     1472        [Isogeny of degree 11 from Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 30*x - 76 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 305*x + 7888 over Rational Field]
     1473
     1474        sage: E = EllipticCurve([1, 1, 0, -660, -7600])
     1475        sage: isogenies_prime_degree_genus_plus_0(E, 17)
     1476        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 660*x - 7600 over Rational Field to Elliptic Curve defined by y^2 + x*y = x^3 + x^2 - 878710*x + 316677750 over Rational Field]
     1477
     1478        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1479        sage: isogenies_prime_degree_genus_plus_0(E, 19)
     1480        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
     1481
     1482        sage: K = QuadraticField(-295,'a')
     1483        sage: a = K.gen()
     1484        sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216)
     1485        sage: isogenies_prime_degree_genus_plus_0(E, 23)
     1486        [Isogeny of degree 23 from Elliptic Curve defined by y^2 = x^3 + (-14460494784192904095/140737488355328*a+270742665778826768325/140737488355328)*x + (37035998788154488846811217135/590295810358705651712*a-1447451882571839266752561148725/590295810358705651712) over Number Field in a with defining polynomial x^2 + 295 to Elliptic Curve defined by y^2 = x^3 + (-5130542435555445498495/140737488355328*a+173233955029127361005925/140737488355328)*x + (-1104699335561165691575396879260545/590295810358705651712*a+3169785826904210171629535101419675/590295810358705651712) over Number Field in a with defining polynomial x^2 + 295]
     1487
     1488        sage: K = QuadraticField(-199,'a')
     1489        sage: a = K.gen()
     1490        sage: E = EllipticCurve_from_j(94743000*a + 269989875)
     1491        sage: isogenies_prime_degree_genus_plus_0(E, 29)
     1492        [Isogeny of degree 29 from Elliptic Curve defined by y^2 = x^3 + (-153477413215038000*a+5140130723072965125)*x + (297036215130547008455526000*a+2854277047164317800973582250) over Number Field in a with defining polynomial x^2 + 199 to Elliptic Curve defined by y^2 = x^3 + (251336161378040805000*a-3071093219933084341875)*x + (-8411064283162168580187643221000*a+34804337770798389546017184785250) over Number Field in a with defining polynomial x^2 + 199]
     1493
     1494        sage: K = QuadraticField(253,'a')
     1495        sage: a = K.gen()
     1496        sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000)
     1497        sage: isogenies_prime_degree_genus_plus_0(E, 31)
     1498        [Isogeny of degree 31 from Elliptic Curve defined by y^2 = x^3 + (4146345122185433034677956608000*a-65951656549965037259634800640000)*x + (-18329111516954473474583425393698245080252416000*a+291542366110383928366510368064204147260129280000) over Number Field in a with defining polynomial x^2 - 253 to Elliptic Curve defined by y^2 = x^3 + (200339763852548615776123686912000*a-3186599019027216904280948275200000)*x + (7443671791411479629112717260182286294850207744000*a-118398847898864757209685951728838895495168655360000) over Number Field in a with defining polynomial x^2 - 253]
     1499
     1500        sage: E = EllipticCurve_from_j(GF(5)(1))
     1501        sage: isogenies_prime_degree_genus_plus_0(E, 41)
     1502        [Isogeny of degree 41 from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5, Isogeny of degree 41 from Elliptic Curve defined by y^2 = x^3 + x + 2 over Finite Field of size 5 to Elliptic Curve defined by y^2 = x^3 + x + 3 over Finite Field of size 5]
     1503
     1504        sage: K = QuadraticField(5,'a')
     1505        sage: a = K.gen()
     1506        sage: E = EllipticCurve_from_j(184068066743177379840*a - 411588709724712960000)
     1507        sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time (4.3s)
     1508        [Isogeny of degree 47 from Elliptic Curve defined by y^2 = x^3 + (454562028554080355857852049849975895490560*a-1016431595837124114668689286176511361024000)*x + (-249456798429896080881440540950393713303830363999480904280965120*a+557802358738710443451273320227578156598454035482869042774016000) over Number Field in a with defining polynomial x^2 - 5 to Elliptic Curve defined by y^2 = x^3 + (39533118442361013730577638493616965245992960*a-88398740199669828340617478832005245173760000)*x + (214030321479466610282320528611562368963830105830555363061803253760*a-478586348074220699687616322532666163722004497458452316582576128000) over Number Field in a with defining polynomial x^2 - 5]
     1509
     1510        sage: K = QuadraticField(-66827,'a')
     1511        sage: a = K.gen()
     1512        sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000)
     1513        sage: isogenies_prime_degree_genus_plus_0(E, 59)   # long time (25s, 2012)
     1514        [Isogeny of degree 59 from Elliptic Curve defined by y^2 = x^3 + (2605886146782144762297974784000*a+1893681048912773634944634716160000)*x + (-116918454256410782232296183198067568744071168000*a+17012043538294664027185882358514011304812871680000) over Number Field in a with defining polynomial x^2 + 66827 to Elliptic Curve defined by y^2 = x^3 + (-19387084027159786821400775098368000*a-4882059104868154225052787156713472000)*x + (-25659862010101415428713331477227179429538847260672000*a-2596038148441293485938798119003462972840818381946880000) over Number Field in a with defining polynomial x^2 + 66827]
     1515
     1516        sage: E = EllipticCurve_from_j(GF(13)(5))
     1517        sage: isogenies_prime_degree_genus_plus_0(E, 71) # long time
     1518        [Isogeny of degree 71 from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13, Isogeny of degree 71 from Elliptic Curve defined by y^2 = x^3 + x + 4 over Finite Field of size 13 to Elliptic Curve defined by y^2 = x^3 + 10*x + 7 over Finite Field of size 13]
     1519
     1520        sage: E = EllipticCurve(GF(13),[0,1,1,1,0])
     1521        sage: isogenies_prime_degree_genus_plus_0(E)
     1522        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 1 over Finite Field of size 13,
     1523        Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
     1524        Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 6 over Finite Field of size 13,
     1525        Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13,
     1526        Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 4 over Finite Field of size 13,
     1527        Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 5*x + 6 over Finite Field of size 13]
     1528
     1529    """
     1530    if l is None:
     1531        return sum([isogenies_prime_degree_genus_plus_0(E, l) for l in hyperelliptic_primes],[])
     1532
     1533    if not l in hyperelliptic_primes:
     1534        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1535
     1536    F = E.base_ring()
     1537    j = E.j_invariant()
     1538    if F.characteristic() in [2, 3, l]:
     1539        raise NotImplementedError("11, 17, 19, 23, 29, 31, 41, 47, 59, and 71-isogenies are not yet implemented in characteristic 2 and 3, and when the characteristic is the same as the degree of the isogeny.")
     1540
     1541    if j == F(0):
     1542        return isogenies_prime_degree_genus_plus_0_j0(E, l)
     1543    if j == F(1728):
     1544        return isogenies_prime_degree_genus_plus_0_j1728(E, l)
     1545
     1546    Fu = PolynomialRing(F,'u')
     1547    u = Fu.gen()
     1548    Fuv = PolynomialRing(F,['u','v'])
     1549    Fxuv = PolynomialRing(F,['x','u','v'])
     1550    X = u
     1551    data = _hyperelliptic_isogeny_data(l)
     1552    a = Fu(data['alpha'])
     1553    b = Fu(data['beta'])
     1554    f = Fu(data['hyper_poly'])
     1555    P = a
     1556    Q = Fu((a**2 - f*b**2)/Fu(4))
     1557    u_list = (j**2-P*j+Q).roots(multiplicities=False)
     1558
     1559    S = []
     1560    for u0 in u_list:
     1561        if b(u0) == 0:
     1562            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1563        else:
     1564            S += [[u0,(2*j-a(u0))/b(u0)]]
     1565    if len(S) == 0:
     1566        return []
     1567    S.sort()
     1568
     1569    c4, c6 = E.c_invariants()
     1570    b2 = E.b2()
     1571    kernels = []
     1572
     1573    psi = Fxuv(Psi2(l))
     1574    for u0, v0 in S:
     1575        A4 = Fuv(data['A4'])(u0,v0) #non-zero since j!=0
     1576        A6 = Fuv(data['A6'])(u0,v0) #non-zero since j!=1728
     1577        T = (c4*A6)/(2*c6*A4)
     1578        kernels += [psi((36*X+3*b2)*T,u0,v0).monic()]
     1579    return [E.isogeny(ker) for ker in kernels]
     1580
     1581
     1582
     1583def isogenies_prime_degree_genus_plus_0_j0(E, l):
     1584    """
     1585    Returns a list of hyperelliptic ``l`` -isogenies  with domain ``E`` when `j(E)=0`.
     1586
     1587    INPUT:
     1588
     1589    - ``E`` -- an elliptic curve with j-invariant 0.
     1590
     1591    - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1592
     1593    OUTPUT:
     1594
     1595    (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1596
     1597    .. note::
     1598
     1599       This implementation requires that the characteristic is not 2, 3 or ``l``.
     1600
     1601    .. note::
     1602
     1603       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
     1604
     1605    EXAMPLES::
     1606
     1607        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j0
     1608
     1609        sage: u = polygen(QQ)
     1610        sage: K.<a> = NumberField(u^4+228*u^3+486*u^2-540*u+225)
     1611        sage: E = EllipticCurve(K,[0,-121/5*a^3-20691/5*a^2-29403/5*a+3267])
     1612        sage: isogenies_prime_degree_genus_plus_0_j0(E,11)
     1613        [Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 to Elliptic Curve defined by y^2 = x^3 + (-44286*a^2+178596*a-32670)*x + (-17863351/5*a^3+125072739/5*a^2-74353653/5*a-682803) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225, Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-121/5*a^3-20691/5*a^2-29403/5*a+3267) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225 to Elliptic Curve defined by y^2 = x^3 + (-3267*a^3-740157*a^2+600039*a-277695)*x + (-17863351/5*a^3-4171554981/5*a^2+3769467867/5*a-272366523) over Number Field in a with defining polynomial x^4 + 228*x^3 + 486*x^2 - 540*x + 225]
     1614
     1615        sage: E = EllipticCurve(GF(5^6,'a'),[0,1])
     1616        sage: isogenies_prime_degree_genus_plus_0_j0(E,17)
     1617        [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 5^6 to Elliptic Curve defined by y^2 = x^3 + 2 over Finite Field in a of size 5^6]
     1618    """
     1619    if not l in hyperelliptic_primes:
     1620        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1621    F = E.base_field()
     1622    if E.j_invariant() != 0:
     1623        raise ValueError,("j-invariant must be 0.")
     1624    if F.characteristic() in [2,3,l]:
     1625        raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
     1626
     1627    Fu = PolynomialRing(F,'u')
     1628    u = Fu.gen()
     1629    Fuv = PolynomialRing(F,['u','v'])
     1630    Fxuv = PolynomialRing(F,['x','u','v'])
     1631    X = u
     1632    data = _hyperelliptic_isogeny_data(l)
     1633    a = Fu(data['alpha'])
     1634    b = Fu(data['beta'])
     1635    f = Fu(data['hyper_poly'])
     1636    Q = Fu((a**2 - f*b**2)/Fu(4))
     1637    u_list = Q.roots(multiplicities=False)
     1638    c6, b2 = E.c6(), E.b2()
     1639    kernels = []
     1640
     1641    if l % 3 == 1 and F(-3).is_square():
     1642        p = F(-3).sqrt()
     1643        endo = Fxuv(data['endo'])
     1644        kernels += [endo(36*X+3*b2,p,-54*c6).monic(), endo(36*X+3*b2,-p,-54*c6).monic()]
     1645
     1646    S = []
     1647    for u0 in u_list:
     1648        if l % 3 == 1 and u0 == F(data['endo_u']):
     1649            continue
     1650        if b(u0) == 0:
     1651            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1652        else:
     1653            S += [[u0,-a(u0)/b(u0)]]
     1654    if len(S)==0 and len(kernels) == 0:
     1655        return []
     1656    S.sort()
     1657
     1658    psi = Fxuv(Psi2(l))
     1659    for u0,v0 in S:
     1660        A6 = Fuv(data['A6'])(u0,v0) # non-zero since j!=1728
     1661        kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**3-A6/(-54*c6)).roots(multiplicities=False)]
     1662    return [E.isogeny(ker) for ker in kernels]
     1663
     1664def isogenies_prime_degree_genus_plus_0_j1728(E, l):
     1665    """
     1666    Returns a list of ``l`` -isogenies  with domain ``E`` when `j(E)=1728`.
     1667
     1668    INPUT:
     1669
     1670    - ``E`` -- an elliptic curve with j-invariant 1728.
     1671
     1672    - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. 
     1673
     1674    OUTPUT:
     1675
     1676    (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1677
     1678    .. note::
     1679
     1680       This implementation requires that the characteristic is not 2, 3 or ``l``.
     1681
     1682    .. note::
     1683
     1684       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
     1685
     1686    EXAMPLES::
     1687
     1688        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j1728
     1689
     1690        sage: u = polygen(QQ)
     1691        sage: K.<a> = NumberField(u^6 - 522*u^5 - 10017*u^4 + 2484*u^3 - 5265*u^2 + 12150*u - 5103)
     1692        sage: E = EllipticCurve(K,[-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356,0])
     1693        sage: isogenies_prime_degree_genus_plus_0_j1728(E,11)
     1694        [Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 to Elliptic Curve defined by y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + (-3540460*a^3+30522492*a^2-7043652*a-5031180) over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103, Isogeny of degree 11 from Elliptic Curve defined by y^2 = x^3 + (-75295/1335852*a^5+13066735/445284*a^4+44903485/74214*a^3+17086861/24738*a^2+11373021/16492*a-1246245/2356)*x over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103 to Elliptic Curve defined by y^2 = x^3 + (9110695/1335852*a^5-1581074935/445284*a^4-5433321685/74214*a^3-3163057249/24738*a^2+1569269691/16492*a+73825125/2356)*x + (3540460*a^3-30522492*a^2+7043652*a+5031180) over Number Field in a with defining polynomial x^6 - 522*x^5 - 10017*x^4 + 2484*x^3 - 5265*x^2 + 12150*x - 5103]
     1695    """
     1696    if not l in  hyperelliptic_primes:
     1697        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1698    F = E.base_ring()
     1699    if E.j_invariant() != 1728:
     1700        raise ValueError("j-invariant must be 1728.")
     1701    if F.characteristic() in [2,3,l]:
     1702        raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
     1703
     1704    Fu = PolynomialRing(F,'u')
     1705    u = Fu.gen()
     1706    Fuv = PolynomialRing(F,['u','v'])
     1707    Fxuv = PolynomialRing(F,['x','u','v'])
     1708    X = u
     1709    data = _hyperelliptic_isogeny_data(l)
     1710    a = Fu(data['alpha'])
     1711    b = Fu(data['beta'])
     1712    f = Fu(data['hyper_poly'])
     1713    P = a
     1714    Q = Fu((a**2 - f*b**2)/Fu(4))
     1715    u_list = (1728**2-P*1728+Q).roots(multiplicities=False)
     1716    c4, b2 = E.c4(), E.b2()
     1717    kernels = []
     1718
     1719    if l % 4 == 1 and  F(-1).is_square():
     1720        i = F(-1).sqrt()
     1721        endo = Fxuv(data['endo'])
     1722        kernels += [endo(X,i,-27*c4).monic(), endo(X,-i,-27*c4).monic()]
     1723
     1724    S = []
     1725    for u0 in u_list:
     1726        if l % 4 == 1 and u0 == F(data['endo_u']):
     1727            continue
     1728        if b(u0) == 0:
     1729            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1730        else:
     1731            S += [[u0,(2*1728-a(u0))/b(u0)]]
     1732    if len(S)==0 and len(kernels) == 0:
     1733        return []
     1734    S.sort()
     1735
     1736    psi = Fxuv(Psi2(l))
     1737    for u0,v0 in S:
     1738        A4 = Fuv(data['A4'])(u0,v0) # non-zero since j!=0
     1739        kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**2-A4/(-27*c4)).roots(multiplicities=False)]
     1740    return [E.isogeny(ker) for ker in kernels]
     1741
     1742@cached_function
     1743def _least_semi_primitive(p):
     1744    """
     1745    Returns the smallest semi-primitive root modulo `p`, i.e., generator of the group `(\ZZ/p\ZZ)^*/\{1,-1\}`.
     1746
     1747    INPUT:
     1748
     1749    - ``p`` -- an odd prime.
     1750
     1751    OUTPUT:
     1752
     1753    the smallest semi-primitive root modulo `p`.
     1754
     1755    .. note::
     1756
     1757       This function would normally be invoked indirectly via ``E.isogenies_prime_degree_general(l)``.
     1758
     1759    EXAMPLES::
     1760
     1761        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _least_semi_primitive
     1762        sage: _least_semi_primitive(5)
     1763        2
     1764        sage: _least_semi_primitive(13)
     1765        2
     1766        sage: _least_semi_primitive(17)
     1767        3
     1768        sage: _least_semi_primitive(73)
     1769        5
     1770        sage: _least_semi_primitive(997)
     1771        7
     1772    """
     1773    if not p.is_prime() or p<3:
     1774        raise ValueError("%s is not an odd prime"%p)
     1775
     1776    def is_semi_primitive(a,p):
     1777        from sage.rings.finite_rings.integer_mod_ring import Integers
     1778        d = Integers(p)(a).multiplicative_order()
     1779        if p%4==1:
     1780            return (d==p-1)
     1781        else:
     1782            return d >= (p-1)/2
     1783
     1784    a = 2
     1785    while not is_semi_primitive(a,p):
     1786        a += 1
     1787    return a
     1788
     1789
     1790def isogenies_prime_degree_general(E, l):
     1791    """
     1792    Returns a list of ``l`` -isogenies  with domain ``E``.
     1793
     1794    INPUT:
     1795
     1796    - ``E`` -- an elliptic curve.
     1797
     1798    - ``l`` -- a prime. 
     1799
     1800    OUTPUT:
     1801
     1802    (list) a list of all isogenies of degree l.
     1803
     1804    ALGORITHM::
     1805
     1806    This algorithm factors the ``l``-division polynomial, then
     1807    combines its factors to otain kernels. See [KT2013]_, Chapter 3.
     1808
     1809    .. note::
     1810
     1811       This function works for any prime `l`.  Normally one should use
     1812       the function :meth:`isogenies_prime_degree` which uses special
     1813       functions for certain small primes.
     1814
     1815    EXAMPLES::
     1816
     1817        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
     1818        sage: E = EllipticCurve_from_j(GF(2^6,'a')(1))
     1819        sage: isogenies_prime_degree_general(E, 7)
     1820        [Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field in a of size 2^6 to Elliptic Curve defined by y^2 + x*y = x^3 + x over Finite Field in a of size 2^6]
     1821        sage: E = EllipticCurve_from_j(GF(3^12,'a')(2))
     1822        sage: isogenies_prime_degree_general(E, 17)
     1823        [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x over Finite Field in a of size 3^12, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 over Finite Field in a of size 3^12]
     1824        sage: E = EllipticCurve('50a1')
     1825        sage: isogenies_prime_degree_general(E, 3)
     1826        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field]
     1827        sage: isogenies_prime_degree_general(E, 5)
     1828        [Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
     1829        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1830        sage: isogenies_prime_degree_general(E, 19)
     1831        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
     1832        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     1833        sage: isogenies_prime_degree_general(E, 37)  # long time (10s)
     1834        [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field]
     1835
     1836        sage: E = EllipticCurve([-3440, 77658])
     1837        sage: isogenies_prime_degree_general(E, 43)  # long time (16s)
     1838        [Isogeny of degree 43 from Elliptic Curve defined by y^2 = x^3 - 3440*x + 77658 over Rational Field to Elliptic Curve defined by y^2 = x^3 - 6360560*x - 6174354606 over Rational Field]
     1839
     1840    Isogenies of degree equal to the characteristic are computed (but
     1841    only the separable isogeny).  In the following example we consider
     1842    an elliptic curve which is supersingular in characteristic 2
     1843    only::
     1844
     1845        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
     1846        sage: ainvs = (0,1,1,-1,-1)
     1847        sage: for l in prime_range(50):
     1848        ....:     E = EllipticCurve(GF(l),ainvs)
     1849        ....:     isogenies_prime_degree_general(E,l)
     1850        []
     1851        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
     1852        [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5]
     1853        [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
     1854        [Isogeny of degree 11 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11]
     1855        [Isogeny of degree 13 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13]
     1856        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
     1857        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
     1858        [Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
     1859        [Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
     1860        [Isogeny of degree 31 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
     1861        [Isogeny of degree 37 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
     1862        [Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
     1863        [Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
     1864        [Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
     1865
     1866    """
     1867    if not l.is_prime():
     1868        raise ValueError("%s is not prime."%l)
     1869    if l==2:
     1870        return isogenies_2(E)
     1871    if l==3:
     1872        return isogenies_3(E)
     1873
     1874    psi_l = E.division_polynomial(l)
     1875    factors = [h for h,e in psi_l.factor() if (l-1)/2 % h.degree() == 0]
     1876    a = _least_semi_primitive(l)
     1877    m = E.multiplication_by_m(a, x_only=True)
     1878    F = psi_l.parent()
     1879    x = F.gen()
     1880    ker = []
     1881    from sage.rings.arith import gcd
     1882    from sage.misc.all import prod
     1883    def mult(f):
     1884        return gcd(F(f(m([x,0])).numerator()),psi_l).monic()
     1885    while len(factors) > 0:
     1886        f = factors[0]
     1887        factors.remove(f)
     1888        d = f.degree()
     1889        S = [f]
     1890        for i in range((l-1)/(2*d)-1):
     1891            g = mult(S[i])
     1892            S.append(g)
     1893            if g in factors:
     1894                factors.remove(g)
     1895        if mult(S[-1]) == f:
     1896            ker.append(prod(S))
     1897    return [E.isogeny(k) for k in ker]
     1898
     1899def isogenies_prime_degree(E, l):
     1900    """
     1901    Returns a list of ``l`` -isogenies  with domain ``E``.
     1902
     1903    INPUT:
     1904
     1905    - ``E`` -- an elliptic curve.
     1906
     1907    - ``l`` -- a prime. 
     1908
     1909    OUTPUT:
     1910
     1911    (list) a list of all isogenies of degree `l`.  If the
     1912    characteristic is `l` then only separable isogenies are
     1913    constructed.
     1914
     1915    EXAMPLES::
     1916
     1917        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
     1918        sage: E = EllipticCurve_from_j(GF(2^6,'a')(1))
     1919        sage: isogenies_prime_degree(E, 7)
     1920        [Isogeny of degree 7 from Elliptic Curve defined by y^2 + x*y = x^3 + 1 over Finite Field in a of size 2^6 to Elliptic Curve defined by y^2 + x*y = x^3 + x over Finite Field in a of size 2^6]
     1921        sage: E = EllipticCurve_from_j(GF(3^12,'a')(2))
     1922        sage: isogenies_prime_degree(E, 17)
     1923        [Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2*x over Finite Field in a of size 3^12, Isogeny of degree 17 from Elliptic Curve defined by y^2 = x^3 + 2*x^2 + 2 over Finite Field in a of size 3^12 to Elliptic Curve defined by y^2 = x^3 + 2*x^2 + x + 2 over Finite Field in a of size 3^12]
     1924        sage: E = EllipticCurve('50a1')
     1925        sage: isogenies_prime_degree(E, 3)
     1926        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 126*x - 552 over Rational Field]
     1927        sage: isogenies_prime_degree(E, 5)
     1928        [Isogeny of degree 5 from Elliptic Curve defined by y^2 + x*y + y = x^3 - x - 2 over Rational Field to Elliptic Curve defined by y^2 + x*y + y = x^3 - 76*x + 298 over Rational Field]
     1929        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1930        sage: isogenies_prime_degree(E, 19)
     1931        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 - 1862*x - 30956 over Rational Field to Elliptic Curve defined by y^2 + y = x^3 - 672182*x + 212325489 over Rational Field]
     1932        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     1933        sage: isogenies_prime_degree(E, 37)
     1934        [Isogeny of degree 37 from Elliptic Curve defined by y^2 = x^3 - x^2 - 6288*x + 211072 over Rational Field to Elliptic Curve defined by y^2 = x^3 - x^2 - 163137088*x - 801950801728 over Rational Field]
     1935
     1936
     1937    Isogenies of degree equal to the characteristic are computed (but
     1938    only the separable isogeny).  In the following example we consider
     1939    an elliptic curve which is supersingular in characteristic 2
     1940    only::
     1941
     1942        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
     1943        sage: ainvs = (0,1,1,-1,-1)
     1944        sage: for l in prime_range(50):
     1945        ....:     E = EllipticCurve(GF(l),ainvs)
     1946        ....:     isogenies_prime_degree(E,l)
     1947        []
     1948        [Isogeny of degree 3 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 2*x + 2 over Finite Field of size 3 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x over Finite Field of size 3]
     1949        [Isogeny of degree 5 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4*x + 4 over Finite Field of size 5]
     1950        [Isogeny of degree 7 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 6*x + 6 over Finite Field of size 7 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 4 over Finite Field of size 7]
     1951        [Isogeny of degree 11 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 10*x + 10 over Finite Field of size 11 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + x + 1 over Finite Field of size 11]
     1952        [Isogeny of degree 13 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 12*x + 12 over Finite Field of size 13]
     1953        [Isogeny of degree 17 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 16 over Finite Field of size 17 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15 over Finite Field of size 17]
     1954        [Isogeny of degree 19 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 18*x + 18 over Finite Field of size 19 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 3*x + 12 over Finite Field of size 19]
     1955        [Isogeny of degree 23 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 22*x + 22 over Finite Field of size 23]
     1956        [Isogeny of degree 29 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 28*x + 28 over Finite Field of size 29 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 7*x + 27 over Finite Field of size 29]
     1957        [Isogeny of degree 31 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 30*x + 30 over Finite Field of size 31 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 15*x + 16 over Finite Field of size 31]
     1958        [Isogeny of degree 37 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36*x + 36 over Finite Field of size 37 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 16*x + 17 over Finite Field of size 37]
     1959        [Isogeny of degree 41 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 40*x + 40 over Finite Field of size 41 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 33*x + 16 over Finite Field of size 41]
     1960        [Isogeny of degree 43 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 42 over Finite Field of size 43 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 36 over Finite Field of size 43]
     1961        [Isogeny of degree 47 from Elliptic Curve defined by y^2 + y = x^3 + x^2 + 46*x + 46 over Finite Field of size 47 to Elliptic Curve defined by y^2 + y = x^3 + x^2 + 42*x + 34 over Finite Field of size 47]
     1962
     1963    Note that the computation is faster for degrees equal to one of
     1964    the genus 0 primes (2, 3, 5, 7, 13) or one of the hyperelliptic
     1965    primes (11, 17, 19, 23, 29, 31, 41, 47, 59, 71) than when the
     1966    generic code must be used::
     1967
     1968        sage: E = EllipticCurve(GF(101), [-3440, 77658])
     1969        sage: E.isogenies_prime_degree(71) # fast
     1970        []
     1971        sage: E.isogenies_prime_degree(73) # not tested (very long time: 32s)
     1972        []
     1973
     1974
     1975    """
     1976    if not l.is_prime():
     1977        raise ValueError("%s is not prime."%l)
     1978    if l==2:
     1979        return isogenies_2(E)
     1980    if l==3:
     1981        return isogenies_3(E)
     1982
     1983    p = E.base_ring().characteristic()
     1984    if l==p:
     1985        return isogenies_prime_degree_general(E,l)
     1986
     1987    if l in [5,7,13] and not p in [2,3]:
     1988        return isogenies_prime_degree_genus_0(E,l)
     1989
     1990    if l in hyperelliptic_primes and not p in [2,3]:
     1991        return isogenies_prime_degree_genus_plus_0(E,l)
     1992
     1993    return isogenies_prime_degree_general(E,l)