Ticket #5890: trac_5890.patch

File trac_5890.patch, 49.6 KB (added by AlexGhitza, 10 years ago)

depends on the latest patch at #5765

  • sage/schemes/elliptic_curves/all.py

    # HG changeset patch
    # User Alexandru Ghitza <aghitza@alum.mit.edu>
    # Date 1240634966 -36000
    # Node ID b6ee31a996da68da5f2300e55e634541e960de92
    # Parent  1cb3a80b55756075242b624d8c5e72a599546acf
    trac 5890: clean up ell_generic.py
    
    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/elliptic_curves/all.py
    a b  
    2222                         EllipticCurves_with_good_reduction_outside_S)
    2323
    2424
    25 from ell_generic import is_EllipticCurve, Hasse_bounds
     25from ell_generic import is_EllipticCurve
    2626
    2727from ell_rational_field import cremona_curves, cremona_optimal_curves
    2828
  • sage/schemes/elliptic_curves/ell_field.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/elliptic_curves/ell_field.py
    a b  
    1515#*****************************************************************************
    1616
    1717import ell_generic
     18import sage.rings.all as rings
     19from constructor import EllipticCurve
    1820
    1921class EllipticCurve_field(ell_generic.EllipticCurve_generic):
    20     pass
     22
     23    base_field = ell_generic.EllipticCurve_generic.base_ring
     24
     25    # Twists: rewritten by John Cremona as follows:
     26    #
     27    # Quadratic twist allowed except when char=2, j=0
     28    # Quartic twist allowed only if j=1728!=0 (so char!=2,3)
     29    # Sextic  twist allowed only if j=0!=1728 (so char!=2,3)
     30    #
     31    # More complicated twists exist in theory for char=2,3 and
     32    # j=0=1728, but I have never worked them out or seen them used!
     33    #                                             
     34
     35    r"""
     36    Twists: rewritten by John Cremona as follows:
     37
     38    The following twists are implemented:
     39   
     40    - Quadratic twist:  except when char=2 and `j=0`.
     41    - Quartic twist: only if `j=1728\not=0` (so not if char=2,3).
     42    - Sextic  twist: only if `j=0\not=1728` (so not if char=2,3).
     43   
     44    More complicated twists exist in theory for char=2,3 and
     45    j=0=1728, but are not implemented.
     46    """
     47
     48    def quadratic_twist(self, D=None):
     49        """
     50        Return the quadratic twist of this curve by ``D``.
     51
     52        INPUT:
     53
     54        - ``D`` (default None) the twisting parameter (see below).
     55       
     56        In characteristics other than 2, `D` must be nonzero, and the twist is
     57        isomorphic to self after adjoining `\sqrt(D)` to the base.
     58       
     59        In characteristic 2, `D` is arbitrary, and the twist is isomorphic
     60        to self after adjoining a root of `x^2+x+D` to the base.
     61       
     62        In characteristic 2 when `j=0`, this is not implemented.
     63       
     64        If the base field `F` is finite, `D` need not be specified, and
     65        the curve returned is the unique curve (up to isomorphism)
     66        defined over `F` isomorphic to the original curve over the
     67        quadratic extension of `F` but not over `F` itself.  Over infinte
     68        fields, an error is raised if `D` is not given.
     69
     70        EXAMPLES::
     71       
     72            sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E
     73            Elliptic Curve defined by y^2 + x*y  = x^3 + 107*x + 340 over Finite Field of size 1103
     74            sage: F=E.quadratic_twist(-1); F
     75            Elliptic Curve defined by y^2  = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 1103
     76            sage: E.is_isomorphic(F)
     77            False
     78            sage: E.is_isomorphic(F,GF(1103^2,'a'))
     79            True
     80       
     81        A characteristic 2 example::
     82       
     83            sage: E=EllipticCurve(GF(2),[1,0,1,1,1])
     84            sage: E1=E.quadratic_twist(1)
     85            sage: E.is_isomorphic(E1)
     86            False
     87            sage: E.is_isomorphic(E1,GF(4,'a'))
     88            True
     89           
     90        Over finite fields, the twisting parameter may be omitted::
     91       
     92            sage: k.<a> = GF(2^10)
     93            sage: E = EllipticCurve(k,[a^2,a,1,a+1,1])
     94            sage: Et = E.quadratic_twist()
     95            sage: Et # random (only determined up to isomorphism)
     96            Elliptic Curve defined by y^2 + x*y  = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) over Finite Field in a of size 2^10
     97            sage: E.is_isomorphic(Et)
     98            False
     99            sage: E.j_invariant()==Et.j_invariant()
     100            True
     101
     102            sage: p=next_prime(10^10)
     103            sage: k = GF(p)
     104            sage: E = EllipticCurve(k,[1,2,3,4,5])
     105            sage: Et = E.quadratic_twist()
     106            sage: Et # random (only determined up to isomorphism)
     107            Elliptic Curve defined by y^2  = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019
     108            sage: E.is_isomorphic(Et)
     109            False
     110            sage: k2 = GF(p^2,'a')
     111            sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2))
     112            True
     113        """
     114        K=self.base_ring()
     115        char=K.characteristic()
     116
     117        if D is None:
     118            if K.is_finite():
     119                x = rings.polygen(K) 
     120                if char==2:
     121                    # We find D such that x^2+x+D is irreducible. If the
     122                    # degree is odd we can take D=1; otherwise it suffices to
     123                    # consider odd powers of a generator.
     124                    D = K(1)
     125                    if K.degree()%2==0:
     126                        D = K.gen()
     127                        a = D**2
     128                        while len((x**2+x+D).roots())>0:
     129                            D *= a
     130                else:
     131                    # We could take a multiplicative generator but
     132                    # that might be expensive to compute; otherwise
     133                    # half the elements will do
     134                    D = K.random_element()
     135                    while len((x**2-D).roots())>0:
     136                        D = K.random_element()
     137            else:
     138                raise ValueError, "twisting parameter D must be specified over infinite fields."
     139        else:
     140            try:
     141                D=K(D)
     142            except ValueError:
     143                raise ValueError, "twisting parameter D must be in the base field."
     144       
     145            if char!=2 and D.is_zero():
     146                raise ValueError, "twisting parameter D must be nonzero when characteristic is not 2"
     147
     148        if char!=2:
     149            b2,b4,b6,b8=self.b_invariants()
     150            # E is isomorphic to  [0,b2,0,8*b4,16*b6]
     151            return EllipticCurve(K,[0,b2*D,0,8*b4*D**2,16*b6*D**3])
     152
     153        # now char==2
     154        if self.j_invariant() !=0: # iff a1!=0
     155            a1,a2,a3,a4,a6=self.ainvs()
     156            E0=self.change_weierstrass_model(a1,a3/a1,0,(a1**2*a4+a3**2)/a1**3)
     157            # which has the form = [1,A2,0,0,A6]
     158            assert E0.a1()==K(1)
     159            assert E0.a3()==K(0)
     160            assert E0.a4()==K(0)
     161            return EllipticCurve(K,[1,E0.a2()+D,0,0,E0.a6()])
     162        else:
     163            raise ValueError, "Quadratic twist not implemented in char 2 when j=0"
     164
     165    def quartic_twist(self, D):
     166        r"""
     167        Return the quartic twist of this curve by `D`.
     168
     169        INPUT:
     170
     171        - ``D`` (must be nonzero) -- the twisting parameter..
     172       
     173        .. note::
     174
     175           The characteristic must not be 2 or 3, and the `j`-invariant must be 1728.
     176       
     177        EXAMPLES::
     178       
     179            sage: E=EllipticCurve_from_j(GF(13)(1728)); E
     180            Elliptic Curve defined by y^2  = x^3 + x over Finite Field of size 13
     181            sage: E1=E.quartic_twist(2); E1
     182            Elliptic Curve defined by y^2  = x^3 + 5*x over Finite Field of size 13
     183            sage: E.is_isomorphic(E1)
     184            False
     185            sage: E.is_isomorphic(E1,GF(13^2,'a'))
     186            False
     187            sage: E.is_isomorphic(E1,GF(13^4,'a'))
     188            True
     189        """
     190        K=self.base_ring()
     191        char=K.characteristic()
     192        D=K(D)
     193       
     194        if char==2 or char==3:
     195            raise ValueError, "Quartic twist not defined in chars 2,3"
     196
     197        if self.j_invariant() !=K(1728):
     198            raise ValueError, "Quartic twist not defined when j!=1728"
     199
     200        if D.is_zero():
     201            raise ValueError, "quartic twist requires a nonzero argument"
     202
     203        c4,c6=self.c_invariants()
     204        # E is isomorphic to  [0,0,0,-27*c4,0]
     205        assert c6==0
     206        return EllipticCurve(K,[0,0,0,-27*c4*D,0])
     207
     208    def sextic_twist(self, D):
     209        r"""
     210        Return the quartic twist of this curve by `D`.
     211
     212        INPUT:
     213
     214        - ``D`` (must be nonzero) -- the twisting parameter..
     215       
     216        .. note::
     217
     218           The characteristic must not be 2 or 3, and the `j`-invariant must be 0.
     219       
     220        EXAMPLES::
     221       
     222            sage: E=EllipticCurve_from_j(GF(13)(0)); E
     223            Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13
     224            sage: E1=E.sextic_twist(2); E1
     225            Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13
     226            sage: E.is_isomorphic(E1)
     227            False
     228            sage: E.is_isomorphic(E1,GF(13^2,'a'))
     229            False
     230            sage: E.is_isomorphic(E1,GF(13^4,'a'))
     231            False
     232            sage: E.is_isomorphic(E1,GF(13^6,'a'))
     233            True
     234        """
     235        K=self.base_ring()
     236        char=K.characteristic()
     237        D=K(D)
     238       
     239        if char==2 or char==3:
     240            raise ValueError, "Sextic twist not defined in chars 2,3"
     241
     242        if self.j_invariant() !=K(0):
     243            raise ValueError, "Sextic twist not defined when j!=0"
     244
     245        if D.is_zero():
     246            raise ValueError, "Sextic twist requires a nonzero argument"
     247
     248        c4,c6=self.c_invariants()
     249        # E is isomorphic to  [0,0,0,0,-54*c6]
     250        assert c4==0
     251        return EllipticCurve(K,[0,0,0,0,-54*c6*D])
     252
     253    def is_quadratic_twist(self, other):
     254        r"""
     255        Determine whether this curve is a quadratic twist of another.
     256
     257        INPUT:
     258               
     259        - ``other`` -- an elliptic curves with the same base field as self.
     260
     261        OUTPUT:
     262
     263        Either 0, if the curves are not quadratic twists, or `D` if
     264        ``other`` is ``self.quadratic_twist(D)`` (up to isomorphism).
     265        If ``self`` and ``other`` are isomorphic, returns 1.
     266
     267        .. note::
     268
     269           Not fully implemented in characteristic 2, or in
     270           characteristic 3 when both `j`-invariants are 0.
     271
     272        EXAMPLES::
     273
     274            sage: E = EllipticCurve('11a1')
     275            sage: Et = E.quadratic_twist(-24)
     276            sage: E.is_quadratic_twist(Et)
     277            -6
     278           
     279            sage: E1=EllipticCurve([0,0,1,0,0])
     280            sage: E1.j_invariant()
     281            0
     282            sage: E2=EllipticCurve([0,0,0,0,2])
     283            sage: E1.is_quadratic_twist(E2)
     284            2
     285           
     286        ::   
     287
     288            sage: E1=EllipticCurve([0,0,0,1,0])
     289            sage: E1.j_invariant()
     290            1728
     291            sage: E2=EllipticCurve([0,0,0,2,0])
     292            sage: E1.is_quadratic_twist(E2)
     293            0
     294            sage: E2=EllipticCurve([0,0,0,25,0])
     295            sage: E1.is_quadratic_twist(E2)
     296            5
     297           
     298        ::   
     299
     300            sage: F = GF(101)
     301            sage: E1 = EllipticCurve(F,[4,7])
     302            sage: E2 = E1.quadratic_twist()
     303            sage: D = E1.is_quadratic_twist(E2); D!=0
     304            True
     305            sage: F = GF(101)
     306            sage: E1 = EllipticCurve(F,[4,7])
     307            sage: E2 = E1.quadratic_twist()
     308            sage: D = E1.is_quadratic_twist(E2)
     309            sage: E1.quadratic_twist(D).is_isomorphic(E2)
     310            True
     311            sage: E1.is_isomorphic(E2)
     312            False
     313            sage: F2 = GF(101^2,'a')
     314            sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))
     315            True
     316           
     317        A characteristic 3 example::
     318
     319            sage: F = GF(3^5,'a')
     320            sage: E1 = EllipticCurve_from_j(F(1))
     321            sage: E2 = E1.quadratic_twist(-1)
     322            sage: D = E1.is_quadratic_twist(E2); D!=0
     323            True
     324            sage: E1.quadratic_twist(D).is_isomorphic(E2)
     325            True
     326           
     327        ::   
     328
     329            sage: E1 = EllipticCurve_from_j(F(0))
     330            sage: E2 = E1.quadratic_twist()
     331            sage: D = E1.is_quadratic_twist(E2); D
     332            1
     333            sage: E1.is_isomorphic(E2)
     334            True
     335
     336        """
     337        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     338        E = self
     339        F = other
     340        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     341            raise ValueError, "arguments are not elliptic curves"
     342        K = E.base_ring()
     343        zero = K.zero_element()
     344        if not K == F.base_ring():
     345            return zero
     346        j=E.j_invariant()
     347        if  j != F.j_invariant():
     348            return zero
     349   
     350        if E.is_isomorphic(F):
     351            return K.one_element()
     352       
     353        char=K.characteristic()
     354       
     355        if char==2:
     356            raise NotImplementedError, "not implemented in characteristic 2"
     357        elif char==3:
     358            if j==0:
     359                raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"
     360            D = E.b2()/F.b2()
     361           
     362        else:
     363            # now char!=2,3:
     364            c4E,c6E = E.c_invariants()
     365            c4F,c6F = F.c_invariants()
     366
     367            if j==0:
     368                um = c6E/c6F
     369                x=rings.polygen(K)
     370                ulist=(x**3-um).roots(multiplicities=False)
     371                if len(ulist)==0:
     372                    D = zero
     373                else:
     374                    D = ulist[0]
     375            elif j==1728:
     376                um=c4E/c4F
     377                x=rings.polygen(K)
     378                ulist=(x**2-um).roots(multiplicities=False)
     379                if len(ulist)==0:
     380                    D = zero
     381                else:
     382                    D = ulist[0]
     383            else:
     384                D = (c6E*c4F)/(c6F*c4E)
     385       
     386        # Normalization of output:
     387       
     388        if D.is_zero():
     389            return D
     390       
     391        if K is rings.QQ:
     392            D = D.squarefree_part()
     393
     394        assert E.quadratic_twist(D).is_isomorphic(F)
     395
     396        return D
     397
     398    def is_quartic_twist(self, other):
     399        r"""
     400        Determine whether this curve is a quartic twist of another.
     401
     402        INPUT:
     403               
     404        - ``other`` -- an elliptic curves with the same base field as self.
     405
     406        OUTPUT:
     407
     408        Either 0, if the curves are not quartic twists, or `D` if
     409        ``other`` is ``self.quartic_twist(D)`` (up to isomorphism).
     410        If ``self`` and ``other`` are isomorphic, returns 1.
     411
     412        .. note::
     413
     414           Not fully implemented in characteristics 2 or 3.
     415
     416        EXAMPLES::
     417
     418            sage: E = EllipticCurve_from_j(GF(13)(1728))
     419            sage: E1 = E.quartic_twist(2)
     420            sage: D = E.is_quartic_twist(E1); D!=0
     421            True
     422            sage: E.quartic_twist(D).is_isomorphic(E1)
     423            True
     424
     425        ::   
     426           
     427            sage: E = EllipticCurve_from_j(1728)
     428            sage: E1 = E.quartic_twist(12345)
     429            sage: D = E.is_quartic_twist(E1); D
     430            15999120
     431            sage: (D/12345).is_perfect_power(4)
     432            True
     433        """
     434        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     435        E = self
     436        F = other
     437        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     438            raise ValueError, "arguments are not elliptic curves"
     439        K = E.base_ring()
     440        zero = K.zero_element()
     441        if not K == F.base_ring():
     442            return zero
     443        j=E.j_invariant()
     444        if  j != F.j_invariant() or j!=K(1728):
     445            return zero
     446   
     447        if E.is_isomorphic(F):
     448            return K.one_element()
     449       
     450        char=K.characteristic()
     451       
     452        if char==2:
     453            raise NotImplementedError, "not implemented in characteristic 2"
     454        elif char==3:
     455            raise NotImplementedError, "not implemented in characteristic 3"           
     456        else:
     457            # now char!=2,3:
     458            D = F.c4()/E.c4()
     459       
     460        if D.is_zero():
     461            return D
     462       
     463        assert E.quartic_twist(D).is_isomorphic(F)
     464
     465        return D
     466
     467    def is_sextic_twist(self, other):
     468        r"""
     469        Determine whether this curve is a sextic twist of another.
     470
     471        INPUT:
     472               
     473        - ``other`` -- an elliptic curves with the same base field as self.
     474
     475        OUTPUT:
     476
     477        Either 0, if the curves are not sextic twists, or `D` if
     478        ``other`` is ``self.sextic_twist(D)`` (up to isomorphism).
     479        If ``self`` and ``other`` are isomorphic, returns 1.
     480
     481        .. note::
     482
     483           Not fully implemented in characteristics 2 or 3.
     484
     485        EXAMPLES::
     486
     487            sage: E = EllipticCurve_from_j(GF(13)(0))
     488            sage: E1 = E.sextic_twist(2)
     489            sage: D = E.is_sextic_twist(E1); D!=0
     490            True
     491            sage: E.sextic_twist(D).is_isomorphic(E1)
     492            True
     493
     494        ::   
     495
     496            sage: E = EllipticCurve_from_j(0)
     497            sage: E1 = E.sextic_twist(12345)
     498            sage: D = E.is_sextic_twist(E1); D
     499            575968320
     500            sage: (D/12345).is_perfect_power(6)
     501            True
     502        """
     503        from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
     504        E = self
     505        F = other
     506        if not is_EllipticCurve(E) or not is_EllipticCurve(F):
     507            raise ValueError, "arguments are not elliptic curves"
     508        K = E.base_ring()
     509        zero = K.zero_element()
     510        if not K == F.base_ring():
     511            return zero
     512        j=E.j_invariant()
     513        if  j != F.j_invariant() or not j.is_zero():
     514            return zero
     515   
     516        if E.is_isomorphic(F):
     517            return K.one_element()
     518       
     519        char=K.characteristic()
     520       
     521        if char==2:
     522            raise NotImplementedError, "not implemented in characteristic 2"
     523        elif char==3:
     524            raise NotImplementedError, "not implemented in characteristic 3"           
     525        else:
     526            # now char!=2,3:
     527            D = F.c6()/E.c6()
     528       
     529        if D.is_zero():
     530            return D
     531       
     532        assert E.sextic_twist(D).is_isomorphic(F)
     533
     534        return D
     535
     536   
  • sage/schemes/elliptic_curves/ell_finite_field.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/elliptic_curves/ell_finite_field.py
    a b  
    3030import sys
    3131from math import ceil, floor, sqrt
    3232
    33 from ell_generic import Hasse_bounds
     33from sage.schemes.plane_curves.projective_curve import Hasse_bounds
    3434from ell_field import EllipticCurve_field
    3535from constructor import EllipticCurve, EllipticCurve_from_j
    3636from sage.schemes.hyperelliptic_curves.hyperelliptic_finite_field import HyperellipticCurve_finite_field
  • sage/schemes/elliptic_curves/ell_generic.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/elliptic_curves/ell_generic.py
    a b  
    892892        """
    893893        return isinstance(self.base_ring(), rings.RationalField)
    894894
    895     def change_ring(self, R):
    896         r"""
    897         Return the new elliptic curve defined by coercing the
    898         `a`-invariants of this elliptic curve into the ring `R`.
    899        
    900         INPUT:       
    901        
    902         -  ``R`` - ring
    903        
    904        
    905         OUTPUT:
    906        
    907         An elliptic curve defined over ``R`` with the same `a`-invariants.
    908        
    909         EXAMPLES::
    910        
    911             sage: E = EllipticCurve([0, 0, 1, -1, 0])
    912             sage: E.change_ring(GF(3))
    913             Elliptic Curve defined by y^2 + y = x^3 + 2*x over Finite Field of size 3
    914         """
    915         return constructor.EllipticCurve(R, [R(a) for a in self.ainvs()])
    916 
    917895    def is_on_curve(self, x, y):
    918896        """
    919897        Returns True if `(x,y)` is an affine point on this curve.
     
    12671245
    12681246        OUTPUT:
    12691247
    1270         A new elliptic curve with the saem `a`-invariants, defined over the new ring.
     1248        A new elliptic curve with the same `a`-invariants, defined over the new ring.
    12711249       
    12721250        EXAMPLES::
    12731251       
     
    12851263        """
    12861264        return constructor.EllipticCurve([R(a) for a in self.a_invariants()])
    12871265
     1266    change_ring = base_extend
     1267
    12881268    def base_ring(self):
    12891269        """
    12901270        Returns the base ring of the elliptic curve.
     
    13091289        """
    13101290        return self.__base_ring
    13111291
    1312     base_field = base_ring
    1313 
    13141292    def gens(self):
    13151293        """
    13161294        Placeholder function to return generators of an elliptic curve.
     
    13521330            NotImplementedError: not implemented.
    13531331        """
    13541332        return self.gens()[i]
    1355        
    1356 
    1357     # Twists: rewritten by John Cremona as follows:
    1358     #
    1359     # Quadratic twist allowed except when char=2, j=0
    1360     # Quartic twist allowed only if j=1728!=0 (so char!=2,3)
    1361     # Sextic  twist allowed only if j=0!=1728 (so char!=2,3)
    1362     #
    1363     # More complicated twists exist in theory for char=2,3 and
    1364     # j=0=1728, but I have never worked them out or seen them used!
    1365     #                                             
    1366 
    1367     r"""
    1368     Twists: rewritten by John Cremona as follows:
    1369 
    1370     The following twists are implemented:
    1371    
    1372     - Quadratic twist:  except when char=2 and `j=0`.
    1373     - Quartic twist: only if `j=1728\not=0` (so not if char=2,3).
    1374     - Sextic  twist: only if `j=0\not=1728` (so not if char=2,3).
    1375    
    1376     More complicated twists exist in theory for char=2,3 and
    1377     j=0=1728, but are not implemented.
    1378     """
    1379 
    1380     def quadratic_twist(self, D=None):
    1381         """
    1382         Return the quadratic twist of this curve by ``D``.
    1383 
    1384         INPUT:
    1385 
    1386         - ``D`` (default None) the twisting parameter (see below).
    1387        
    1388         In characteristics other than 2, `D` must be nonzero, and the twist is
    1389         isomorphic to self after adjoining `\sqrt(D)` to the base.
    1390        
    1391         In characteristic 2, `D` is arbitrary, and the twist is isomorphic
    1392         to self after adjoining a root of `x^2+x+D` to the base.
    1393        
    1394         In characteristic 2 when `j=0`, this is not implemented.
    1395        
    1396         If the base field `F` is finite, `D` need not be specified, and
    1397         the curve returned is the unique curve (up to isomorphism)
    1398         defined over `F` isomorphic to the original curve over the
    1399         quadratic extension of `F` but not over `F` itself.  Over infinte
    1400         fields, an error is raised if `D` is not given.
    1401 
    1402         EXAMPLES::
    1403        
    1404             sage: E = EllipticCurve([GF(1103)(1), 0, 0, 107, 340]); E
    1405             Elliptic Curve defined by y^2 + x*y  = x^3 + 107*x + 340 over Finite Field of size 1103
    1406             sage: F=E.quadratic_twist(-1); F
    1407             Elliptic Curve defined by y^2  = x^3 + 1102*x^2 + 609*x + 300 over Finite Field of size 1103
    1408             sage: E.is_isomorphic(F)
    1409             False
    1410             sage: E.is_isomorphic(F,GF(1103^2,'a'))
    1411             True
    1412        
    1413         A characteristic 2 example::
    1414        
    1415             sage: E=EllipticCurve(GF(2),[1,0,1,1,1])
    1416             sage: E1=E.quadratic_twist(1)
    1417             sage: E.is_isomorphic(E1)
    1418             False
    1419             sage: E.is_isomorphic(E1,GF(4,'a'))
    1420             True
    1421            
    1422         Over finite fields, the twisting parameter may be omitted::
    1423        
    1424             sage: k.<a> = GF(2^10)
    1425             sage: E = EllipticCurve(k,[a^2,a,1,a+1,1])
    1426             sage: Et = E.quadratic_twist()
    1427             sage: Et # random (only determined up to isomorphism)
    1428             Elliptic Curve defined by y^2 + x*y  = x^3 + (a^7+a^4+a^3+a^2+a+1)*x^2 + (a^8+a^6+a^4+1) over Finite Field in a of size 2^10
    1429             sage: E.is_isomorphic(Et)
    1430             False
    1431             sage: E.j_invariant()==Et.j_invariant()
    1432             True
    1433 
    1434             sage: p=next_prime(10^10)
    1435             sage: k = GF(p)
    1436             sage: E = EllipticCurve(k,[1,2,3,4,5])
    1437             sage: Et = E.quadratic_twist()
    1438             sage: Et # random (only determined up to isomorphism)
    1439             Elliptic Curve defined by y^2  = x^3 + 7860088097*x^2 + 9495240877*x + 3048660957 over Finite Field of size 10000000019
    1440             sage: E.is_isomorphic(Et)
    1441             False
    1442             sage: k2 = GF(p^2,'a')
    1443             sage: E.change_ring(k2).is_isomorphic(Et.change_ring(k2))
    1444             True
    1445         """
    1446         K=self.base_ring()
    1447         char=K.characteristic()
    1448 
    1449         if D is None:
    1450             if K.is_finite():
    1451                 x = polygen(K) 
    1452                 if char==2:
    1453                     # We find D such that x^2+x+D is irreducible. If the
    1454                     # degree is odd we can take D=1; otherwise it suffices to
    1455                     # consider odd powers of a generator.
    1456                     D = K(1)
    1457                     if K.degree()%2==0:
    1458                         D = K.gen()
    1459                         a = D**2
    1460                         while len((x**2+x+D).roots())>0:
    1461                             D *= a
    1462                 else:
    1463                     # We could take a multiplicative generator but
    1464                     # that might be expensive to compute; otherwise
    1465                     # half the elements will do
    1466                     D = K.random_element()
    1467                     while len((x**2-D).roots())>0:
    1468                         D = K.random_element()
    1469             else:
    1470                 raise ValueError, "twisting parameter D must be specified over infinite fields."
    1471         else:
    1472             try:
    1473                 D=K(D)
    1474             except ValueError:
    1475                 raise ValueError, "twisting parameter D must be in the base field."
    1476        
    1477             if char!=2 and D.is_zero():
    1478                 raise ValueError, "twisting parameter D must be nonzero when characteristic is not 2"
    1479 
    1480         if char!=2:
    1481             b2,b4,b6,b8=self.b_invariants()
    1482             # E is isomorphic to  [0,b2,0,8*b4,16*b6]
    1483             return EllipticCurve(K,[0,b2*D,0,8*b4*D**2,16*b6*D**3])
    1484 
    1485         # now char==2
    1486         if self.j_invariant() !=0: # iff a1!=0
    1487             a1,a2,a3,a4,a6=self.ainvs()
    1488             E0=self.change_weierstrass_model(a1,a3/a1,0,(a1**2*a4+a3**2)/a1**3)
    1489             # which has the form = [1,A2,0,0,A6]
    1490             assert E0.a1()==K(1)
    1491             assert E0.a3()==K(0)
    1492             assert E0.a4()==K(0)
    1493             return EllipticCurve(K,[1,E0.a2()+D,0,0,E0.a6()])
    1494         else:
    1495             raise ValueError, "Quadratic twist not implemented in char 2 when j=0"
    1496 
    1497     def quartic_twist(self, D):
    1498         r"""
    1499         Return the quartic twist of this curve by `D`.
    1500 
    1501         INPUT:
    1502 
    1503         - ``D`` (must be nonzero) -- the twisting parameter..
    1504        
    1505         .. note::
    1506 
    1507            The characteristic must not be 2 or 3, and the `j`-invariant must be 1728.
    1508        
    1509         EXAMPLES::
    1510        
    1511             sage: E=EllipticCurve_from_j(GF(13)(1728)); E
    1512             Elliptic Curve defined by y^2  = x^3 + x over Finite Field of size 13
    1513             sage: E1=E.quartic_twist(2); E1
    1514             Elliptic Curve defined by y^2  = x^3 + 5*x over Finite Field of size 13
    1515             sage: E.is_isomorphic(E1)
    1516             False
    1517             sage: E.is_isomorphic(E1,GF(13^2,'a'))
    1518             False
    1519             sage: E.is_isomorphic(E1,GF(13^4,'a'))
    1520             True
    1521         """
    1522         K=self.base_ring()
    1523         char=K.characteristic()
    1524         D=K(D)
    1525        
    1526         if char==2 or char==3:
    1527             raise ValueError, "Quartic twist not defined in chars 2,3"
    1528 
    1529         if self.j_invariant() !=K(1728):
    1530             raise ValueError, "Quartic twist not defined when j!=1728"
    1531 
    1532         if D.is_zero():
    1533             raise ValueError, "quartic twist requires a nonzero argument"
    1534 
    1535         c4,c6=self.c_invariants()
    1536         # E is isomorphic to  [0,0,0,-27*c4,0]
    1537         assert c6==0
    1538         return EllipticCurve(K,[0,0,0,-27*c4*D,0])
    1539 
    1540     def sextic_twist(self, D):
    1541         r"""
    1542         Return the quartic twist of this curve by `D`.
    1543 
    1544         INPUT:
    1545 
    1546         - ``D`` (must be nonzero) -- the twisting parameter..
    1547        
    1548         .. note::
    1549 
    1550            The characteristic must not be 2 or 3, and the `j`-invariant must be 0.
    1551        
    1552         EXAMPLES::
    1553        
    1554             sage: E=EllipticCurve_from_j(GF(13)(0)); E
    1555             Elliptic Curve defined by y^2 = x^3 + 1 over Finite Field of size 13
    1556             sage: E1=E.sextic_twist(2); E1
    1557             Elliptic Curve defined by y^2 = x^3 + 11 over Finite Field of size 13
    1558             sage: E.is_isomorphic(E1)
    1559             False
    1560             sage: E.is_isomorphic(E1,GF(13^2,'a'))
    1561             False
    1562             sage: E.is_isomorphic(E1,GF(13^4,'a'))
    1563             False
    1564             sage: E.is_isomorphic(E1,GF(13^6,'a'))
    1565             True
    1566         """
    1567         K=self.base_ring()
    1568         char=K.characteristic()
    1569         D=K(D)
    1570        
    1571         if char==2 or char==3:
    1572             raise ValueError, "Sextic twist not defined in chars 2,3"
    1573 
    1574         if self.j_invariant() !=K(0):
    1575             raise ValueError, "Sextic twist not defined when j!=0"
    1576 
    1577         if D.is_zero():
    1578             raise ValueError, "Sextic twist requires a nonzero argument"
    1579 
    1580         c4,c6=self.c_invariants()
    1581         # E is isomorphic to  [0,0,0,0,-54*c6]
    1582         assert c4==0
    1583         return EllipticCurve(K,[0,0,0,0,-54*c6*D])
    1584 
    1585     def is_quadratic_twist(self, other):
    1586         r"""
    1587         Determine whether this curve is a quadratic twist of another.
    1588 
    1589         INPUT:
    1590                
    1591         - ``other`` -- an elliptic curves with the same base field as self.
    1592 
    1593         OUTPUT:
    1594 
    1595         Either 0, if the curves are not quadratic twists, or `D` if
    1596         ``other`` is ``self.quadratic_twist(D)`` (up to isomorphism).
    1597         If ``self`` and ``other`` are isomorphic, returns 1.
    1598 
    1599         .. note::
    1600 
    1601            Not fully implemented in characteristic 2, or in
    1602            characteristic 3 when both `j`-invariants are 0.
    1603 
    1604         EXAMPLES::
    1605 
    1606             sage: E = EllipticCurve('11a1')
    1607             sage: Et = E.quadratic_twist(-24)
    1608             sage: E.is_quadratic_twist(Et)
    1609             -6
    1610            
    1611             sage: E1=EllipticCurve([0,0,1,0,0])
    1612             sage: E1.j_invariant()
    1613             0
    1614             sage: E2=EllipticCurve([0,0,0,0,2])
    1615             sage: E1.is_quadratic_twist(E2)
    1616             2
    1617            
    1618         ::   
    1619 
    1620             sage: E1=EllipticCurve([0,0,0,1,0])
    1621             sage: E1.j_invariant()
    1622             1728
    1623             sage: E2=EllipticCurve([0,0,0,2,0])
    1624             sage: E1.is_quadratic_twist(E2)
    1625             0
    1626             sage: E2=EllipticCurve([0,0,0,25,0])
    1627             sage: E1.is_quadratic_twist(E2)
    1628             5
    1629            
    1630         ::   
    1631 
    1632             sage: F = GF(101)
    1633             sage: E1 = EllipticCurve(F,[4,7])
    1634             sage: E2 = E1.quadratic_twist()
    1635             sage: D = E1.is_quadratic_twist(E2); D!=0
    1636             True
    1637             sage: F = GF(101)
    1638             sage: E1 = EllipticCurve(F,[4,7])
    1639             sage: E2 = E1.quadratic_twist()
    1640             sage: D = E1.is_quadratic_twist(E2)
    1641             sage: E1.quadratic_twist(D).is_isomorphic(E2)
    1642             True
    1643             sage: E1.is_isomorphic(E2)
    1644             False
    1645             sage: F2 = GF(101^2,'a')
    1646             sage: E1.change_ring(F2).is_isomorphic(E2.change_ring(F2))
    1647             True
    1648            
    1649         A characteristic 3 example::
    1650 
    1651             sage: F = GF(3^5,'a')
    1652             sage: E1 = EllipticCurve_from_j(F(1))
    1653             sage: E2 = E1.quadratic_twist(-1)
    1654             sage: D = E1.is_quadratic_twist(E2); D!=0
    1655             True
    1656             sage: E1.quadratic_twist(D).is_isomorphic(E2)
    1657             True
    1658            
    1659         ::   
    1660 
    1661             sage: E1 = EllipticCurve_from_j(F(0))
    1662             sage: E2 = E1.quadratic_twist()
    1663             sage: D = E1.is_quadratic_twist(E2); D
    1664             1
    1665             sage: E1.is_isomorphic(E2)
    1666             True
    1667 
    1668         """
    1669         from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
    1670         E = self
    1671         F = other
    1672         if not is_EllipticCurve(E) or not is_EllipticCurve(F):
    1673             raise ValueError, "arguments are not elliptic curves"
    1674         K = E.base_ring()
    1675         zero = K.zero_element()
    1676         if not K == F.base_ring():
    1677             return zero
    1678         j=E.j_invariant()
    1679         if  j != F.j_invariant():
    1680             return zero
    1681    
    1682         if E.is_isomorphic(F):
    1683             return K.one_element()
    1684        
    1685         char=K.characteristic()
    1686        
    1687         if char==2:
    1688             raise NotImplementedError, "not implemented in characteristic 2"
    1689         elif char==3:
    1690             if j==0:
    1691                 raise NotImplementedError, "not implemented in characteristic 3 for curves of j-invariant 0"
    1692             D = E.b2()/F.b2()
    1693            
    1694         else:
    1695             # now char!=2,3:
    1696             c4E,c6E = E.c_invariants()
    1697             c4F,c6F = F.c_invariants()
    1698 
    1699             if j==0:
    1700                 um = c6E/c6F
    1701                 x=polygen(K)
    1702                 ulist=(x**3-um).roots(multiplicities=False)
    1703                 if len(ulist)==0:
    1704                     D = zero
    1705                 else:
    1706                     D = ulist[0]
    1707             elif j==1728:
    1708                 um=c4E/c4F
    1709                 x=polygen(K)
    1710                 ulist=(x**2-um).roots(multiplicities=False)
    1711                 if len(ulist)==0:
    1712                     D = zero
    1713                 else:
    1714                     D = ulist[0]
    1715             else:
    1716                 D = (c6E*c4F)/(c6F*c4E)
    1717        
    1718         # Normalization of output:
    1719        
    1720         if D.is_zero():
    1721             return D
    1722        
    1723         if K is rings.QQ:
    1724             D = D.squarefree_part()
    1725 
    1726         assert E.quadratic_twist(D).is_isomorphic(F)
    1727 
    1728         return D
    1729 
    1730     def is_quartic_twist(self, other):
    1731         r"""
    1732         Determine whether this curve is a quartic twist of another.
    1733 
    1734         INPUT:
    1735                
    1736         - ``other`` -- an elliptic curves with the same base field as self.
    1737 
    1738         OUTPUT:
    1739 
    1740         Either 0, if the curves are not quartic twists, or `D` if
    1741         ``other`` is ``self.quartic_twist(D)`` (up to isomorphism).
    1742         If ``self`` and ``other`` are isomorphic, returns 1.
    1743 
    1744         .. note::
    1745 
    1746            Not fully implemented in characteristics 2 or 3.
    1747 
    1748         EXAMPLES::
    1749 
    1750             sage: E = EllipticCurve_from_j(GF(13)(1728))
    1751             sage: E1 = E.quartic_twist(2)
    1752             sage: D = E.is_quartic_twist(E1); D!=0
    1753             True
    1754             sage: E.quartic_twist(D).is_isomorphic(E1)
    1755             True
    1756 
    1757         ::   
    1758            
    1759             sage: E = EllipticCurve_from_j(1728)
    1760             sage: E1 = E.quartic_twist(12345)
    1761             sage: D = E.is_quartic_twist(E1); D
    1762             15999120
    1763             sage: (D/12345).is_perfect_power(4)
    1764             True
    1765         """
    1766         from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
    1767         E = self
    1768         F = other
    1769         if not is_EllipticCurve(E) or not is_EllipticCurve(F):
    1770             raise ValueError, "arguments are not elliptic curves"
    1771         K = E.base_ring()
    1772         zero = K.zero_element()
    1773         if not K == F.base_ring():
    1774             return zero
    1775         j=E.j_invariant()
    1776         if  j != F.j_invariant() or j!=K(1728):
    1777             return zero
    1778    
    1779         if E.is_isomorphic(F):
    1780             return K.one_element()
    1781        
    1782         char=K.characteristic()
    1783        
    1784         if char==2:
    1785             raise NotImplementedError, "not implemented in characteristic 2"
    1786         elif char==3:
    1787             raise NotImplementedError, "not implemented in characteristic 3"           
    1788         else:
    1789             # now char!=2,3:
    1790             D = F.c4()/E.c4()
    1791        
    1792         if D.is_zero():
    1793             return D
    1794        
    1795         assert E.quartic_twist(D).is_isomorphic(F)
    1796 
    1797         return D
    1798 
    1799     def is_sextic_twist(self, other):
    1800         r"""
    1801         Determine whether this curve is a sextic twist of another.
    1802 
    1803         INPUT:
    1804                
    1805         - ``other`` -- an elliptic curves with the same base field as self.
    1806 
    1807         OUTPUT:
    1808 
    1809         Either 0, if the curves are not sextic twists, or `D` if
    1810         ``other`` is ``self.sextic_twist(D)`` (up to isomorphism).
    1811         If ``self`` and ``other`` are isomorphic, returns 1.
    1812 
    1813         .. note::
    1814 
    1815            Not fully implemented in characteristics 2 or 3.
    1816 
    1817         EXAMPLES::
    1818 
    1819             sage: E = EllipticCurve_from_j(GF(13)(0))
    1820             sage: E1 = E.sextic_twist(2)
    1821             sage: D = E.is_sextic_twist(E1); D!=0
    1822             True
    1823             sage: E.sextic_twist(D).is_isomorphic(E1)
    1824             True
    1825 
    1826         ::   
    1827 
    1828             sage: E = EllipticCurve_from_j(0)
    1829             sage: E1 = E.sextic_twist(12345)
    1830             sage: D = E.is_sextic_twist(E1); D
    1831             575968320
    1832             sage: (D/12345).is_perfect_power(6)
    1833             True
    1834         """
    1835         from sage.schemes.elliptic_curves.ell_generic import is_EllipticCurve
    1836         E = self
    1837         F = other
    1838         if not is_EllipticCurve(E) or not is_EllipticCurve(F):
    1839             raise ValueError, "arguments are not elliptic curves"
    1840         K = E.base_ring()
    1841         zero = K.zero_element()
    1842         if not K == F.base_ring():
    1843             return zero
    1844         j=E.j_invariant()
    1845         if  j != F.j_invariant() or not j.is_zero():
    1846             return zero
    1847    
    1848         if E.is_isomorphic(F):
    1849             return K.one_element()
    1850        
    1851         char=K.characteristic()
    1852        
    1853         if char==2:
    1854             raise NotImplementedError, "not implemented in characteristic 2"
    1855         elif char==3:
    1856             raise NotImplementedError, "not implemented in characteristic 3"           
    1857         else:
    1858             # now char!=2,3:
    1859             D = F.c6()/E.c6()
    1860        
    1861         if D.is_zero():
    1862             return D
    1863        
    1864         assert E.sextic_twist(D).is_isomorphic(F)
    1865 
    1866         return D
    18671333
    18681334    def rst_transform(self, r, s, t):
    18691335        r"""
     
    23801846
    23811847    torsion_polynomial = division_polynomial
    23821848
    2383 #     def torsion_polynomial_old(self, n, var='x', i=0):
    2384 #         r"""
    2385 #         Returns the n-th torsion polynomial (a.k.a., division polynomial).
    2386 
    2387 #         INPUT:
    2388 #             n -- non-negative integer
    2389 #             var -- string; the indeterminate of the polynomial (default: x)
    2390 #             i -- integer, either 0 (default) or 1.
    2391            
    2392 #         OUTPUT:
    2393 #             Polynomial -- n-th torsion polynomial, which is a polynomial over
    2394 #                           the base field of the elliptic curve.
    2395 
    2396 #         SEE ALSO: _division_polynomial, full_division_polynomial
    2397 
    2398 #         EXAMPLES:
    2399 #             sage: E = EllipticCurve([0,0,1,-1,0])
    2400 #             sage: E.torsion_polynomial_old(1)
    2401 #             1
    2402 #             sage: E.torsion_polynomial_old(2)
    2403 #             4*x^3 - 4*x + 1
    2404 #             sage: E.torsion_polynomial_old(3, 'z')
    2405 #             3*z^4 - 6*z^2 + 3*z - 1
    2406 
    2407 #             sage: E = EllipticCurve([0, -1, 1, -10, -20])
    2408 #             sage: E.torsion_polynomial(0)
    2409 #             0
    2410 #             sage: E.torsion_polynomial(1)
    2411 #             1
    2412 #             sage: E.torsion_polynomial(2)
    2413 #             4*x^3 - 4*x^2 - 40*x - 79
    2414 #             sage: E.torsion_polynomial(3)
    2415 #             3*x^4 - 4*x^3 - 60*x^2 - 237*x - 21
    2416 #             sage: E.torsion_polynomial(4)
    2417 #             8*x^9 - 24*x^8 - 464*x^7 - 2758*x^6 + 6636*x^5 + 34356*x^4 + 53510*x^3 + 99714*x^2 + 351024*x + 459859
    2418 
    2419 #             sage: E = EllipticCurve([-4,0])
    2420 #             sage: E.torsion_polynomial(2)
    2421 #             4*x^3 - 16*x
    2422 #             sage: E.torsion_polynomial(5)
    2423 #             5*x^12 - 248*x^10 - 1680*x^8 + 19200*x^6 - 32000*x^4 + 51200*x^2 + 4096
    2424 #             sage: E.torsion_polynomial(6)
    2425 #             12*x^19 - 1200*x^17 - 18688*x^15 + 422912*x^13 - 2283520*x^11 + 9134080*x^9 - 27066368*x^7 + 19136512*x^5 + 19660800*x^3 - 3145728*x
    2426 
    2427 #             Check for consistency with division_polynomial_0:
    2428 #             sage: assert all([E.torsion_polynomial(2*m-1)==E.division_polynomial_0(2*m-1) for m in range(1,20)])
    2429 #             sage: assert all([E.torsion_polynomial(2*m)==E.division_polynomial_0(2*m)*E.division_polynomial_0(-1) for m in range(1,20)])
    2430      
    2431 #         AUTHOR: David Kohel (kohel@maths.usyd.edu.au), 2005-04-25
    2432 #         """
    2433 #         n = int(n)
    2434 #         try:
    2435 #             return self.__torsion_polynomial[n]
    2436 #         except AttributeError:
    2437 #             self.__torsion_polynomial = {}
    2438 #         except KeyError:
    2439 #             pass
    2440 #         E = self; i=int(i)
    2441 #         if n < 0:
    2442 #             raise ValueError, "n must be a non-negative integer."
    2443 #         if i > 1 :
    2444 #             raise ValueError, "i must be 0 or 1."
    2445        
    2446 #         R = rings.PolynomialRing(E.base_ring(), var)
    2447 
    2448 # # This is just an abbreviation to make the following code clearer:
    2449 #         tp = lambda m: E.torsion_polynomial(m)
    2450 
    2451 #         if i == 1:
    2452 #             if n == 0:
    2453 #                 f = tp(1)
    2454 #                 E.__torsion_polynomial[n] = f
    2455 #                 return f
    2456 #             else:
    2457 #                 x = R.gen()
    2458 #                 psi2 = tp(2)
    2459 #                 if n%2 == 0:
    2460 #                     f = x * psi2 * (tp(n)//psi2)**2 - tp(n+1) * tp(n-1)
    2461 #                     E.__torsion_polynomial[n] = f
    2462 #                     return f
    2463 #                 else:
    2464 #                     f = x * tp(n)**2 - (tp(n+1)//psi2) * tp(n-1)
    2465 #                     E.__torsion_polynomial[n] = f
    2466 #                     return f
    2467                
    2468 #         else:
    2469            
    2470 #             if n == 0: return R(0)
    2471 #             if n == 1: return R(1)
    2472 #             x = R.gen()
    2473 #             b2, b4, b6, b8 = E.b_invariants()
    2474 #             psi2 = 4*x**3 + b2*x**2 + 2*b4*x + b6
    2475 #             if n == 2:
    2476 #                 f = psi2
    2477 #                 E.__torsion_polynomial[n] = f; return f
    2478 #             if n == 3:
    2479 #                 f = 3*x**4 + b2*x**3 + 3*b4*x**2 + 3*b6*x + b8
    2480 #                 E.__torsion_polynomial[n] = f; return f
    2481 #             if n == 4:
    2482 #                 f = psi2 * (2*x**6 + b2*x**5 + 5*b4*x**4 + 10*b6*x**3 \
    2483 #                     + 10*b8*x**2  + (b2*b8 - b4*b6)*x + b4*b8 - b6**2)
    2484 #                 E.__torsion_polynomial[n] = f; return f
    2485 #             if n%2 == 0:
    2486 #                 m = n//2
    2487 #                 if m%2 == 0:
    2488 #                     f = tp(m) * \
    2489 #                         ((tp(m+2)//psi2) * tp(m-1)**2 - \
    2490 #                          (tp(m-2)//psi2) * tp(m+1)**2)
    2491 #                     E.__torsion_polynomial[n] = f; return f
    2492 #                 else:
    2493 #                     f = psi2 * tp(m)*( \
    2494 #                         tp(m+2) * (tp(m-1)//psi2)**2 - \
    2495 #                         tp(m-2) * (tp(m+1)//psi2)**2)
    2496 #                     E.__torsion_polynomial[n] = f; return f                   
    2497 #             else: 
    2498 #                 m = n//2
    2499 #                 if m%2 == 0:
    2500 #                     f = psi2 * \
    2501 #                         tp(m+2) * (tp(m)//psi2)**3 - \
    2502 #                         tp(m-1) * tp(m+1)**3
    2503 #                     E.__torsion_polynomial[n] = f; return f                   
    2504 #                 else:
    2505 #                     f = tp(m+2) * tp(m)**3 - psi2 * \
    2506 #                         tp(m-1)*(tp(m+1)//psi2)**3
    2507 #                     E.__torsion_polynomial[n] = f; return f
    2508 
    2509 #     def full_division_polynomial(self, m):
    2510 #         """
    2511 #         Return the $m$-th bivariate division polynomial in $x$ and
    2512 #         $y$.  When $m$ is odd this is exactly the same as the usual
    2513 #         $m$th division polynomial.
    2514 
    2515 #         For the usual division polynomial only in $x$, see the
    2516 #         functions division_polynomial() and
    2517 #         division_polynomial_0().
    2518 
    2519 #         INPUT:
    2520 #             self -- elliptic curve
    2521 #             m    -- a positive integer
    2522 #         OUTPUT:
    2523 #             a polynomial in two variables $x$, $y$.
    2524 
    2525 #         NOTE: The result is cached.           
    2526 
    2527 #         EXAMPLES:
    2528 #         We create a curve and compute the first two full division
    2529 #         polynomials.
    2530 #             sage: E = EllipticCurve([2,3])
    2531 #             sage: E.full_division_polynomial(1)
    2532 #             1
    2533 #             sage: E.full_division_polynomial(2)
    2534 #             2*y
    2535 
    2536 #         Note that for odd input the full division polynomial is
    2537 #         just the usual division polynomial, but not for even input:
    2538 #             sage: E.division_polynomial(2)
    2539 #             4*x^3 + 8*x + 12
    2540 #             sage: E.full_division_polynomial(3)
    2541 #             3*x^4 + 12*x^2 + 36*x - 4
    2542 #             sage: E.division_polynomial(3)
    2543 #             3*x^4 + 12*x^2 + 36*x - 4
    2544 #             sage: E.full_division_polynomial(4)
    2545 #             4*x^6*y + 40*x^4*y + 240*x^3*y - 80*x^2*y - 96*x*y - 320*y
    2546 #             sage: E.full_division_polynomial(5)
    2547 #             5*x^12 + 124*x^10 + 1140*x^9 - 420*x^8 + 1440*x^7 - 4560*x^6 - 8352*x^5 - 36560*x^4 - 45120*x^3 - 10240*x^2 - 39360*x - 22976
    2548 
    2549 #         TESTS:
    2550 #         We test that the full division polynomial as computed using
    2551 #         the recurrence agrees with the normal division polynomial for
    2552 #         a certain curve and all odd $n$ up to $23$:
    2553        
    2554 #             sage: E = EllipticCurve([23,-105])
    2555 #             sage: for n in [1,3,..,23]:
    2556 #             ...       assert E.full_division_polynomial(n) == E.division_polynomial(n)       
    2557 #         """
    2558 #         # Coerce the input m to be an integer
    2559 #         m = rings.Integer(m)
    2560 
    2561 #         # Check whether the corresponding poly is cached already
    2562 #         try:
    2563 #             return self.__divpoly2[m]
    2564 #         except AttributeError:
    2565 #             self.__divpoly2 = {}
    2566 #         except KeyError:
    2567 #             pass
    2568 
    2569 #         # Get the invariants of the curve
    2570 #         a1,a2,a3,a4,a6 = self.a_invariants()
    2571 
    2572 #         # Define the polynomial ring that will contain the full
    2573 #         # division polynomial.
    2574        
    2575 #         R, (x,y) = PolynomialRing(self.base_ring(), 2, 'x,y').objgens()
    2576 
    2577 #         # The function division_polynomial_0() gives the correct
    2578 #         # result when m is odd, and all we do in this case is evaluate
    2579 #         # this at the variable x in our bivariate polynomial ring.
    2580 
    2581 #         # For even m, we must multiply the result of
    2582 #         # division_polynomial_0() by the full 2-torsion polynomial
    2583 #         # which is 2*y+a1*x+a3
    2584 
    2585 #         f = self.division_polynomial_0(m,x)
    2586 #         if m % 2 == 0:
    2587 #             f *= (2*y+a1*x+a3)
    2588 
    2589 #         # Cache the result and return it.
    2590 #         self.__divpoly2[m] = f
    2591 #         return f
    2592 
    25931849    def _multiple_x_numerator(self, n, x=None, cache=None):
    25941850         r"""
    25951851         Returns the numerator of the `x`-coordinate of the `n\th` multiple of a
     
    34612717       
    34622718        .. note::
    34632719
    3464            The result is cached; on subsequent calls teh cached value
    3465            is returned prvided that it has sufficient precision,
     2720           The result is cached; on subsequent calls the cached value
     2721           is returned provided that it has sufficient precision,
    34662722           otherwise pari is called again with the new precision.
    34672723       
    34682724        EXAMPLES::
     
    34842740        from sage.libs.pari.all import pari
    34852741        self._pari_curve = pari(self.a_invariants()).ellinit(precision=prec)
    34862742        return self._pari_curve
    3487 
    3488 
    3489 
    3490 def Hasse_bounds(q, genus=1):
    3491     r"""
    3492     Return the Hasse bounds for the cardinality of a curve defined
    3493     over `\GF{q}` of given ``genus``.
    3494 
    3495     INPUT:
    3496 
    3497     - ``q`` (int) -- a prime power
    3498    
    3499     - ``genus`` (int, default 1) -- a non-negative integer,
    3500 
    3501     OUTPUT:
    3502 
    3503     (tuple)  The Hasse bounds (lb,ub) for the cardinality of a curve of
    3504     genus ``genus`` defined over `\GF{q}`.
    3505    
    3506     EXAMPLES::
    3507    
    3508         sage: Hasse_bounds(2)
    3509         (1, 5)
    3510         sage: Hasse_bounds(next_prime(10^30))
    3511         (999999999999998000000000000058, 1000000000000002000000000000058)
    3512     """
    3513     if genus==1:
    3514         rq = (4*q).isqrt()
    3515     else:
    3516         rq = (4*(genus**2)*q).isqrt()
    3517     return (q+1-rq,q+1+rq)
    3518    
  • sage/schemes/elliptic_curves/ell_point.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/elliptic_curves/ell_point.py
    a b  
    21232123            return rings.Integer(1)
    21242124        E = self.curve()
    21252125        K = E.base_ring()
    2126         bounds = ell_generic.Hasse_bounds(K.order())
     2126        from sage.schemes.plane_curves.projective_curve import Hasse_bounds
     2127        bounds = Hasse_bounds(K.order())
    21272128
    21282129        try:
    21292130            M = E._order
  • sage/schemes/plane_curves/all.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/plane_curves/all.py
    a b  
    2222
    2323from constructor import Curve
    2424
     25from projective_curve import Hasse_bounds
    2526
    26 
  • sage/schemes/plane_curves/projective_curve.py

    diff -r 1cb3a80b5575 -r b6ee31a996da sage/schemes/plane_curves/projective_curve.py
    a b  
    474474
    475475            raise ValueError, "No algorithm '%s' known"%algorithm
    476476
     477def Hasse_bounds(q, genus=1):
     478    r"""
     479    Return the Hasse-Weil bounds for the cardinality of a nonsingular
     480    curve defined over `\GF{q}` of given ``genus``.
     481
     482    INPUT:
     483
     484    - ``q`` (int) -- a prime power
     485   
     486    - ``genus`` (int, default 1) -- a non-negative integer,
     487
     488    OUTPUT:
     489
     490    (tuple)  The Hasse bounds (lb,ub) for the cardinality of a curve of
     491    genus ``genus`` defined over `\GF{q}`.
     492   
     493    EXAMPLES::
     494   
     495        sage: Hasse_bounds(2)
     496        (1, 5)
     497        sage: Hasse_bounds(next_prime(10^30))
     498        (999999999999998000000000000058, 1000000000000002000000000000058)
     499    """
     500    if genus==1:
     501        rq = (4*q).isqrt()
     502    else:
     503        rq = (4*(genus**2)*q).isqrt()
     504    return (q+1-rq,q+1+rq)
     505