Ticket #13615: trac_13615_combined_4th_review.patch

File trac_13615_combined_4th_review.patch, 202.3 KB (added by defeo, 6 years ago)
  • doc/en/reference/plane_curves/index.rst

    # HG changeset patch
    # User Luca De Feo <luca.defeo@polytechnique.edu>
    # Date 1378508630 -7200
    #      Sat Sep 07 01:03:50 2013 +0200
    # Node ID 3d0ce5527055f027a6ba896587ab4260c11d50e8
    # Parent  5d8c13e7b81a1e152855073f97a4d48ee97255d1
    #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  
    3030   sage/schemes/elliptic_curves/kodaira_symbol
    3131   sage/schemes/elliptic_curves/weierstrass_morphism
    3232   sage/schemes/elliptic_curves/ell_curve_isogeny
     33   sage/schemes/elliptic_curves/isogeny_small_degree
    3334   sage/schemes/elliptic_curves/ell_wp
    3435   sage/schemes/elliptic_curves/period_lattice
    3536   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  
    42044204            ValueError: 4 is not prime.
    42054205
    42064206        """
    4207         from ell_curve_isogeny import isogenies_prime_degree_genus_0, isogenies_sporadic_Q
     4207        from isogeny_small_degree import isogenies_prime_degree_genus_0, isogenies_sporadic_Q
    42084208       
    42094209        if l in [2, 3, 5, 7, 13]:
    42104210            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 following code computes data to be used in
     337# isogenies_sporadic_Q. Over Q there are only finitely many
     338# j-invariants of curves with l-isogenies where l is not equal to 2,
     339# 3, 5, 7 or 13. In these cases l is equal to 11, 17, 19, 37, 43, 67
     340# or 163. We refer to these l as "sporadic".
     341
     342# sporadic_j is a dictionary holding for each possible sporadic
     343# j-invariant, the unique l such that an l-isogeny exists.
     344sporadic_j = {
     345    QQ(-121)                : 11,
     346    QQ(-32768)              : 11,
     347    QQ(-24729001)           : 11,
     348    QQ(-297756989)/2        : 17,
     349    QQ(-882216989)/131072   : 17,
     350    QQ(-884736)             : 19,
     351    QQ(-9317)               : 37,
     352    QQ(-162677523113838677) : 37,
     353    QQ(-884736000)          : 43,
     354    QQ(-147197952000)       : 67,
     355    QQ(-262537412640768000) : 163
     356    }
     357
     358@cached_function
     359def _sporadic_Q_data(j):
     360    """
     361    Returns technical data used in computing sporadic isogenies over `\QQ`.
     362
     363    INPUT:
     364
     365    - ``j`` -- The `j`-invariant of a sporadic curve, i.e. one of the
     366      keys of ``sporadic_j``.
     367
     368    OUTPUT:
     369
     370    ``([a4,a6],coeffs)`` where ``[a4,a6]`` are the coefficients of a
     371    short Weierstrass equation of an elliptic curve E with j(E)=``j``,
     372    and ``coeffs`` is a list of coefficients of a polynomial defining
     373    the kernel of an l-isogeny from E.
     374
     375    Whenever we have a curve of j-invariant ``j``, we can compute the
     376    corresponding l-isogeny by just scaling ``coeffs`` by the right
     377    twisting factor and using the result as a kernel-polynomial.
     378
     379    ALGORITHM:
     380
     381    For small l it works fine to factor the l-division polynomial, but
     382    this takes a long time for the larger l and is a very bad idea for
     383    l=163; hence we use floating point arithmetic with a precision
     384    which is known to work.  This idea was suggested by Samir Siksek.
     385
     386    TESTS::
     387
     388        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import sporadic_j, _sporadic_Q_data
     389        sage: [_sporadic_Q_data(j) for j in sorted(sporadic_j.keys()) if j != -262537412640768000]
     390        [([-269675595, -1704553285050],
     391          [-855506888466179262477032094260950275409164148942611063430052125977143159,
     392           -1469048260972089939455942042937882262144594798448952781325533511718750,
     393           -1171741935131505774747142644126089902595908234671576131857702734375,
     394           -574934780393177024547076427530739751753985644656221274606250000,
     395           -193516922725803688001809624711400287605136013195315374687500,
     396           -47085563820928456130325308223963045033502182349693125000,
     397           -8472233937388712980597845725196873697064639957437500,
     398           -1124815211213953261752081095348112305023653750000,
     399           -105684015609077608033913080859605951322531250,
     400           -5911406027236569746089675554748135312500,
     401           22343907270397352965399097794968750,
     402           43602171843758666292581116410000,
     403           5054350766002463251474186500,
     404           350135768194635636171000,
     405           16633063574896677300,
     406           549939627039600,
     407           12182993865,
     408           163170,
     409           1]),
     410         ([-117920, 15585808],
     411          [426552448394636714720553816389274308035895411389805883034985546818882031845376,
     412           -55876556222880738651382959148329502876096075327084935039031884373558741172224,
     413           3393295715290183821010552313572221545212247684503012173117764703828786020352,
     414           -125729166452196578653551230178028570067747190427221869867485520072257044480,
     415           3121342502030777257351089270834971957072933779704445667351054593298530304,
     416           -52544031605544530265465344472543470442324636919759253720520768014516224,
     417           532110915869155495738137756847596184665209453108323879594125221167104,
     418           -399031158106622651277981701966309467713625045637309782055519780864,
     419           -101914346170769215732007802723651742508893380955930030421292613632,
     420           2296526155500449624398016447877283594461904009374321659789443072,
     421           -31950871094301541469458501953701002806003991982768349794795520,
     422           329792235011603804948028315065667439678526339671142107709440,
     423           -2655636715955021784085217734679612378726442691190553837568,
     424           16825164648840434987220620681420687654501026066872664064,
     425           -81705027839007003131400500185224450729843244954288128,
     426           273656504606483403474090105104132405333665144373248,
     427           -320807702482945680116212224172370503903312084992,
     428           -3166683390779345463318656135338172047199043584,
     429           27871349428383710305216046431806697565585408,
     430           -132774697798318602604125735604528772808704,
     431           436096215568182871014215818309741314048,
     432           -964687143341252402362763535357837312,
     433           942144169187362941776488535425024,
     434           2794850106281773765892648206336,
     435           -17236916236678037389276086272,
     436           50979778712911923486851072,
     437           -105035658611718440992768,
     438           161833913559276412928,
     439           -188675698610077696,
     440           163929317513984,
     441           -102098677888,
     442           42387952,
     443           -10184,
     444           1]),
     445         ([-13760, 621264],
     446          [-1961864562041980324821547425314935668736,
     447           784270445793223959453256359333693751296,
     448           -120528107728500223255333768387027271680,
     449           10335626145581464192664472924270362624,
     450           -568426570575654606865505142156820480,
     451           21261993723422650574629752537088000,
     452           -544630471727787626557612832587776,
     453           8870521306520473088172555763712,
     454           -54993059067301585878494740480,
     455           -1434261324709904840432549888,
     456           50978938193065926383894528,
     457           -845761855773797582372864,
     458           8627493611216601088000,
     459           -48299605284169187328,
     460           -32782260293713920,
     461           3415534989828096,
     462           -34580115625984,
     463           199359712512,
     464           -730488128,
     465           1658080,
     466           -2064,
     467           1]),
     468         ([-3940515, 3010787550],
     469          [-6458213126940667330314375,
     470           34699336325466068070000,
     471           -72461450055340471500,
     472           68342601718080000,
     473           -15140380554450,
     474           -25802960400,
     475           23981220,
     476           -8160,
     477           1]),
     478         ([-38907, -2953962], [-20349931239, -424530315, -134838, 53658, 429, 1]),
     479         ([-608, 5776],
     480          [-34162868224,
     481           -8540717056,
     482           6405537792,
     483           -1123778560,
     484           84283392,
     485           -2033152,
     486           -92416,
     487           6992,
     488           -152,
     489           1]),
     490         ([-9504, 365904], [1294672896, -92835072, 1463616, 7920, -264, 1]),
     491         ([-10395, 444150],
     492          [-38324677699334121599624973029296875,
     493           -17868327793500376961572310472656250,
     494           2569568362004197901139023084765625,
     495           -95128267987528547588017818750000,
     496           -822168183291347061312510937500,
     497           134395594560592096297190625000,
     498           -2881389756919344324888937500,
     499           -2503855007083401977250000,
     500           922779077075655997443750,
     501           -11503912310262102937500,
     502           -18237870962450291250,
     503           1457822151548910000,
     504           -10087015556047500,
     505           -13677678063000,
     506           490243338900,
     507           -2461460400,
     508           5198445,
     509           -4410,
     510           1]),
     511         ([-856035, -341748450],
     512          [103687510635057329105625,
     513           961598491955315190000,
     514           1054634146768300500,
     515           -6553122389064000,
     516           -14554350284850,
     517           -2046589200,
     518           13185540,
     519           8160,
     520           1]),
     521         ([-3267, -280962], [1480352841, -56169531, -2829222, 10890, 429, 1])]
     522    """
     523    from sage.rings.all import RealField
     524    from sage.misc.all import prod
     525    ell = sporadic_j[j]
     526    E = EllipticCurve(j=j).short_weierstrass_model()
     527    a4a6 = list(E.ainvs())[3:]
     528    L = E.period_lattice()
     529    pr = 100
     530    if ell==163:
     531        pr=1000
     532    elif ell>30:
     533        pr=300
     534    w1, w2 = L.basis(prec=pr)
     535    X = polygen(RealField(pr),'X')
     536    w = w1 # real period
     537    if j in [-121, -24729001, -162677523113838677, QQ(-882216989)/131072]:
     538        w = 2*w2-w1 # imaginary period
     539    kerpol = prod(([X-L.elliptic_exponential(n*w/ell)[0] for n in range(1,(ell+1)//2)]))
     540    kerpolcoeffs = [c.real().round() for c in list(kerpol)]
     541    return (a4a6,kerpolcoeffs)
     542
     543def isogenies_sporadic_Q(E, l=None):
     544    """
     545    Returns list of ``l`` -isogenies with domain ``E`` (defined over `\QQ`).
     546
     547    Returns a list of sporadic l-isogenies from E (l = 11, 17, 19, 37,
     548    43, 67 or 163). Only for elliptic curves over `\QQ`.
     549
     550    INPUT:
     551
     552    - ``E`` -- an elliptic curve defined over `\QQ`.
     553
     554    - ``l`` -- either None or a prime number.
     555
     556    OUTPUT:
     557
     558    (list) If ``l`` is None, a list of all isogenies with domain ``E``
     559    and of degree 11, 17, 19, 37, 43, 67 or 163; otherwise a list of
     560    isogenies of the given degree.
     561
     562    .. note::
     563
     564       This function would normally be invoked indirectly via
     565       ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate
     566       function.
     567
     568    EXAMPLES::
     569
     570        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_sporadic_Q                                                                       
     571        sage: E = EllipticCurve('121a1')   
     572        sage: isogenies_sporadic_Q(E, 11)
     573        [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]
     574        sage: isogenies_sporadic_Q(E, 13)
     575        []
     576        sage: isogenies_sporadic_Q(E, 17)
     577        []
     578        sage: isogenies_sporadic_Q(E)   
     579        [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]
     580         
     581        sage: E = EllipticCurve([1, 1, 0, -660, -7600])   
     582        sage: isogenies_sporadic_Q(E, 17)
     583        [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]
     584        sage: isogenies_sporadic_Q(E)   
     585        [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]
     586        sage: isogenies_sporadic_Q(E, 11)
     587        []
     588       
     589        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])   
     590        sage: isogenies_sporadic_Q(E, 11)
     591        []
     592        sage: isogenies_sporadic_Q(E, 19)
     593        [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]
     594        sage: isogenies_sporadic_Q(E)   
     595        [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]
     596
     597        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     598        sage: E.conductor()
     599        19600
     600        sage: isogenies_sporadic_Q(E,37)
     601        [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]
     602
     603        sage: E = EllipticCurve([1, 1, 0, -25178045, 48616918750])
     604        sage: E.conductor()                                       
     605        148225
     606        sage: isogenies_sporadic_Q(E,37)
     607        [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]
     608
     609        sage: E = EllipticCurve([-3440, 77658])         
     610        sage: E.conductor()                   
     611        118336
     612        sage: isogenies_sporadic_Q(E,43)       
     613        [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]
     614
     615        sage: E = EllipticCurve([-29480, -1948226])     
     616        sage: E.conductor()
     617        287296
     618        sage: isogenies_sporadic_Q(E,67)
     619        [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]
     620
     621        sage: E = EllipticCurve([-34790720, -78984748304])
     622        sage: E.conductor()
     623        425104
     624        sage: isogenies_sporadic_Q(E,163)
     625        [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]
     626    """
     627    if E.base_ring() != QQ:
     628        raise ValueError("The elliptic curve must be defined over QQ.")
     629    j = E.j_invariant()
     630    j = QQ(j)
     631    if (j not in sporadic_j
     632        or (l is not None and sporadic_j[j] != l)):
     633        return []
     634
     635    data = _sporadic_Q_data(j)
     636    Ew = E.short_weierstrass_model()
     637    E_to_Ew = E.isomorphism_to(Ew)
     638    c4, c6 = Ew.c_invariants()
     639    (a4,a6), f = data
     640    d = (c6*a4)/(18*c4*a6) # twisting factor
     641    R = PolynomialRing(E.base_field(),'X')
     642    n = len(f)
     643    ker = R([d**(n-i-1) * f[i] for i in range(n)])
     644    isog = Ew.isogeny(kernel=ker, degree=l, model="minimal", check=False)
     645    isog.set_pre_isomorphism(E_to_Ew)
     646    return [isog]
     647
     648
     649def isogenies_2(E):
     650    """
     651    Returns a list of all 2-isogenies with domain ``E``.
     652
     653    INPUT:
     654
     655    - ``E`` -- an elliptic curve.
     656
     657    OUTPUT:
     658
     659    (list) 2-isogenies with domain ``E``.  In general these are
     660    normalised, but over `\QQ` the codomain is a minimal model.
     661
     662    EXAMPLES::
     663
     664        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_2   
     665        sage: E = EllipticCurve('14a1'); E
     666        Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
     667        sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
     668        [(1, 0, 1, -36, -70)]
     669
     670        sage: E = EllipticCurve([1,2,3,4,5]); E
     671        Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
     672        sage: [phi.codomain().ainvs() for phi in isogenies_2(E)]
     673        []
     674        sage: E = EllipticCurve(QQbar, [9,8]); E 
     675        Elliptic Curve defined by y^2 = x^3 + 9*x + 8 over Algebraic Field
     676        sage: isogenies_2(E) # not implemented
     677    """
     678    f2 = E.division_polynomial(2)
     679    x2 = f2.roots(multiplicities=False)
     680    x2.sort()
     681    x = f2.parent().gen()
     682    ff = [x-x2i for x2i in x2]
     683    model = "minimal" if E.base_field() is QQ else None
     684    isogs = [E.isogeny(f, model=model) for f in ff]
     685    return isogs
     686   
     687def isogenies_3(E):
     688    """
     689    Returns a list of all 3-isogenies with domain ``E``.
     690
     691    INPUT:
     692
     693    - ``E`` -- an elliptic curve.
     694
     695    OUTPUT:
     696
     697    (list) 3-isogenies with domain ``E``.  In general these are
     698    normalised, but over `\QQ` the codomain is a minimal model.
     699
     700    EXAMPLES::
     701
     702        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_3
     703        sage: E = EllipticCurve(GF(17), [1,1])
     704        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     705        [(0, 0, 0, 9, 7), (0, 0, 0, 0, 1)]
     706
     707        sage: E = EllipticCurve(GF(17^2,'a'), [1,1])
     708        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     709        [(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)]
     710
     711        sage: E = EllipticCurve('19a1')   
     712        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     713        [(0, 1, 1, 1, 0), (0, 1, 1, -769, -8470)]
     714
     715        sage: E = EllipticCurve([1,1])
     716        sage: [phi.codomain().ainvs() for phi in isogenies_3(E)]
     717        []
     718    """
     719    f3 = E.division_polynomial(3)
     720    x3 = f3.roots(multiplicities=False)
     721    x3.sort()
     722    x = f3.parent().gen()
     723    ff = [x-x3i for x3i in x3]
     724    model = "minimal" if E.base_field() is QQ else None
     725    isogs = [E.isogeny(f, model=model) for f in ff]
     726    return isogs
     727
     728# 6 special cases: `l` = 5, 7, 13 and `j` = 0, 1728.
     729
     730def isogenies_5_0(E):
     731    """
     732    Returns a list of all the 5-isogenies  with domain ``E`` when the
     733    j-invariant is 0.
     734
     735    OUTPUT:
     736
     737    (list) 5-isogenies with codomain E.  In general these are
     738    normalised, but over `\QQ` the codomain is a minimal model.
     739
     740    .. note::
     741
     742       This implementation requires that the characteristic is not 2,
     743       3 or 5.
     744
     745    .. note::
     746
     747       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
     748
     749    EXAMPLES::
     750
     751        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_0
     752        sage: E = EllipticCurve([0,12])
     753        sage: isogenies_5_0(E)                             
     754        []
     755
     756        sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
     757        sage: isogenies_5_0(E)
     758        [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]
     759
     760        sage: K.<a> = NumberField(x**6-320*x**3-320)
     761        sage: E = EllipticCurve(K,[0,0,1,0,0])
     762        sage: isogenies_5_0(E)                     
     763        [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,
     764        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]
     765
     766    """
     767    F = E.base_field()
     768    if E.j_invariant() != 0:
     769        raise ValueError("j-invariant must be 0.")
     770    if F.characteristic() in [2,3,5]:
     771        raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
     772    if not F(5).is_square():
     773        return []
     774    Ew = E.short_weierstrass_model()
     775    a = Ew.a6()
     776    x = polygen(F)
     777    betas = (x**6-160*a*x**3-80*a**2).roots(multiplicities=False)
     778    betas.sort()
     779    if len(betas)==0:
     780        return []
     781    gammas = [(beta**2 *(beta**3-140*a))/(120*a) for beta in betas]
     782    model = "minimal" if F is QQ else None
     783    isogs = [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
     784    iso = E.isomorphism_to(Ew)
     785    [isog.set_pre_isomorphism(iso) for isog in isogs]
     786    return isogs
     787
     788def isogenies_5_1728(E):
     789    """
     790    Returns a list of 5-isogenies with domain ``E`` when the j-invariant is
     791    1728.
     792
     793    OUTPUT:
     794
     795    (list) 5-isogenies with codomain E.  In general these are
     796    normalised; but if `-1` is a square then there are two
     797    endomorphisms of degree `5`, for which the codomain is the same as
     798    the domain curve; and over `\QQ`, the codomain is a minimal model.
     799
     800    .. note::
     801
     802       This implementation requires that the characteristic is not 2,
     803       3 or 5.
     804
     805    .. note::
     806
     807       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(5)``.
     808
     809    EXAMPLES::
     810       
     811        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_5_1728
     812        sage: E = EllipticCurve([7,0])   
     813        sage: isogenies_5_1728(E)
     814        []
     815
     816        sage: E = EllipticCurve(GF(13),[11,0])
     817        sage: isogenies_5_1728(E)       
     818        [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,
     819        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]
     820
     821    An example of endomorphisms of degree 5::
     822
     823        sage: K.<i> = QuadraticField(-1)                   
     824        sage: E = EllipticCurve(K,[0,0,0,1,0])
     825        sage: isogenies_5_1728(E)             
     826        [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,
     827        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]
     828        sage: _[0].rational_maps()
     829        (((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)),
     830         ((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)))
     831
     832    An example of 5-isogenies over a number field::
     833
     834        sage: K.<a> = NumberField(x**4+20*x**2-80)
     835        sage: K(5).is_square() #necessary but not sufficient!       
     836        True
     837        sage: E = EllipticCurve(K,[0,0,0,1,0])   
     838        sage: isogenies_5_1728(E)                 
     839        [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,
     840        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]   
     841    """
     842    F = E.base_field()
     843    if E.j_invariant() != 1728:
     844        raise ValueError("j-invariant must be 1728.")
     845    if F.characteristic() in [2,3,5]:
     846        raise NotImplementedError("Not implemented in characteristic 2, 3 or 5.")
     847    model = "minimal" if F is QQ else None
     848    # quick test for a negative answer (from Fricke module)
     849    square5 = F(5).is_square()
     850    square1 = F(-1).is_square()
     851    if not square5 and not square1:
     852        return []
     853    Ew = E.short_weierstrass_model()
     854    iso = E.isomorphism_to(Ew)
     855    a = Ew.a4()
     856    x = polygen(F)
     857    isogs = []
     858    # 2 cases
     859    # Type 1: if -1 is a square we have 2 endomorphisms
     860    if square1:
     861        i = F(-1).sqrt()
     862        isogs = [Ew.isogeny(f) for f in [x**2+a/(1+2*i), x**2+a/(1-2*i)]]
     863        [isog.set_post_isomorphism(isog.codomain().isomorphism_to(E)) for isog in isogs]
     864    # Type 2: if 5 is a square we have up to 4 (non-endomorphism) isogenies
     865    if square5:
     866        betas = (x**4+20*a*x**2-80*a**2).roots(multiplicities=False)
     867        betas.sort()
     868        gammas = [a*(beta**2-2)/6 for beta in betas]
     869        isogs += [Ew.isogeny(x**2+beta*x+gamma, model=model) for beta,gamma in zip(betas,gammas)]
     870    [isog.set_pre_isomorphism(iso) for isog in isogs]
     871    return isogs
     872
     873def isogenies_7_0(E):
     874    """
     875    Returns list of all 7-isogenies from E when the j-invariant is 0.
     876
     877    OUTPUT:
     878
     879    (list) 7-isogenies with codomain E.  In general these are
     880    normalised; but if `-3` is a square then there are two
     881    endomorphisms of degree `7`, for which the codomain is the same as
     882    the domain; and over `\QQ`, the codomain is a minimal model.
     883
     884    .. note::
     885
     886       This implementation requires that the characteristic is not 2,
     887       3 or 7.
     888
     889    .. note::
     890
     891       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
     892
     893    EXAMPLES:
     894
     895    First some examples of endomorphisms::
     896
     897        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0   
     898        sage: K.<r> = QuadraticField(-3)
     899        sage: E = EllipticCurve(K, [0,1]) 
     900        sage: isogenies_7_0(E)
     901        [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,
     902        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]
     903
     904        sage: E = EllipticCurve(GF(13^2,'a'),[0,-3])
     905        sage: isogenies_7_0(E)       
     906        [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]
     907
     908    Now some examples of 7-isogenies which are not endomorphisms::
     909
     910        sage: K = GF(101)               
     911        sage: E = EllipticCurve(K, [0,1])
     912        sage: isogenies_7_0(E)           
     913        [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]
     914
     915    Examples over a number field::
     916
     917        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_0
     918        sage: E = EllipticCurve('27a1').change_ring(QuadraticField(-3,'r'))
     919        sage: isogenies_7_0(E)
     920        [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,
     921        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]
     922
     923        sage: K.<a> = NumberField(x^6 + 1512*x^3 - 21168)
     924        sage: E = EllipticCurve(K, [0,1])
     925        sage: isogs = isogenies_7_0(E)
     926        sage: [phi.codomain().a_invariants() for phi in isogs]
     927        [(0, 0, 0, -5/294*a^5 - 300/7*a^2, -55/2*a^3 - 1133),
     928        (0, 0, 0, -295/1176*a^5 - 5385/14*a^2, 55/2*a^3 + 40447)]
     929        sage: [phi.codomain().j_invariant() for phi in isogs]
     930        [158428486656000/7*a^3 - 313976217600000,
     931        -158428486656000/7*a^3 - 34534529335296000]
     932    """
     933    if E.j_invariant()!=0:
     934        raise ValueError("j-invariant must be 0.")
     935    F = E.base_field()
     936    if F.characteristic() in [2,3,7]:
     937        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
     938    x = polygen(F)
     939    Ew = E.short_weierstrass_model()
     940    iso = E.isomorphism_to(Ew)
     941    a = Ew.a6()
     942    model = "minimal" if F is QQ else None
     943
     944    # there will be 2 endomorphisms if -3 is a square:
     945
     946    ts = (x**2+3).roots(multiplicities=False)
     947    ts.sort()
     948    kers = [7*x-(2+6*t) for t in ts]
     949    kers = [k(x**3/a).monic() for k in kers]
     950    isogs = [Ew.isogeny(k,model=model) for k in kers]
     951    if len(isogs)>0:
     952        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     953
     954    # we may have up to 6 other isogenies:
     955    ts = (x**2-21).roots(multiplicities=False)
     956    for t0 in ts:
     957        s3 = a/(28+6*t0)
     958        ss = (x**3-s3).roots(multiplicities=False)
     959        ss.sort()
     960        ker = x**3 - 2*t0*x**2 - 4*t0*x + 4*t0 + 28
     961        kers = [ker(x/s).monic() for s in ss]
     962        isogs += [Ew.isogeny(k, model=model) for k in kers]
     963   
     964    [isog.set_pre_isomorphism(iso) for isog in isogs]
     965    return isogs
     966
     967def isogenies_7_1728(E):
     968    """
     969    Returns list of all 7-isogenies from E when the j-invariant is 1728.
     970
     971    OUTPUT:
     972
     973    (list) 7-isogenies with codomain E.  In general these are
     974    normalised; but over `\QQ` the codomain is a minimal model.
     975
     976    .. note::
     977
     978       This implementation requires that the characteristic is not 2,
     979       3, or 7.
     980
     981    .. note::
     982
     983       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(7)``.
     984
     985    EXAMPLES::
     986
     987        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728                                                                           
     988        sage: E = EllipticCurve(GF(47), [1, 0])
     989        sage: isogenies_7_1728(E)             
     990        [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,
     991        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]
     992
     993    An example in characteristic 53 (for which an earlier implementation did not work)::   
     994
     995        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_7_1728
     996        sage: E = EllipticCurve(GF(53), [1, 0])
     997        sage: isogenies_7_1728(E)
     998        []
     999        sage: E = EllipticCurve(GF(53^2,'a'), [1, 0])
     1000        sage: [iso.codomain().ainvs() for iso in isogenies_7_1728(E)]
     1001        [(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)]
     1002
     1003    ::   
     1004
     1005        sage: K.<a> = NumberField(x^8 + 84*x^6 - 1890*x^4 + 644*x^2 - 567)
     1006        sage: E = EllipticCurve(K, [1, 0])                               
     1007        sage: isogs = isogenies_7_1728(E)
     1008        sage: [phi.codomain().a_invariants() for phi in isogs]
     1009        [(0,
     1010        0,
     1011        0,
     1012        35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
     1013        155/636*a^7 + 245/12*a^5 - 313355/636*a^3 - 3577/636*a),
     1014        (0,
     1015        0,
     1016        0,
     1017        35/636*a^6 + 55/12*a^4 - 79135/636*a^2 + 1127/212,
     1018        -155/636*a^7 - 245/12*a^5 + 313355/636*a^3 + 3577/636*a)]
     1019        sage: [phi.codomain().j_invariant() for phi in isogs]
     1020        [-526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53,
     1021        -526110256146528/53*a^6 + 183649373229024*a^4 - 3333881559996576/53*a^2 + 2910267397643616/53]
     1022        sage: E1 = isogs[0].codomain()
     1023        sage: E2 = isogs[1].codomain()
     1024        sage: E1.is_isomorphic(E2)
     1025        False
     1026        sage: E1.is_quadratic_twist(E2)
     1027        -1
     1028    """
     1029    if E.j_invariant()!=1728:
     1030        raise ValueError("j_invariant must be 1728 (in base field).")
     1031    F = E.base_field()
     1032    if F.characteristic() in [2,3,7]:
     1033        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 7.")
     1034    Ew = E.short_weierstrass_model()
     1035    iso = E.isomorphism_to(Ew)
     1036    a = Ew.a4()
     1037
     1038    ts = (Fricke_module(7)-1728).numerator().roots(F,multiplicities=False)
     1039    if len(ts)==0:
     1040        return []
     1041    ts.sort()
     1042    isogs = []
     1043    model = "minimal" if F is QQ else None
     1044    x = polygen(F)
     1045    for t0 in ts:
     1046        s2 = a/t0
     1047        ss = (x**2-s2).roots(multiplicities=False)
     1048        ss.sort()
     1049        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
     1050
     1051        kers = [ker(x/s) for s in ss]
     1052        isogs += [Ew.isogeny(k.monic(), model=model) for k in kers]
     1053    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1054    return isogs
     1055
     1056def isogenies_13_0(E):
     1057    """
     1058    Returns list of all 13-isogenies from E when the j-invariant is 0.
     1059
     1060    OUTPUT:
     1061
     1062    (list) 13-isogenies with codomain E.  In general these are
     1063    normalised; but if `-3` is a square then there are two
     1064    endomorphisms of degree `13`, for which the codomain is the same
     1065    as the domain.
     1066
     1067    .. note::
     1068
     1069       This implementation requires that the characteristic is not 2,
     1070       3 or 13.
     1071
     1072    .. note::
     1073
     1074       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
     1075
     1076    EXAMPLES::
     1077
     1078        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_0 
     1079
     1080    Endomorphisms of degree 13 will exist when -3 is a square::   
     1081
     1082        sage: K.<r> = QuadraticField(-3)
     1083        sage: E = EllipticCurve(K, [0, r]); E
     1084        Elliptic Curve defined by y^2 = x^3 + r over Number Field in r with defining polynomial x^2 + 3
     1085        sage: isogenies_13_0(E)
     1086        [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,
     1087        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]
     1088        sage: isogenies_13_0(E)[0].rational_maps()
     1089        (((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)))
     1090
     1091    An example of endomorphisms over a finite field::
     1092   
     1093        sage: K = GF(19^2,'a')
     1094        sage: E = EllipticCurve(j=K(0)); E
     1095        Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field in a of size 19^2
     1096        sage: isogenies_13_0(E)                   
     1097        [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,
     1098        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]
     1099        sage: isogenies_13_0(E)[0].rational_maps()
     1100        ((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))
     1101
     1102    A previous implementation did not work in some characteristics::   
     1103
     1104        sage: K = GF(29)
     1105        sage: E = EllipticCurve(j=K(0))
     1106        sage: isogenies_13_0(E)
     1107        [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]
     1108
     1109    ::
     1110
     1111        sage: K = GF(101)                                         
     1112        sage: E = EllipticCurve(j=K(0)); E.ainvs()                 
     1113        (0, 0, 0, 0, 1)
     1114        sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
     1115        [(0, 0, 0, 64, 36), (0, 0, 0, 42, 66)]
     1116
     1117    ::
     1118
     1119        sage: x = polygen(QQ)
     1120        sage: f = x^12 + 78624*x^9 - 130308048*x^6 + 2270840832*x^3 - 54500179968
     1121        sage: K.<a> = NumberField(f)     
     1122        sage: E = EllipticCurve(j=K(0)); E.ainvs()
     1123        (0, 0, 0, 0, 1)
     1124        sage: [phi.codomain().ainvs() for phi in isogenies_13_0(E)]
     1125        [(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)]
     1126    """
     1127    if E.j_invariant()!=0:
     1128        raise ValueError("j-invariant must be 0.")
     1129    F = E.base_field()
     1130    if F.characteristic() in [2,3,13]:
     1131        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
     1132    Ew = E.short_weierstrass_model()
     1133    iso = E.isomorphism_to(Ew)
     1134    a = Ew.a6()
     1135    model = "minimal" if F is QQ else None
     1136    x = polygen(F)
     1137
     1138    # there will be 2 endomorphisms if -3 is a square:
     1139    ts = (x**2+3).roots(multiplicities=False)
     1140    ts.sort()
     1141    kers = [13*x**2 + (78*t + 26)*x + 24*t + 40 for t in ts]
     1142    kers = [k(x**3/a).monic() for k in kers]
     1143    isogs = [Ew.isogeny(k,model=model) for k in kers]
     1144    if len(isogs)>0:
     1145        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     1146 
     1147    # we may have up to 12 other isogenies:
     1148    ts = (x**4 + 7*x**3 + 20*x**2 + 19*x + 1).roots(multiplicities=False)
     1149    ts.sort()
     1150    for t0 in ts:
     1151        s3 = a / (6*t0**3 + 32*t0**2 + 68*t0 + 4)
     1152        ss = (x**3-s3).roots(multiplicities=False)
     1153        ss.sort()
     1154        ker = (x**6 + (20*t0**3 + 106*t0**2 + 218*t0 + 4)*x**5
     1155            + (-826*t0**3 - 4424*t0**2 - 9244*t0 - 494)*x**4
     1156            + (13514*t0**3 + 72416*t0**2 + 151416*t0 + 8238)*x**3
     1157            + (-101948*t0**3 - 546304*t0**2 - 1142288*t0 - 62116)*x**2
     1158            + (354472*t0**3 + 1899488*t0**2 + 3971680*t0 + 215960)*x
     1159            - 459424*t0**3 - 2461888*t0**2 - 5147648*t0 - 279904)
     1160        kers = [ker(x/s).monic() for s in ss]
     1161        isogs += [Ew.isogeny(k, model=model) for k in kers]
     1162   
     1163    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1164
     1165    return isogs
     1166
     1167def isogenies_13_1728(E):
     1168    """
     1169    Returns list of all 13-isogenies from E when the j-invariant is 1728.
     1170
     1171    OUTPUT:
     1172
     1173    (list) 13-isogenies with codomain E.  In general these are
     1174    normalised; but if `-1` is a square then there are two
     1175    endomorphisms of degree `13`, for which the codomain is the same
     1176    as the domain; and over `\QQ`, the codomain is a minimal model.
     1177
     1178    .. note::
     1179
     1180       This implementation requires that the characteristic is not
     1181       2, 3 or 13.
     1182
     1183    .. note::
     1184
     1185       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(13)``.
     1186
     1187    EXAMPLES::
     1188
     1189        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_13_1728
     1190
     1191        sage: K.<i> = QuadraticField(-1)
     1192        sage: E = EllipticCurve([0,0,0,i,0]); E.ainvs()
     1193        (0, 0, 0, i, 0)
     1194        sage: isogenies_13_1728(E)
     1195        [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,
     1196        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]
     1197
     1198    ::
     1199
     1200        sage: K = GF(83)
     1201        sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
     1202        (0, 0, 0, 5, 0)
     1203        sage: isogenies_13_1728(E)                       
     1204        []
     1205        sage: K = GF(89)                                 
     1206        sage: E = EllipticCurve(K, [0,0,0,5,0]); E.ainvs()
     1207        (0, 0, 0, 5, 0)
     1208        sage: isogenies_13_1728(E)                       
     1209        [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,
     1210        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]
     1211
     1212    ::
     1213
     1214        sage: K = GF(23)                                     
     1215        sage: E = EllipticCurve(K, [1,0])                     
     1216        sage: isogenies_13_1728(E)                           
     1217        [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]
     1218
     1219    ::
     1220
     1221        sage: x = polygen(QQ)
     1222        sage: f = x^12 + 1092*x^10 - 432432*x^8 + 6641024*x^6 - 282896640*x^4 - 149879808*x^2 - 349360128
     1223        sage: K.<a> = NumberField(f)
     1224        sage: E = EllipticCurve(K, [1,0])
     1225        sage: [phi.codomain().ainvs() for phi in isogenies_13_1728(E)]
     1226        [(0,
     1227        0,
     1228        0,
     1229        11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
     1230        214217013065/82065216155553792*a^11 + 1217882637605/427423000810176*a^9 - 214645003230565/189965778137856*a^7 + 22973355421236025/1282269002430528*a^5 - 2059145797340695/2544184528632*a^3 - 23198483147321/989405094468*a),
     1231        (0,
     1232        0,
     1233        0,
     1234        11090413835/20943727039698624*a^10 + 32280103535965/55849938772529664*a^8 - 355655987835845/1551387188125824*a^6 + 19216954517530195/5235931759924656*a^4 - 1079766118721735/5936430566808*a^2 + 156413528482727/8080141604822,
     1235        -214217013065/82065216155553792*a^11 - 1217882637605/427423000810176*a^9 + 214645003230565/189965778137856*a^7 - 22973355421236025/1282269002430528*a^5 + 2059145797340695/2544184528632*a^3 + 23198483147321/989405094468*a)]
     1236   
     1237    """
     1238    if E.j_invariant()!=1728:
     1239        raise ValueError("j-invariant must be 1728.")
     1240    F = E.base_field()
     1241    if F.characteristic() in [2, 3, 13]:
     1242        raise NotImplementedError("Not implemented when the characteristic of the base field is 2, 3 or 13.")
     1243    Ew = E.short_weierstrass_model()
     1244    iso = E.isomorphism_to(Ew)
     1245    a = Ew.a4()
     1246    model = "minimal" if F is QQ else None
     1247    x = polygen(F)
     1248
     1249    # we will have two endomorphisms if -1 is a square:
     1250    ts = (x**2+1).roots(multiplicities=False)
     1251    ts.sort()
     1252    kers = [13*x**3 + (-26*i - 13)*x**2 + (-52*i - 13)*x - 2*i - 3 for i in ts]
     1253    kers = [k(x**2/a).monic() for k in kers]
     1254    isogs = [Ew.isogeny(k,model=model) for k in kers]
     1255    if len(isogs)>0:
     1256        [endo.set_post_isomorphism(endo.codomain().isomorphism_to(E)) for endo in isogs]
     1257
     1258    # we may have up to 12 other isogenies:
     1259
     1260    ts = (x**6 + 10*x**5 + 46*x**4 + 108*x**3 + 122*x**2 + 38*x - 1).roots(multiplicities=False)
     1261    ts.sort()
     1262    for t0 in ts:
     1263        s2 = a/(66*t0**5 + 630*t0**4 + 2750*t0**3 + 5882*t0**2 + 5414*t0 + 162)
     1264        ss = (x**2-s2).roots(multiplicities=False)
     1265        ss.sort()
     1266        ker = (x**6 + (-66*t0**5 - 630*t0**4 - 2750*t0**3 - 5882*t0**2
     1267              - 5414*t0 - 162)*x**5 + (-21722*t0**5 - 205718*t0**4 -
     1268              890146*t0**3 - 1873338*t0**2 - 1652478*t0 + 61610)*x**4
     1269              + (-3391376*t0**5 - 32162416*t0**4 - 139397232*t0**3 -
     1270              294310576*t0**2 - 261885968*t0 + 6105552)*x**3 +
     1271              (-241695080*t0**5 - 2291695976*t0**4 - 9930313256*t0**3
     1272              - 20956609720*t0**2 - 18625380856*t0 + 469971320)*x**2 +
     1273              (-8085170432*t0**5 - 76663232384*t0**4 -
     1274              332202985024*t0**3 - 701103233152*t0**2 -
     1275              623190845440*t0 + 15598973056)*x - 101980510208*t0**5 -
     1276              966973468160*t0**4 - 4190156868352*t0**3 -
     1277              8843158270336*t0**2 - 7860368751232*t0 + 196854655936)
     1278       
     1279        kers = [ker(x/s).monic() for s in ss]
     1280        isogs += [Ew.isogeny(k, model=model) for k in kers]
     1281
     1282    [isog.set_pre_isomorphism(iso) for isog in isogs]
     1283   
     1284    return isogs
     1285
     1286# List of primes l for which X_0(l) is (hyper)elliptic and X_0^+(l) has genus 0
     1287
     1288hyperelliptic_primes = [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
     1289
     1290@cached_function
     1291def _hyperelliptic_isogeny_data(l):
     1292    r"""
     1293    Helper function for elliptic curve isogenies.
     1294
     1295    INPUT:
     1296
     1297    - ``l`` -- a prime in [11, 17, 19, 23, 29, 31, 41, 47, 59, 71]
     1298
     1299    OUTPUT:
     1300
     1301    - A dict holding a collection of precomputed data needed for computing `l`-isogenies.
     1302
     1303    EXAMPLES::
     1304
     1305        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _hyperelliptic_isogeny_data
     1306        sage: HID = _hyperelliptic_isogeny_data(11)
     1307        sage: HID['A2']
     1308        55*u - 33
     1309        sage: HID['A4']
     1310        -183*u^2 + 738*u - 180*v - 135
     1311        sage: HID['A6']
     1312        1330*u^3 - 11466*u^2 + 1332*u*v + 2646*u - 1836*v + 1890
     1313        sage: HID['alpha']
     1314        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
     1315        sage: HID['beta']
     1316        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
     1317        sage: HID['hyper_poly']
     1318        u^4 - 16*u^3 + 2*u^2 + 12*u - 7
     1319
     1320        sage: _hyperelliptic_isogeny_data(37)
     1321        Traceback (most recent call last):
     1322        ...
     1323        ValueError: 37 must be one of [11, 17, 19, 23, 29, 31, 41, 47, 59, 71].
     1324
     1325    """
     1326    if not l in hyperelliptic_primes:
     1327        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1328    data = {}
     1329    Zu = PolynomialRing(ZZ,'u')
     1330    Zuv = PolynomialRing(ZZ,['u','v'])
     1331    Zxuv = PolynomialRing(ZZ,['x','u','v'])
     1332    x,u,v = Zxuv.gens()
     1333    if l == 11:
     1334        data['hyper_poly'] = Zu([-7, 12, 2, -16, 1])
     1335        data['A2'] = Zu([-33, 55])
     1336        data['A4'] = Zuv(Zu([-135, 738, -183])+v*Zu([-180]))
     1337        data['A6'] = Zuv(Zu([1890, 2646, -11466, 1330]) + v*Zu([-1836, 1332]))
     1338        data['alpha'] = Zu([-6750, 24300, 40095, -187407, 132066, 133056, -177408, 69630, -12716, 1188, -55, 1])
     1339        data['beta'] = Zu([0, -12150, 27135, 10665, -48573, 29313, -7187, 843, -47, 1])
     1340        #beta factors as (u - 15) * (u - 6) * (u - 3) * (u - 1) * u * (u**2 - 12*u - 9) * (u**2 - 10*u + 5)
     1341        return data
     1342    if l == 17:
     1343        data['hyper_poly'] = Zu([-8, 4, -3, -10, 1])
     1344        data['A2'] = Zu([68, -204, 136])
     1345        data['A4'] = Zuv(Zu([60, 720, -2595, 2250, -435]) + v*Zu([-360, 792, -432]))
     1346        data['A6'] = Zuv(Zu([-8512, 22608, -5064, -57528, 87288, -43704, 4912] ) + v*Zu( [2520, -15372, 28098, -20160, 4914]))
     1347        data['alpha'] = Zu([16000, -67200, 2720, 557600, -1392232, 1073992, 1104830, -3131026, 2450210, 73746, -1454945, 1110355, -424065, 95659, -13243, 1105, -51, 1])
     1348        data['beta'] = Zu([0, 22400, -105920, 146208, 111616, -593800, 680948, -102282, -457950, 468035, -219274, 58549, -9374, 889, -46, 1])
     1349        #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)
     1350        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
     1351        data['endo_u'] = 1
     1352        return data
     1353    if l == 19:
     1354        data['hyper_poly'] = Zu([-8, 20, -8, -8, 1])
     1355        data['A2'] = Zu([-114, 57, 171])
     1356        data['A4'] = Zuv(Zu([-1020, 444, 2733, 726, -543]) + v*Zu([-180, -720, -540]))
     1357        data['A6'] = Zuv(Zu([-10080, 21816, 54324, -37386, -86742, -20070, 6858]) + v*Zu([-2968, -13748, -11284, 6356, 6860]))
     1358        data['alpha'] = Zu([16000, -22400, -337440, 475456, 1562104, -1988616, -3025294, 3245960, 2833014, -2420087, -1140950, 932406, 129580, -180443, 21090, 11153, -4066, 570, -38, 1])
     1359        data['beta'] = Zu([0, 33600, -8160, -292400, 23472, 791244, 39282, -847909, -47024, 392654, -24046, -82469, 19162, 4833, -2652, 446, -34, 1])
     1360        #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)
     1361        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
     1362        data['endo_u'] = -1
     1363        return data
     1364    if l == 23:
     1365        data['hyper_poly'] = Zu([-7, 10, -11, 2, 2, -8, 1])
     1366        data['A2'] = Zu([69, -230, 253])
     1367        data['A4'] = Zuv(Zu([405, 180, -930, 2820, -795]) + v*Zu([360, -792]))
     1368        data['A6'] = Zuv(Zu([-15498, 34020, -36918, -8120, 51114, -72492, 12166]) + v*Zu([-1080, 7704, -24840, 12168]))
     1369        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])
     1370        data['beta'] = Zu( [0, 12150, -72495, 168588, -144045, -254034, 930982, -1256170, 604358, 693650, -1563176, 1271974, -225188, -444070, 421050, -184350, 47754, -7696, 759, -42, 1])
     1371        #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)
     1372        return data
     1373    if l == 29:
     1374        data['hyper_poly'] = Zu([-7, 8, 8, 2, -12, -4, 1])
     1375        data['A2'] = Zu([-174, -232, 348, 406])
     1376        data['A4'] = Zuv(Zu([-1215, -3096, 132, 7614, 6504, -360, -1263] ) + v*Zu( [180, -720, -2160, -1260]))
     1377        data['A6'] = Zuv(Zu([-18900, -63504, 24696, 285068, 285264, -185136, -506268, -275520, 504, 24388] ) + v*Zu( [4482, -2448, -59868, -94968, -18144, 48276, 24390]))
     1378        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])
     1379        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])
     1380        #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)
     1381        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
     1382        data['endo_u'] = -1
     1383        return data
     1384    if l == 31:
     1385        data['hyper_poly'] = Zu([-3, -14, -11, 18, 6, -8, 1])
     1386        data['A2'] = Zu([558, 837, -1488, 465])
     1387        data['A4'] = Zuv(Zu([-4140, -12468, 15189, 16956, -27054, 11184, -1443]) + v*Zu([2160, -7560, 6120, -1440]))
     1388        data['A6'] = Zuv(Zu([71280, 592056, -108324, -2609730, 2373048, 1282266, -2793204, 1530882, -356976, 29790]) + v*Zu([-81312, 181664, 294728, -868392, 701400, -238840, 29792]))
     1389        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])
     1390        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])
     1391        #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)
     1392        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
     1393        data['endo_u'] = 2
     1394        return data
     1395    if l == 41:
     1396        data['hyper_poly'] = Zu([-8, -20, -15, 8, 20, 10, -8, -4, 1])
     1397        data['A2'] = Zu([328, 656, -656, -1148, 820])
     1398        data['A4'] = Zuv(Zu([-1380, -4008, 1701, 10872, 6144, -18378, -2160, 9732, -2523]) + v*Zu([720, -1440, -2160, 5400, -2520]))
     1399        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]))
     1400        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])
     1401        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])
     1402        #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)
     1403        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
     1404        data['endo_u'] = 1
     1405        return data
     1406    if l == 47:
     1407        data['hyper_poly'] = Zu([-11, 28, -38, 30, -13, -16, 19, -24, 11, -6, 1])
     1408        data['A2'] = Zu([376, -1504, 2209, -1598, 1081])
     1409        data['A4'] = Zuv(Zu([2400, -4080, -1440, 18000, -26355, 34740, -22050, 12900, -3315]) + v*Zu([1152, -3384, 3672, -3312]))
     1410        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]))
     1411        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])
     1412        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])
     1413        #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)
     1414        return data
     1415    if l == 59:
     1416        data['hyper_poly'] = Zu([-8, -4, 20, -24, -3, 40, -62, 40, 3, -28, 22, -8, 1])
     1417        data['A2'] = Zu([590, -1475, -295, 4130, -4425, 1711])
     1418        data['A4'] = Zuv(Zu([-2460, 8844, -3843, -20718, 57153, -50418, -12600, 72762, -69339, 30978, -5223]) + v*Zu([900, 360, -7560, 10800, -5220]))
     1419        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]))
     1420        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])
     1421        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])
     1422        #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)
     1423        return data
     1424    if l == 71:
     1425        data['hyper_poly'] = Zu([-7, 6, -27, 40, -58, 66, -66, 40, 15, -48, 66, -66, 37, -10, 1])
     1426        data['A2'] = Zu([213, -1420, 4260, -4970, 9940, -9088, 2485])
     1427        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]))
     1428        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]))
     1429        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])
     1430        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])
     1431        #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)
     1432        return data
     1433
     1434@cached_function
     1435def Psi2(l):
     1436    """
     1437    Returns the generic kernel polynomial for hyperelliptic `l`-isogenies.
     1438
     1439    INPUT:
     1440
     1441    - ``l`` -- either 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1442
     1443    OUTPUT:
     1444
     1445    The generic `l`-kernel polynomial.
     1446
     1447    TESTS::
     1448
     1449        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import Psi2
     1450        sage: Psi2(11)
     1451        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
     1452
     1453    """
     1454    if not l in hyperelliptic_primes:
     1455        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1456
     1457    data = _hyperelliptic_isogeny_data(l)
     1458    R = PolynomialRing(QQ,['x','u'])
     1459    x, u = R.gens()
     1460    L = PolynomialRing(R,'y')
     1461    y = L.gen()
     1462    K = R.extension(y**2-R(data['hyper_poly']),name = 'v')
     1463    v = K.gen()
     1464    from sage.categories.homset import Hom
     1465    h = Hom(K,K)(-v)
     1466
     1467    A = K(data['A4'])
     1468    B = K(data['A6'])
     1469    Abar = h(A)*l**2
     1470    Bbar = -h(B)*l**3
     1471    s1 = K(data['A2'])
     1472
     1473    d = (l-1)//2
     1474    s = [1]
     1475    t = [d,s1,((1-10*d)*A - Abar)*(1/QQ(30))]
     1476    t += [((1-28*d)*B - 42*t[1]*A - Bbar)*(1/QQ(70))]
     1477    c = [0,6*t[2] + 2*A*t[0],10*t[3] + 6*A*t[1] + 4*B*t[0]]
     1478    for n in range(2,d):
     1479        k = sum(c[i]*c[n-i] for i in range(1,n))
     1480        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)))]
     1481    for n in range(3,d):
     1482        t += [(c[n]-(4*n-2)*A*t[n-1]-(4*n-4)*B*t[n-2])*(1/QQ(4*n+2))]
     1483    for n in range(1,d+1):
     1484        s += [(-1/QQ(n))*sum((-1)**i*t[i]*s[n-i] for i in range(1,n+1))]
     1485    psi = sum((-1)**i*s[i]*x**(d-i) for i in range(0,d+1))
     1486    R = PolynomialRing(QQ,['x','u','v'])
     1487    return R(psi)
     1488
     1489
     1490def isogenies_prime_degree_genus_plus_0(E, l=None):
     1491    """
     1492    Returns list of ``l`` -isogenies with domain ``E``.
     1493
     1494    INPUT:
     1495
     1496    - ``E`` -- an elliptic curve.
     1497
     1498    - ``l`` -- either None or 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1499
     1500    OUTPUT:
     1501
     1502    (list) When ``l`` is None a list of all isogenies of degree 11, 17, 19, 23,
     1503    29, 31, 41, 47, 59, or 71, otherwise a list of isogenies of the given degree.
     1504
     1505    .. note::
     1506
     1507       This function would normally be invoked indirectly via
     1508       ``E.isogenies_prime_degree(l)``, which automatically calls the appropriate function.
     1509
     1510    ALGORITHM::
     1511
     1512    See [KT2013]_, Chapter 5.
     1513
     1514    EXAMPLES::
     1515
     1516        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0
     1517
     1518        sage: E = EllipticCurve('121a1')
     1519        sage: isogenies_prime_degree_genus_plus_0(E, 11)
     1520        [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]
     1521
     1522        sage: E = EllipticCurve([1, 1, 0, -660, -7600])
     1523        sage: isogenies_prime_degree_genus_plus_0(E, 17)
     1524        [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]
     1525
     1526        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1527        sage: isogenies_prime_degree_genus_plus_0(E, 19)
     1528        [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]
     1529
     1530        sage: K = QuadraticField(-295,'a')
     1531        sage: a = K.gen()
     1532        sage: E = EllipticCurve_from_j(-484650135/16777216*a + 4549855725/16777216)
     1533        sage: isogenies_prime_degree_genus_plus_0(E, 23)
     1534        [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]
     1535
     1536        sage: K = QuadraticField(-199,'a')
     1537        sage: a = K.gen()
     1538        sage: E = EllipticCurve_from_j(94743000*a + 269989875)
     1539        sage: isogenies_prime_degree_genus_plus_0(E, 29)
     1540        [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]
     1541
     1542        sage: K = QuadraticField(253,'a')
     1543        sage: a = K.gen()
     1544        sage: E = EllipticCurve_from_j(208438034112000*a - 3315409892960000)
     1545        sage: isogenies_prime_degree_genus_plus_0(E, 31)
     1546        [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]
     1547
     1548        sage: E = EllipticCurve_from_j(GF(5)(1))
     1549        sage: isogenies_prime_degree_genus_plus_0(E, 41)
     1550        [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]
     1551
     1552        sage: K = QuadraticField(5,'a')
     1553        sage: a = K.gen()
     1554        sage: E = EllipticCurve_from_j(184068066743177379840*a - 411588709724712960000)
     1555        sage: isogenies_prime_degree_genus_plus_0(E, 47) # long time (4.3s)
     1556        [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]
     1557
     1558        sage: K = QuadraticField(-66827,'a')
     1559        sage: a = K.gen()
     1560        sage: E = EllipticCurve_from_j(-98669236224000*a + 4401720074240000)
     1561        sage: isogenies_prime_degree_genus_plus_0(E, 59)   # long time (25s, 2012)
     1562        [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]
     1563
     1564        sage: E = EllipticCurve_from_j(GF(13)(5))
     1565        sage: isogenies_prime_degree_genus_plus_0(E, 71) # long time
     1566        [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]
     1567
     1568        sage: E = EllipticCurve(GF(13),[0,1,1,1,0])
     1569        sage: isogenies_prime_degree_genus_plus_0(E)
     1570        [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,
     1571        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,
     1572        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,
     1573        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,
     1574        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,
     1575        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]
     1576
     1577    """
     1578    if l is None:
     1579        return sum([isogenies_prime_degree_genus_plus_0(E, l) for l in hyperelliptic_primes],[])
     1580
     1581    if not l in hyperelliptic_primes:
     1582        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1583
     1584    F = E.base_ring()
     1585    j = E.j_invariant()
     1586    if F.characteristic() in [2, 3, l]:
     1587        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.")
     1588
     1589    if j == F(0):
     1590        return isogenies_prime_degree_genus_plus_0_j0(E, l)
     1591    if j == F(1728):
     1592        return isogenies_prime_degree_genus_plus_0_j1728(E, l)
     1593
     1594    Fu = PolynomialRing(F,'u')
     1595    u = Fu.gen()
     1596    Fuv = PolynomialRing(F,['u','v'])
     1597    Fxuv = PolynomialRing(F,['x','u','v'])
     1598    X = u
     1599    data = _hyperelliptic_isogeny_data(l)
     1600    a = Fu(data['alpha'])
     1601    b = Fu(data['beta'])
     1602    f = Fu(data['hyper_poly'])
     1603    P = a
     1604    Q = Fu((a**2 - f*b**2)/Fu(4))
     1605    u_list = (j**2-P*j+Q).roots(multiplicities=False)
     1606
     1607    S = []
     1608    for u0 in u_list:
     1609        if b(u0) == 0:
     1610            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1611        else:
     1612            S += [[u0,(2*j-a(u0))/b(u0)]]
     1613    if len(S) == 0:
     1614        return []
     1615    S.sort()
     1616
     1617    c4, c6 = E.c_invariants()
     1618    b2 = E.b2()
     1619    kernels = []
     1620
     1621    psi = Fxuv(Psi2(l))
     1622    for u0, v0 in S:
     1623        A4 = Fuv(data['A4'])(u0,v0) #non-zero since j!=0
     1624        A6 = Fuv(data['A6'])(u0,v0) #non-zero since j!=1728
     1625        T = (c4*A6)/(2*c6*A4)
     1626        kernels += [psi((36*X+3*b2)*T,u0,v0).monic()]
     1627    return [E.isogeny(ker) for ker in kernels]
     1628
     1629
     1630
     1631def isogenies_prime_degree_genus_plus_0_j0(E, l):
     1632    """
     1633    Returns a list of hyperelliptic ``l`` -isogenies  with domain ``E`` when `j(E)=0`.
     1634
     1635    INPUT:
     1636
     1637    - ``E`` -- an elliptic curve with j-invariant 0.
     1638
     1639    - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1640
     1641    OUTPUT:
     1642
     1643    (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1644
     1645    .. note::
     1646
     1647       This implementation requires that the characteristic is not 2, 3 or ``l``.
     1648
     1649    .. note::
     1650
     1651       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
     1652
     1653    EXAMPLES::
     1654
     1655        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j0
     1656
     1657        sage: u = polygen(QQ)
     1658        sage: K.<a> = NumberField(u^4+228*u^3+486*u^2-540*u+225)
     1659        sage: E = EllipticCurve(K,[0,-121/5*a^3-20691/5*a^2-29403/5*a+3267])
     1660        sage: isogenies_prime_degree_genus_plus_0_j0(E,11)
     1661        [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]
     1662
     1663        sage: E = EllipticCurve(GF(5^6,'a'),[0,1])
     1664        sage: isogenies_prime_degree_genus_plus_0_j0(E,17)
     1665        [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]
     1666    """
     1667    if not l in hyperelliptic_primes:
     1668        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1669    F = E.base_field()
     1670    if E.j_invariant() != 0:
     1671        raise ValueError,("j-invariant must be 0.")
     1672    if F.characteristic() in [2,3,l]:
     1673        raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
     1674
     1675    Fu = PolynomialRing(F,'u')
     1676    u = Fu.gen()
     1677    Fuv = PolynomialRing(F,['u','v'])
     1678    Fxuv = PolynomialRing(F,['x','u','v'])
     1679    X = u
     1680    data = _hyperelliptic_isogeny_data(l)
     1681    a = Fu(data['alpha'])
     1682    b = Fu(data['beta'])
     1683    f = Fu(data['hyper_poly'])
     1684    Q = Fu((a**2 - f*b**2)/Fu(4))
     1685    u_list = Q.roots(multiplicities=False)
     1686    c6, b2 = E.c6(), E.b2()
     1687    kernels = []
     1688
     1689    if l % 3 == 1 and F(-3).is_square():
     1690        p = F(-3).sqrt()
     1691        endo = Fxuv(data['endo'])
     1692        kernels += [endo(36*X+3*b2,p,-54*c6).monic(), endo(36*X+3*b2,-p,-54*c6).monic()]
     1693
     1694    S = []
     1695    for u0 in u_list:
     1696        if l % 3 == 1 and u0 == F(data['endo_u']):
     1697            continue
     1698        if b(u0) == 0:
     1699            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1700        else:
     1701            S += [[u0,-a(u0)/b(u0)]]
     1702    if len(S)==0 and len(kernels) == 0:
     1703        return []
     1704    S.sort()
     1705
     1706    psi = Fxuv(Psi2(l))
     1707    for u0,v0 in S:
     1708        A6 = Fuv(data['A6'])(u0,v0) # non-zero since j!=1728
     1709        kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**3-A6/(-54*c6)).roots(multiplicities=False)]
     1710    return [E.isogeny(ker) for ker in kernels]
     1711
     1712def isogenies_prime_degree_genus_plus_0_j1728(E, l):
     1713    """
     1714    Returns a list of ``l`` -isogenies  with domain ``E`` when `j(E)=1728`.
     1715
     1716    INPUT:
     1717
     1718    - ``E`` -- an elliptic curve with j-invariant 1728.
     1719
     1720    - ``l`` -- 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71. 
     1721
     1722    OUTPUT:
     1723
     1724    (list) a list of all isogenies of degree 11, 17, 19, 23, 29, 31, 41, 47, 59, or 71.
     1725
     1726    .. note::
     1727
     1728       This implementation requires that the characteristic is not 2, 3 or ``l``.
     1729
     1730    .. note::
     1731
     1732       This function would normally be invoked indirectly via ``E.isogenies_prime_degree(l)``.
     1733
     1734    EXAMPLES::
     1735
     1736        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_genus_plus_0_j1728
     1737
     1738        sage: u = polygen(QQ)
     1739        sage: K.<a> = NumberField(u^6 - 522*u^5 - 10017*u^4 + 2484*u^3 - 5265*u^2 + 12150*u - 5103)
     1740        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])
     1741        sage: isogenies_prime_degree_genus_plus_0_j1728(E,11)
     1742        [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]
     1743    """
     1744    if not l in  hyperelliptic_primes:
     1745        raise ValueError("%s must be one of %s."%(l,hyperelliptic_primes))
     1746    F = E.base_ring()
     1747    if E.j_invariant() != 1728:
     1748        raise ValueError("j-invariant must be 1728.")
     1749    if F.characteristic() in [2,3,l]:
     1750        raise NotImplementedError("Not implemented in characteristic 2, 3 or l.")
     1751
     1752    Fu = PolynomialRing(F,'u')
     1753    u = Fu.gen()
     1754    Fuv = PolynomialRing(F,['u','v'])
     1755    Fxuv = PolynomialRing(F,['x','u','v'])
     1756    X = u
     1757    data = _hyperelliptic_isogeny_data(l)
     1758    a = Fu(data['alpha'])
     1759    b = Fu(data['beta'])
     1760    f = Fu(data['hyper_poly'])
     1761    P = a
     1762    Q = Fu((a**2 - f*b**2)/Fu(4))
     1763    u_list = (1728**2-P*1728+Q).roots(multiplicities=False)
     1764    c4, b2 = E.c4(), E.b2()
     1765    kernels = []
     1766
     1767    if l % 4 == 1 and  F(-1).is_square():
     1768        i = F(-1).sqrt()
     1769        endo = Fxuv(data['endo'])
     1770        kernels += [endo(X,i,-27*c4).monic(), endo(X,-i,-27*c4).monic()]
     1771
     1772    S = []
     1773    for u0 in u_list:
     1774        if l % 4 == 1 and u0 == F(data['endo_u']):
     1775            continue
     1776        if b(u0) == 0:
     1777            S += [[u0,v0] for v0 in (X**2-f(u0)).roots(multiplicities=False)]
     1778        else:
     1779            S += [[u0,(2*1728-a(u0))/b(u0)]]
     1780    if len(S)==0 and len(kernels) == 0:
     1781        return []
     1782    S.sort()
     1783
     1784    psi = Fxuv(Psi2(l))
     1785    for u0,v0 in S:
     1786        A4 = Fuv(data['A4'])(u0,v0) # non-zero since j!=0
     1787        kernels += [psi((36*X+3*b2)*T,u0,v0).monic() for T in (X**2-A4/(-27*c4)).roots(multiplicities=False)]
     1788    return [E.isogeny(ker) for ker in kernels]
     1789
     1790@cached_function
     1791def _least_semi_primitive(p):
     1792    """
     1793    Returns the smallest semi-primitive root modulo `p`, i.e., generator of the group `(\ZZ/p\ZZ)^*/\{1,-1\}`.
     1794
     1795    INPUT:
     1796
     1797    - ``p`` -- an odd prime.
     1798
     1799    OUTPUT:
     1800
     1801    the smallest semi-primitive root modulo `p`.
     1802
     1803    .. note::
     1804
     1805       This function would normally be invoked indirectly via ``E.isogenies_prime_degree_general(l)``.
     1806
     1807    EXAMPLES::
     1808
     1809        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import _least_semi_primitive
     1810        sage: _least_semi_primitive(5)
     1811        2
     1812        sage: _least_semi_primitive(13)
     1813        2
     1814        sage: _least_semi_primitive(17)
     1815        3
     1816        sage: _least_semi_primitive(73)
     1817        5
     1818        sage: _least_semi_primitive(997)
     1819        7
     1820    """
     1821    if not p.is_prime() or p<3:
     1822        raise ValueError("%s is not an odd prime"%p)
     1823
     1824    def is_semi_primitive(a,p):
     1825        from sage.rings.finite_rings.integer_mod_ring import Integers
     1826        d = Integers(p)(a).multiplicative_order()
     1827        if p%4==1:
     1828            return (d==p-1)
     1829        else:
     1830            return d >= (p-1)/2
     1831
     1832    a = 2
     1833    while not is_semi_primitive(a,p):
     1834        a += 1
     1835    return a
     1836
     1837
     1838def isogenies_prime_degree_general(E, l):
     1839    """
     1840    Returns a list of ``l`` -isogenies  with domain ``E``.
     1841
     1842    INPUT:
     1843
     1844    - ``E`` -- an elliptic curve.
     1845
     1846    - ``l`` -- a prime. 
     1847
     1848    OUTPUT:
     1849
     1850    (list) a list of all isogenies of degree l.
     1851
     1852    ALGORITHM::
     1853
     1854    This algorithm factors the ``l``-division polynomial, then
     1855    combines its factors to otain kernels. See [KT2013]_, Chapter 3.
     1856
     1857    .. note::
     1858
     1859       This function works for any prime `l`.  Normally one should use
     1860       the function :meth:`isogenies_prime_degree` which uses special
     1861       functions for certain small primes.
     1862
     1863    EXAMPLES::
     1864
     1865        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
     1866        sage: E = EllipticCurve_from_j(GF(2^6,'a')(1))
     1867        sage: isogenies_prime_degree_general(E, 7)
     1868        [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]
     1869        sage: E = EllipticCurve_from_j(GF(3^12,'a')(2))
     1870        sage: isogenies_prime_degree_general(E, 17)
     1871        [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]
     1872        sage: E = EllipticCurve('50a1')
     1873        sage: isogenies_prime_degree_general(E, 3)
     1874        [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]
     1875        sage: isogenies_prime_degree_general(E, 5)
     1876        [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]
     1877        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1878        sage: isogenies_prime_degree_general(E, 19)
     1879        [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]
     1880        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     1881        sage: isogenies_prime_degree_general(E, 37)  # long time (10s)
     1882        [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]
     1883
     1884        sage: E = EllipticCurve([-3440, 77658])
     1885        sage: isogenies_prime_degree_general(E, 43)  # long time (16s)
     1886        [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]
     1887
     1888    Isogenies of degree equal to the characteristic are computed (but
     1889    only the separable isogeny).  In the following example we consider
     1890    an elliptic curve which is supersingular in characteristic 2
     1891    only::
     1892
     1893        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree_general
     1894        sage: ainvs = (0,1,1,-1,-1)
     1895        sage: for l in prime_range(50):
     1896        ....:     E = EllipticCurve(GF(l),ainvs)
     1897        ....:     isogenies_prime_degree_general(E,l)
     1898        []
     1899        [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]
     1900        [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]
     1901        [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]
     1902        [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]
     1903        [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]
     1904        [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]
     1905        [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]
     1906        [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]
     1907        [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]
     1908        [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]
     1909        [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]
     1910        [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]
     1911        [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]
     1912        [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]
     1913
     1914    """
     1915    if not l.is_prime():
     1916        raise ValueError("%s is not prime."%l)
     1917    if l==2:
     1918        return isogenies_2(E)
     1919    if l==3:
     1920        return isogenies_3(E)
     1921
     1922    psi_l = E.division_polynomial(l)
     1923    factors = [h for h,e in psi_l.factor() if (l-1)/2 % h.degree() == 0]
     1924    a = _least_semi_primitive(l)
     1925    m = E.multiplication_by_m(a, x_only=True)
     1926    F = psi_l.parent()
     1927    x = F.gen()
     1928    ker = []
     1929    from sage.rings.arith import gcd
     1930    from sage.misc.all import prod
     1931    def mult(f):
     1932        return gcd(F(f(m([x,0])).numerator()),psi_l).monic()
     1933    while len(factors) > 0:
     1934        f = factors[0]
     1935        factors.remove(f)
     1936        d = f.degree()
     1937        S = [f]
     1938        for i in range((l-1)/(2*d)-1):
     1939            g = mult(S[i])
     1940            S.append(g)
     1941            if g in factors:
     1942                factors.remove(g)
     1943        if mult(S[-1]) == f:
     1944            ker.append(prod(S))
     1945    return [E.isogeny(k) for k in ker]
     1946
     1947def isogenies_prime_degree(E, l):
     1948    """
     1949    Returns a list of ``l`` -isogenies  with domain ``E``.
     1950
     1951    INPUT:
     1952
     1953    - ``E`` -- an elliptic curve.
     1954
     1955    - ``l`` -- a prime. 
     1956
     1957    OUTPUT:
     1958
     1959    (list) a list of all isogenies of degree `l`.  If the
     1960    characteristic is `l` then only separable isogenies are
     1961    constructed.
     1962
     1963    EXAMPLES::
     1964
     1965        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
     1966        sage: E = EllipticCurve_from_j(GF(2^6,'a')(1))
     1967        sage: isogenies_prime_degree(E, 7)
     1968        [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]
     1969        sage: E = EllipticCurve_from_j(GF(3^12,'a')(2))
     1970        sage: isogenies_prime_degree(E, 17)
     1971        [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]
     1972        sage: E = EllipticCurve('50a1')
     1973        sage: isogenies_prime_degree(E, 3)
     1974        [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]
     1975        sage: isogenies_prime_degree(E, 5)
     1976        [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]
     1977        sage: E = EllipticCurve([0, 0, 1, -1862, -30956])
     1978        sage: isogenies_prime_degree(E, 19)
     1979        [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]
     1980        sage: E = EllipticCurve([0, -1, 0, -6288, 211072])
     1981        sage: isogenies_prime_degree(E, 37)
     1982        [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]
     1983
     1984
     1985    Isogenies of degree equal to the characteristic are computed (but
     1986    only the separable isogeny).  In the following example we consider
     1987    an elliptic curve which is supersingular in characteristic 2
     1988    only::
     1989
     1990        sage: from sage.schemes.elliptic_curves.isogeny_small_degree import isogenies_prime_degree
     1991        sage: ainvs = (0,1,1,-1,-1)
     1992        sage: for l in prime_range(50):
     1993        ....:     E = EllipticCurve(GF(l),ainvs)
     1994        ....:     isogenies_prime_degree(E,l)
     1995        []
     1996        [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]
     1997        [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]
     1998        [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]
     1999        [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]
     2000        [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]
     2001        [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]
     2002        [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]
     2003        [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]
     2004        [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]
     2005        [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]
     2006        [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]
     2007        [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]
     2008        [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]
     2009        [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]
     2010
     2011    Note that the computation is faster for degrees equal to one of
     2012    the genus 0 primes (2, 3, 5, 7, 13) or one of the hyperelliptic
     2013    primes (11, 17, 19, 23, 29, 31, 41, 47, 59, 71) than when the
     2014    generic code must be used::
     2015
     2016        sage: E = EllipticCurve(GF(101), [-3440, 77658])
     2017        sage: E.isogenies_prime_degree(71) # fast
     2018        []
     2019        sage: E.isogenies_prime_degree(73) # not tested (very long time: 32s)
     2020        []
     2021
     2022
     2023    """
     2024    if not l.is_prime():
     2025        raise ValueError("%s is not prime."%l)
     2026    if l==2:
     2027        return isogenies_2(E)
     2028    if l==3:
     2029        return isogenies_3(E)
     2030
     2031    p = E.base_ring().characteristic()
     2032    if l==p:
     2033        return isogenies_prime_degree_general(E,l)
     2034
     2035    if l in [5,7,13] and not p in [2,3]:
     2036        return isogenies_prime_degree_genus_0(E,l)
     2037
     2038    if l in hyperelliptic_primes and not p in [2,3]:
     2039        return isogenies_prime_degree_genus_plus_0(E,l)
     2040
     2041    return isogenies_prime_degree_general(E,l)