Ticket #3897: 3897-local_data.patch

File 3897-local_data.patch, 72.8 KB (added by John Cremona, 14 years ago)
  • sage/rings/integer.pyx

    # HG changeset patch
    # User John Cremona <john.cremona@gmail.com>
    # Date 1222156565 -3600
    # Node ID ae41d53e73be502bed9b220fc7e90a25474ed7f2
    # Parent  b1ff622d9c6e0fed6c0a1d019b7fa4ad95e8f43c
    [mq]: ell_local.patch
    
    diff -r b1ff622d9c6e -r ae41d53e73be sage/rings/integer.pyx
    a b cdef class Integer(sage.structure.elemen 
    18561856        import sage.rings.integer_ring
    18571857        return sage.rings.integer_ring.factor(self, algorithm=algorithm, proof=proof)
    18581858       
     1859    def support(self):
     1860        """
     1861        Return a sorted list of the primes dividing this integer.
     1862
     1863        OUTPUT:
     1864            The sorted list of primes appearing in the factorization
     1865            of this rational with positive exponent.
     1866
     1867        EXAMPLES:
     1868            sage: factorial(10).support()
     1869            [2, 3, 5, 7]
     1870            sage: (-999).support()
     1871            [3, 37]
     1872
     1873        Trying to find the support of 0 gives an arithmetic error:
     1874            sage: 0.support()
     1875            Traceback (most recent call last):
     1876            ...
     1877            ArithmeticError: Support of 0 not defined.       
     1878        """
     1879        if self.is_zero():
     1880            raise ArithmeticError, "Support of 0 not defined."
     1881        return sage.rings.arith.prime_factors(self)
     1882       
    18591883    def coprime_integers(self, m):
    18601884        """
    18611885        Return the positive integers $< m$ that are coprime to self.
  • sage/rings/number_field/number_field_element.pyx

    diff -r b1ff622d9c6e -r ae41d53e73be sage/rings/number_field/number_field_element.pyx
    a b cdef class NumberFieldElement(FieldEleme 
    16401640            raise ValueError, "P must be prime"
    16411641        return Integer_sage(self.number_field()._pari_().elementval(self._pari_(), P._pari_prime))
    16421642
     1643    def support(self):
     1644        """
     1645        Return the support of this number field element.
     1646
     1647        OUTPUT:
     1648            A sorted list of the primes ideals at which this number
     1649            field element has nonzero valuation.  An error is raised
     1650            if the element is zero.
     1651           
     1652        EXAMPLES:
     1653            sage: x = ZZ['x'].gen()
     1654            sage: F.<t> = NumberField(x^3 - 2)
     1655
     1656            sage: P5s = F(5).support()
     1657            sage: P5s
     1658            [Fractional ideal (-t^2 - 1), Fractional ideal (t^2 - 2*t - 1)]
     1659            sage: all(5 in P5 for P5 in P5s)
     1660            True
     1661            sage: all(P5.is_prime() for P5 in P5s)
     1662            True
     1663            sage: [ P5.norm() for P5 in P5s ]
     1664            [5, 25]
     1665
     1666
     1667        TESTS:
     1668            It doesn't make sense to factor the ideal (0):
     1669
     1670            sage: F(0).support()
     1671            Traceback (most recent call last):
     1672            ...
     1673            ArithmeticError: Support of 0 is not defined.
     1674        """
     1675        if self.is_zero():
     1676            raise ArithmeticError, "Support of 0 is not defined."
     1677        return self.number_field().primes_above(self)
     1678
    16431679    def _matrix_over_base(self, L):
    16441680        """
    16451681        Return the matrix of self over the base field L.
  • sage/rings/rational.pyx

    diff -r b1ff622d9c6e -r ae41d53e73be sage/rings/rational.pyx
    a b cdef class Rational(sage.structure.eleme 
    17301730            ArithmeticError: Prime factorization of 0 not defined.       
    17311731        """
    17321732        return sage.rings.rational_field.factor(self)
     1733       
     1734    def support(self):
     1735        """
     1736        Return a sorted list of the primes where this rational number
     1737        has non-zero valuation.
     1738
     1739        OUTPUT:
     1740            The set of primes appearing in the factorization of
     1741            this rational with nonzero exponent, as a sorted list.
     1742
     1743        EXAMPLES:
     1744            sage: (-4/17).support()
     1745            [2, 17]
     1746
     1747        Trying to find the support of 0 gives an arithmetic error:
     1748            sage: (0/1).support()
     1749            Traceback (most recent call last):
     1750            ...
     1751            ArithmeticError: Support of 0 not defined.       
     1752        """
     1753        if self.is_zero():
     1754            raise ArithmeticError, "Support of 0 not defined."
     1755        return sage.rings.arith.prime_factors(self)
    17331756       
    17341757    def gamma(self, prec=None):
    17351758        """
  • sage/rings/rational_field.py

    diff -r b1ff622d9c6e -r ae41d53e73be sage/rings/rational_field.py
    a b class RationalField(_uniq, number_field_ 
    383383
    384384        EXAMPLES:
    385385            sage: QQ.discriminant()
     386            1       
     387        """
     388        return sage.rings.integer.Integer(1)
     389
     390    def class_number(self):
     391        """
     392        Return the class number of the field of rational numbers,
     393        which is 1.
     394
     395        EXAMPLES:
     396            sage: QQ.class_number()
    386397            1       
    387398        """
    388399        return sage.rings.integer.Integer(1)
  • new file sage/schemes/elliptic_curves/ell_local_data.py

    diff -r b1ff622d9c6e -r ae41d53e73be sage/schemes/elliptic_curves/ell_local_data.py
    - +  
     1r"""
     2Local data for elliptic curves over number fields (including Q) at primes.
     3
     4AUTHORS:
     5    -- John Cremona: First version 2008-09-21 (refactoring code from
     6       ell_number_field.py and ell_rational_field.py)
     7"""
     8
     9#*****************************************************************************
     10#       Copyright (C) 2005 William Stein <wstein@gmail.com>
     11#
     12#  Distributed under the terms of the GNU General Public License (GPL)
     13#
     14#    This code is distributed in the hope that it will be useful,
     15#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17#    General Public License for more details.
     18#
     19#  The full text of the GPL is available at:
     20#
     21#                  http://www.gnu.org/licenses/
     22#*****************************************************************************
     23
     24
     25from sage.structure.sage_object import SageObject
     26from sage.misc.misc import verbose, forall
     27
     28from sage.rings.all import PolynomialRing, QQ, ZZ, Integer, is_Ideal, is_NumberFieldElement, is_NumberFieldFractionalIdeal, is_NumberField
     29from sage.structure.element import RingElement
     30from constructor import EllipticCurve
     31from kodaira_symbol import KodairaSymbol
     32
     33class EllipticCurveLocalData(SageObject):
     34    """
     35    The class for the local reduction data of an elliptic curve.
     36
     37    Currently supported are elliptic curves defined over Q, and
     38    elliptic curves defined over a number field, at an arbitrary prime
     39    or prime ideal.
     40    """
     41   
     42    def __init__(self, E, P, proof=None):
     43        """
     44        Initializes the reduction data for the elliptic curve E at the prime P.
     45
     46        INPUT:
     47            E -- an elliptic curve defined over a number field (or QQ)
     48            P -- a prime ideal of the field
     49                 (or a prime integer if the field is QQ)
     50            proof -- whether to only use provably correct methods
     51                     (default controled by global proof module).  Note
     52                     that the proof module is number_field, not
     53                     elliptic_curves, since the functions that
     54                     actually need the flag are in number fields.
     55
     56        EXAMPLES:
     57            This function is not normally called directly, but will be
     58            called by
     59
     60            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     61            sage: E = EllipticCurve('14a1')
     62            sage: EllipticCurveLocalData(E,2)
     63            Local data at Principal ideal (2) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:
     64            Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
     65            Minimal discriminant valuation: 6
     66            Conductor exponent: 1
     67            Kodaira Symbol: I6
     68            Tamagawa Number: 2
     69            sage: EllipticCurveLocalData(E,3)
     70            Local data at Principal ideal (3) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:
     71            Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
     72            Minimal discriminant valuation: 0
     73            Conductor exponent: 0
     74            Kodaira Symbol: I0
     75            Tamagawa Number: 1
     76            sage: EllipticCurveLocalData(E,7)           
     77            Local data at Principal ideal (7) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:
     78            Local minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field
     79            Minimal discriminant valuation: 3
     80            Conductor exponent: 1
     81            Kodaira Symbol: I3
     82            Tamagawa Number: 3
     83        """
     84        self._curve = E
     85        K = E.base_field()
     86        self._prime = check_prime(K,P) # error handling done in that function
     87        self._Emin, ch, self._val_disc, self._fp, self._KS, self._cp = self._tate(proof)
     88       
     89           
     90    def __repr__(self):
     91        """
     92        Returns the string representation of this reduction data.
     93
     94        EXAMPLES:
     95            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     96            sage: E = EllipticCurve('14a1')
     97            sage: EllipticCurveLocalData(E,2).__repr__()
     98            'Local data at Principal ideal (2) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 6\nConductor exponent: 1\nKodaira Symbol: I6\nTamagawa Number: 2'
     99            sage: EllipticCurveLocalData(E,3).__repr__()
     100            'Local data at Principal ideal (3) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 0\nConductor exponent: 0\nKodaira Symbol: I0\nTamagawa Number: 1'
     101            sage: EllipticCurveLocalData(E,7).__repr__()
     102            'Local data at Principal ideal (7) of Integer Ring of Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field:\nLocal minimal model: Elliptic Curve defined by y^2 + x*y + y = x^3 + 4*x - 6 over Rational Field\nMinimal discriminant valuation: 3\nConductor exponent: 1\nKodaira Symbol: I3\nTamagawa Number: 3'
     103        """
     104        return "Local data at %s of %s:\nLocal minimal model: %s\nMinimal discriminant valuation: %s\nConductor exponent: %s\nKodaira Symbol: %s\nTamagawa Number: %s"%(self._prime,self._curve,self._Emin,self._val_disc,self._fp,self._KS,self._cp)
     105
     106    def minimal_model(self):
     107        """
     108        Return the (local) minimal model from this local reduction data.
     109
     110        EXAMPLES:
     111            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     112            sage: E = EllipticCurve([0,0,0,0,64]); E
     113            Elliptic Curve defined by y^2  = x^3 + 64 over Rational Field
     114            sage: data = EllipticCurveLocalData(E,2)
     115            sage: data.minimal_model()
     116            Elliptic Curve defined by y^2  = x^3 +1 over Rational Field
     117            sage: data.minimal_model() == E.local_minimal_model(2)
     118            True
     119        """
     120        return self._Emin
     121
     122    def prime(self):
     123        """
     124        Return the prime ideal associated with from this local reduction data.
     125
     126        EXAMPLES:
     127            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     128            sage: E = EllipticCurve([0,0,0,0,64]); E
     129            Elliptic Curve defined by y^2  = x^3 + 64 over Rational Field
     130            sage: data = EllipticCurveLocalData(E,2)
     131            sage: data.prime()
     132            Principal ideal (2) of Integer Ring
     133        """
     134        return self._prime
     135
     136    def conductor_valuation(self):
     137        """
     138        Return the valuation of the conductor from this local reduction data.
     139
     140        EXAMPLES:
     141            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     142            sage: E = EllipticCurve([0,0,0,0,64]); E
     143            Elliptic Curve defined by y^2  = x^3 + 64 over Rational Field
     144            sage: data = EllipticCurveLocalData(E,2)
     145            sage: data.conductor_valuation()
     146            2
     147        """
     148        return self._fp
     149
     150    def kodaira_symbol(self):
     151        """
     152        Return the Kodaira symbol from this local reduction data.
     153
     154        EXAMPLES:
     155            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     156            sage: E = EllipticCurve([0,0,0,0,64]); E
     157            Elliptic Curve defined by y^2  = x^3 + 64 over Rational Field
     158            sage: data = EllipticCurveLocalData(E,2)
     159            sage: data.kodaira_symbol()
     160            IV
     161        """
     162        return self._KS
     163
     164    def tamagawa_number(self):
     165        r"""
     166        Return the Tamagawa number from this local reduction data.
     167
     168        This is the index $[E(K_v):E^0(K_v)]$.
     169
     170        EXAMPLES:
     171            sage: from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData
     172            sage: E = EllipticCurve([0,0,0,0,64]); E
     173            Elliptic Curve defined by y^2  = x^3 + 64 over Rational Field
     174            sage: data = EllipticCurveLocalData(E,2)
     175            sage: data.tamagawa_number()
     176            3
     177        """
     178        return self._cp
     179
     180    def _tate(self, proof = None):
     181        """
     182        Tate's algorithm for an elliptic curve over a number field:
     183        computes local reduction data at a prime ideal and a local
     184        minimal model.
     185
     186        The model is not required to be integral on input.  If P is
     187        principal, uses a generator as uniformizer, so it will not
     188        affect integrality or minimality at other primes.  If P is not
     189        principal, the minimal model returned will preserve
     190        integrality at other primes, but not minimality.
     191
     192        INPUT:
     193            Called only by the EllipticCurveLocalData.__init__()
     194
     195        OUTPUT:
     196            Emin -- a model (integral and) minimal at P
     197            p    -- the residue characteristic
     198            val_disc  -- the valuation of the local minimal discriminant
     199            fp   -- valuation of the conductor
     200            KS   -- Kodaira symbol
     201            cp   -- Tamagawa number
     202
     203        """
     204        E = self._curve
     205        P = self._prime
     206        K = E.base_ring()
     207        OK = K.maximal_order()
     208        t = verbose("Running Tate's algorithm with P = %s"%P, level=1)
     209        F = OK.residue_field(P)
     210        p = F.characteristic()
     211        if P.is_principal():
     212            pi = P.gens_reduced()[0]
     213            verbose("P is principal, generator pi = %s"%pi, t, 1)
     214        else:
     215            pi = K.uniformizer(P, 'negative')
     216            verbose("P is not principal, uniformizer pi = %s"%pi, t, 1)
     217        prime = pi if K is QQ else P
     218
     219        pval = lambda x: x.valuation(prime)
     220        pdiv = lambda x: x.is_zero() or pval(x) > 0
     221        pinv = lambda x: F.lift(~F(x))
     222        proot = lambda x,e: F.lift(F(x).nth_root(e, extend = False, all = True)[0])
     223        preduce = lambda x: F.lift(F(x))
     224
     225        def _pquadroots(a, b, c):
     226            r"""
     227            Local function returning True iff $ax^2 + bx + c$ has roots modulo P
     228            """
     229            (a, b, c) = (F(a), F(b), F(c))
     230            if a == 0:
     231                return (b != 0) or (c == 0)
     232            elif p == 2:
     233                return len(PolynomialRing(F, "x")([c,b,a]).roots()) > 0
     234            else:
     235                return (b**2 - 4*a*c).is_square()
     236        def _pcubicroots(b, c, d):
     237            r"""
     238            Local function returning the number of roots of $x^3 +
     239            b*x^2 + c*x + d$ modulo P, counting multiplicities
     240            """
     241            return sum([rr[1] for rr in PolynomialRing(F, 'x')([d, c, b, 1]).roots()],0)
     242
     243        if p == 2:
     244            halfmodp = OK(Integer(0))
     245        else:
     246            halfmodp = pinv(Integer(2))
     247
     248        A = E.a_invariants()
     249        A = [0, A[0], A[1], A[2], A[3], 0, A[4]]
     250        indices = [1,2,3,4,6]
     251        if min([pval(a) for a in A if a != 0]) < 0:
     252            verbose("Non-integral model at P: valuations are %s; making integral"%([pval(a) for a in A if a != 0]), t, 1)
     253            e = 0
     254            for i in range(7):
     255                if A[i] != 0:
     256                    e = max(e, (-pval(A[i])/i).ceil())
     257            pie = pi**e
     258            for i in range(7):
     259                if A[i] != 0:
     260                    A[i] *= pie**i
     261            verbose("P-integral model is %s, with valuations %s"%([A[i] for i in indices], [pval(A[i]) for i in indices]), t, 1)
     262
     263        (a1, a2, a3, a4, a6) = (A[1], A[2], A[3], A[4], A[6])
     264        while True:
     265            C = EllipticCurve([a1, a2, a3, a4, a6]);
     266            (b2, b4, b6, b8) = C.b_invariants()
     267            (c4, c6) = C.c_invariants()
     268            delta = C.discriminant()
     269            val_disc = pval(delta)
     270
     271            if val_disc == 0:
     272                ## Good reduction already
     273                cp = 1
     274                fp = 0
     275                KS = KodairaSymbol("I0")
     276                break #return
     277
     278            # Otherwise, we change coordinates so that p | a3, a4, a6
     279            if p == 2:
     280                if pdiv(b2):
     281                    r = proot(a4, 2)
     282                    t = proot(((r + a2)*r + a4)*r + a6, 2)
     283                else:
     284                    temp = pinv(a1)
     285                    r = temp * a3
     286                    t = temp * (a4 + r*r)
     287            elif p == 3:
     288                if pdiv(b2):
     289                    r = proot(-b6, 3)
     290                else:
     291                    r = -pinv(b2) * b4
     292                t = a1 * r + a3
     293            else:
     294                if pdiv(c4):
     295                    r = -pinv(12) * b2
     296                else:
     297                    r = -pinv(12*c4) * (c6 + b2 * c4)
     298                t = -halfmodp * (a1 * r + a3)
     299            r = preduce(r)
     300            t = preduce(t)
     301            # print "Before first tranform C = %s"%C
     302            # print "[a1,a2,a3,a4,a6] = %s"%([a1, a2, a3, a4, a6])
     303            C = C.rst_transform(r, 0, t)
     304            (a1, a2, a3, a4, a6) = C.a_invariants()
     305            (b2, b4, b6, b8) = C.b_invariants()
     306            if min([pval(a) for a in (a1, a2, a3, a4, a6) if a != 0]) < 0:
     307                raise RuntimeError, "Non-integral model after first transform!"
     308            verbose("After first transform %s\n, [a1,a2,a3,a4,a6] = %s\n, valuations = %s"%([r, 0, t], [a1, a2, a3, a4, a6], [pval(a1), pval(a2), pval(a3), pval(a4), pval(a6)]), t, 2)
     309            if pval(a3) == 0:
     310                raise RuntimeError, "p does not divide a3 after first transform!"
     311            if pval(a4) == 0:
     312                raise RuntimeError, "p does not divide a4 after first transform!"
     313            if pval(a6) == 0:
     314                raise RuntimeError, "p does not divide a6 after first transform!"
     315
     316            # Now we test for Types In, II, III, IV
     317            # Do we not have to update the c invariants?
     318            if not pdiv(c4):
     319                ## Type In (n = val_disc)
     320                if _pquadroots(1, a1, -a2):
     321                    cp = val_disc
     322                elif Integer(2).divides(val_disc):
     323                    cp = 2
     324                else:
     325                    cp = 1
     326                KS = KodairaSymbol("I%s"%val_disc)
     327                fp = 1
     328                break #return
     329            if pval(a6) < 2:
     330                ## Type II
     331                KS = KodairaSymbol("II")
     332                fp = val_disc
     333                cp = 1
     334                break #return
     335            if pval(b8) < 3:
     336                ## Type III
     337                KS = KodairaSymbol("III")
     338                fp = val_disc - 1
     339                cp = 2
     340                break #return
     341            if pval(b6) < 3:
     342                ## Type IV
     343                if _pquadroots(1, a3 / pi, -a6/(pi*pi)):
     344                    cp = 3
     345                else:
     346                    cp = 1
     347                KS = KodairaSymbol("IV")
     348                fp = val_disc - 2
     349                break #return
     350
     351            # If our curve is none of these types, we change types so that p | a1, a2 and p^2 | a3, a4 and p^3 | a6
     352            if p == 2:
     353                s = proot(a2, 2)
     354                t = pi*proot(a6/(pi*pi), 2)
     355            elif p == 3:
     356                s = a1
     357                t = a3
     358            else:
     359                s = -a1*halfmodp
     360                t = -a3*halfmodp
     361            C = C.rst_transform(0, s, t)
     362            (a1, a2, a3, a4, a6) = C.a_invariants()
     363            (b2, b4, b6, b8) = C.b_invariants()
     364            verbose("After second transform %s\n[a1, a2, a3, a4, a6] = %s\nValuations: %s"%([0, s, t], [a1,a2,a3,a4,a6],[pval(a1),pval(a2),pval(a3),pval(a4),pval(a6)]), t, 2)
     365            if pval(a1) == 0:
     366                raise RuntimeError, "p does not divide a1 after second transform!"
     367            if pval(a2) == 0:
     368                raise RuntimeError, "p does not divide a2 after second transform!"
     369            if pval(a3) < 2:
     370                raise RuntimeError, "p^2 does not divide a3 after second transform!"
     371            if pval(a4) < 2:
     372                raise RuntimeError, "p^2 does not divide a4 after second transform!"
     373            if pval(a6) < 3:
     374                raise RuntimeError, "p^3 does not divide a6 after second transform!"
     375            if min(pval(a1), pval(a2), pval(a3), pval(a4), pval(a6)) < 0:
     376                raise RuntimeError, "Non-integral model after second transform!"
     377
     378            # Analyze roots of the cubic T^3 + bT^2 + cT + d = 0, where b = a2/p, c = a4/p^2, d = a6/p^3
     379            b = a2/pi
     380            c = a4/(pi*pi)
     381            d = a6/(pi**3)
     382            bb = b*b
     383            cc = c*c
     384            bc = b*c
     385            w = 27*d*d - bb*cc + 4*b*bb*d - 18*bc*d + 4*c*cc
     386            x = 3*c - bb
     387            if pdiv(w):
     388                if pdiv(x):
     389                    sw = 3
     390                else:
     391                    sw = 2
     392            else:
     393                sw = 1
     394            verbose("Analyzing roots of cubic T^3 + %s*T^2 + %s*T + %s, case %s"%(b, c, d, sw), t, 1)
     395            if sw == 1:
     396                ## Three distinct roots - Type I*0
     397                verbose("Distinct roots", t, 1)
     398                KS = KodairaSymbol("I0*")
     399                cp = 1 + _pcubicroots(b, c, d)
     400                fp = val_disc - 4
     401                break #return
     402            elif sw == 2:
     403                ## One double root - Type I*m for some m
     404                verbose("One double root", t, 1)
     405                ## Change coords so that the double root is T = 0 mod p
     406                if p == 2:
     407                    r = proot(c, 2)
     408                elif p == 3:
     409                    r = c * pinv(b)
     410                else:
     411                    r = (bc - 9*d)*pinv(2*x)
     412                r = pi * preduce(r)
     413                C = C.rst_transform(r, 0, 0)
     414                (a1, a2, a3, a4, a6) = C.a_invariants()
     415                (b2, b4, b6, b8) = C.b_invariants()
     416                ix = 3; iy = 3; mx = pi*pi; my = pi*pi
     417                while True:
     418                    a2t = a2 / pi
     419                    a3t = a3 / my
     420                    a4t = a4 / (pi*mx)
     421                    a6t = a6 / (mx*my)
     422                    if pdiv(a3t*a3t + 4*a6t):
     423                        if p == 2:
     424                            t = my*proot(a6t, 2)
     425                        else:
     426                            t = my*preduce(-a3t*halfmodp)
     427                        C = C.rst_transform(0, 0, t)
     428                        (a1, a2, a3, a4, a6) = C.a_invariants()
     429                        (b2, b4, b6, b8) = C.b_invariants()
     430                        my = my*pi
     431                        iy += 1
     432                        a2t = a2/pi
     433                        a3t = a3/my
     434                        a4t = a4/(pi*mx)
     435                        a6t = a6/(mx*my)
     436                        if pdiv(a4t*a4t - 4*a6t*a2t):
     437                            if p == 2:
     438                                r = mx*proot(a6t*pinv(a2t), 2)
     439                            else:
     440                                r = mx*preduce(-a4t*pinv(2*a2t))
     441                            C = C.rst_transform(r, 0, 0)
     442                            (a1, a2, a3, a4, a6) = C.a_invariants()
     443                            (b2, b4, b6, b8) = C.b_invariants()
     444                            mx = mx*pi
     445                            ix += 1 # and stay in loop
     446                        else:
     447                            if _pquadroots(a2t, a4t, a6t):
     448                                cp = 4
     449                            else:
     450                                cp = 2
     451                            break # exit loop
     452                    else:
     453                        if _pquadroots(1, a3t, -a6t):
     454                            cp = 4
     455                        else:
     456                            cp = 2
     457                        break
     458                KS = KodairaSymbol("I%s*"%(ix+iy-5))
     459                fp = val_disc - ix - iy + 1
     460                break #return
     461            else: # sw == 3
     462                ## The cubic has a triple root
     463                verbose("Triple root", t, 1)
     464                ## First we change coordinates so that T = 0 mod p
     465                if p == 2:
     466                    r = b
     467                elif p == 3:
     468                    r = proot(-d, 3)
     469                else:
     470                    r = -b * pinv(3)
     471                r = pi*preduce(r)
     472                C = C.rst_transform(r, 0, 0)
     473                (a1, a2, a3, a4, a6) = C.a_invariants()
     474                (b2, b4, b6, b8) = C.b_invariants()
     475                verbose("After third transform %s\n[a1,a2,a3,a4,a6] = %s\nValuations: %s"%([r,0,0],[a1,a2,a3,a4,a6],[pval(ai) for ai in [a1,a2,a3,a4,a6]]), t, 2)
     476                if min(pval(ai) for ai in [a1,a2,a3,a4,a6]) < 0:
     477                    raise RuntimeError, "Non-integral model after third transform!"
     478                if pval(a2) < 2 or pval(a4) < 3 or pval(a6) < 4:
     479                    raise RuntimeError, "Cubic after transform does not have a triple root at 0"
     480                a3t = a3/(pi*pi)
     481                a6t = a6/(pi**4)
     482                # We test for Type IV*
     483                if not pdiv(a3t*a3t + 4*a6t):
     484                    cp = 3 if _pquadroots(1, a3t, -a6t) else 1
     485                    KS = KodairaSymbol("IV*")
     486                    fp = val_disc - 6
     487                    break #return
     488                # Now change coordinates so that p^3|a3, p^5|a6
     489                t =        -pi*pi*proot(a6t, 2) if p==2 \
     490                      else  pi*pi*preduce(-a3t*halfmodp)
     491                C = C.rst_transform(0, 0, t)
     492                (a1, a2, a3, a4, a6) = C.a_invariants()
     493                (b2, b4, b6, b8) = C.b_invariants()
     494                # We test for types III* and II*
     495                if pval(a4) < 4:
     496                    ## Type III*
     497                    KS = KodairaSymbol("III*")
     498                    fp = val_disc - 7
     499                    cp = 2
     500                    break #return
     501                if pval(a6) < 6:
     502                    ## Type II*
     503                    KS = KodairaSymbol("II*")
     504                    fp = val_disc - 8
     505                    cp = 1
     506                    break #return
     507                a1 /= pi
     508                a2 /= pi**2
     509                a3 /= pi**3
     510                a4 /= pi**4
     511                a6 /= pi**6
     512                verbose("Non-minimal equation, dividing out...\nNew model is %s"%([a1, a2, a3, a4, a6]), t, 1)
     513        C = C._tidy_model()
     514        return (C, p, val_disc, fp, KS, cp)
     515   
     516   
     517def check_prime(K,P):
     518    """
     519    Function to check that P determines a prime of K, and return that ideal.
     520
     521    INPUT:
     522        K -- a number field (including QQ)
     523        P -- an element of K or a (fractional) ideal of K
     524
     525    OUTPUT:
     526        A prime ideal equal to or generated by P, or raise an error if invalid.
     527
     528    EXAMPLES:
     529        sage: from sage.schemes.elliptic_curves.ell_local_data import check_prime
     530        sage: check_prime(QQ,3)
     531        Principal ideal (3) of Integer Ring
     532        sage: check_prime(QQ,ZZ.ideal(31))
     533        Principal ideal (31) of Integer Ring
     534        sage: K.<a>=NumberField(x^2-5)
     535        sage: check_prime(K,a)
     536        Fractional ideal (a)
     537        sage: check_prime(K,a+1)
     538        Fractional ideal (a + 1)
     539        sage: [check_prime(K,P) for P in K.primes_above(31)]
     540        [Fractional ideal (-5/2*a - 1/2), Fractional ideal (-5/2*a + 1/2)]
     541    """
     542    if K is QQ:
     543        if isinstance(P, (int,long,Integer)):
     544            P = ZZ.ideal(Integer(P))
     545        if is_Ideal(P) and P.base_ring() is ZZ and P.is_prime():
     546            return P
     547        raise TypeError, "%s is not a prime ideal of %s"%(P,ZZ)
     548
     549    if not is_NumberField(K):
     550        raise TypeError, "%s is not a number field"%K
     551       
     552    if is_NumberFieldFractionalIdeal(P):
     553        if P.is_prime():
     554            return P
     555        else:
     556            raise TypeError, "%s is not a prime ideal of %s"%(P,K)
     557   
     558    if is_NumberFieldElement(P):
     559        if P in K:
     560            P = K.ideal(P)
     561        else:
     562            raise TypeError, "%s is not an element of %s"%(P,K)
     563        if P.is_prime():
     564            return P
     565        else:
     566            raise TypeError, "%s is not a prime ideal of %s"%(P,K)
     567   
     568    raise TypeError, "%s is not a valid prime of %s"%(P,K)
  • sage/schemes/elliptic_curves/ell_number_field.py

    diff -r b1ff622d9c6e -r ae41d53e73be sage/schemes/elliptic_curves/ell_number_field.py
    a b class EllipticCurve_number_field(Ellipti 
    183183        primes if P is a list or tuple
    184184       
    185185        EXAMPLES:
    186             sage: K.<i>=NumberField(x^2+1)
    187             sage: P1,P2 =(K.factor(5)[j][0] for j in (0,1))
    188             sage: E=EllipticCurve([i/5,i/5,i/5,i/5,i/5])
     186            sage: K.<i> = NumberField(x^2+1)
     187            sage: P1,P2 = K.primes_above(5)
     188            sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5])
    189189            sage: E.is_local_integral_model(P1,P2)
    190190            False
    191             sage: Emin=E.local_integral_model(P1,P2)
     191            sage: Emin = E.local_integral_model(P1,P2)
    192192            sage: Emin.is_local_integral_model(P1,P2)
    193193            True
    194194        """
    class EllipticCurve_number_field(Ellipti 
    203203        NB Does not affect integrality at other primes even if P non-principal
    204204       
    205205        EXAMPLES:
    206             sage: K.<i>=NumberField(x^2+1)
    207             sage: P1,P2 =(K.factor(5)[j][0] for j in (0,1))
    208             sage: E=EllipticCurve([i/5,i/5,i/5,i/5,i/5])
     206            sage: K.<i> = NumberField(x^2+1)
     207            sage: P1,P2 = K.primes_above(5)
     208            sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5])
    209209            sage: E.local_integral_model((P1,P2))
    210210            Elliptic Curve defined by y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i over Number Field in i with defining polynomial x^2 + 1
    211211        """
    class EllipticCurve_number_field(Ellipti 
    224224        Return true iff self is integral at all primes
    225225       
    226226        EXAMPLES:
    227             sage: K.<i>=NumberField(x^2+1)
    228             sage: E=EllipticCurve([i/5,i/5,i/5,i/5,i/5])
    229             sage: P1,P2 = (K.factor(5)[j][0] for j in (0,1))
    230             sage: Emin=E.global_integral_model()
     227            sage: K.<i> = NumberField(x^2+1)
     228            sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5])
     229            sage: P1,P2 = K.primes_above(5)
     230            sage: Emin = E.global_integral_model()
    231231            sage: Emin.is_global_integral_model()
    232232            True
    233233        """
    class EllipticCurve_number_field(Ellipti 
    238238        Return a model of self which is integral at all primes
    239239       
    240240        EXAMPLES:
    241             sage: K.<i>=NumberField(x^2+1)
    242             sage: E=EllipticCurve([i/5,i/5,i/5,i/5,i/5])
    243             sage: P1,P2 = (K.factor(5)[j][0] for j in (0,1))
     241            sage: K.<i> = NumberField(x^2+1)
     242            sage: E = EllipticCurve([i/5,i/5,i/5,i/5,i/5])
     243            sage: P1,P2 = K.primes_above(5)
    244244            sage: E.global_integral_model()
    245245            Elliptic Curve defined by y^2 + (-i)*x*y + (-25*i)*y = x^3 + 5*i*x^2 + 125*i*x + 3125*i over Number Field in i with defining polynomial x^2 + 1
    246246
    class EllipticCurve_number_field(Ellipti 
    257257            assert z.denominator() == 1, "bug in global_integral_model: %s" % ai
    258258        return EllipticCurve(ai)
    259259
    260     def integral_model(self):
    261         r"""
    262         Return a weierstrass model, $F$, of self with integral coefficients,
    263         along with a morphism $\phi$ of points on self to points on $F$.
    264        
    265         EXAMPLES:
    266             sage: E = EllipticCurve([1/2,0,0,5,1/3])
    267             sage: F, phi = E.integral_model()
    268             sage: F
    269             Elliptic Curve defined by y^2 + 3*x*y  = x^3 + 6480*x + 15552 over Rational Field
    270             sage: phi
    271             Generic morphism:
    272               From: Abelian group of points on Elliptic Curve defined by y^2 + 1/2*x*y  = x^3 + 5*x + 1/3 over Rational Field
    273               To:   Abelian group of points on Elliptic Curve defined by y^2 + 3*x*y  = x^3 + 6480*x + 15552 over Rational Field
    274               Via:  (u,r,s,t) = (1/6, 0, 0, 0)
    275             sage: P = E([4/9,41/27])
    276             sage: phi(P)
    277             (16 : 328 : 1)
    278             sage: phi(P) in F
    279             True
    280         """
    281         F = self.global_integral_model()
    282         return F, self.isomorphism_to(F)
    283        
     260    integral_model = global_integral_model
     261
    284262    def _tidy_model(self):
    285263        """
    286264        Transforms the elliptic curve to a model in which a1, a2, a3
    287265        are reduced modulo 2, 3, 2 respectively.
    288266
    289         This only works on integral models, ie it requires that a1, a2
     267        This only works on integral models, i.e. it requires that a1, a2
    290268        and a3 lie in the ring of integers of the base field.
    291269
    292270        EXAMPLES:
    class EllipticCurve_number_field(Ellipti 
    301279            8456608930180227786550494643437985949781*a - 52130038506835491453281450568107193773505]
    302280
    303281            sage: E._tidy_model().ainvs()
    304             [-a,
     282            [a,
    305283            a + 1,
    306             -11*a + 151,
    307             368258520200522046806318520*a - 2270097978636731786720859535,
    308             8456608930173478039472018047583706317255*a - 52130038506793883217874390501829588398139]
     284            a + 1,
     285            368258520200522046806318444*a - 2270097978636731786720859345,
     286            8456608930173478039472018047583706316424*a - 52130038506793883217874390501829588391299]
     287            sage: EllipticCurve([101,202,303,404,505])._tidy_model().ainvs()
     288            [1, 1, 0, -2509254, 1528863051]
     289            sage: EllipticCurve([-101,-202,-303,-404,-505])._tidy_model().ainvs()
     290            [1, -1, 0, -1823195, 947995262]
    309291        """
    310292        ZK = self.base_ring().maximal_order()
    311         (a1, a2, a3, a4, a6) = [ZK(a) for a in self.a_invariants()]
     293        try:
     294            (a1, a2, a3, a4, a6) = [ZK(a) for a in self.a_invariants()]
     295        except TypeError:
     296            raise TypeError, "_tidy_model() requires an integral model."
    312297        # N.B. Must define s, r, t in the right order.
    313         s = -ZK([(a/2).round('away') for a in a1.list()])
    314         r = -ZK([(a/3).round('away') for a in (a2 + s*a1 +s*s).list()])
    315         t = -ZK([(a/2).round('away') for a in (a3 - r*a1).list()])
     298        if ZK.degree() == 1:
     299            s = ((-a1)/2).round('up')
     300            r = ((-a2 + s*a1 +s*s)/3).round()
     301            t = ((-a3 - r*a1)/2).round('up')
     302        else:
     303            s = ZK([(a/2).round('up') for a in (-a1).list()])
     304            r = ZK([(a/3).round() for a in (-a2 + s*a1 +s*s).list()])
     305            t = ZK([(a/2).round('up') for a in (-a3 - r*a1).list()])
    316306
    317307        return self.rst_transform(r, s, t)
    318308
    319     def local_information(self, P=None, proof = None):
    320         """
    321         Tate's algorithm for an elliptic curve over a number field.
     309    def local_data(self, P=None, proof = None):
     310        r"""
     311        Local data for this elliptic curve at a prime.
    322312
    323         If a prime P of the base field is specified, computes local
    324         reduction data at the prime ideal P and a local minimal model.
    325         If no P is specified, computes local information at all bad primes.
     313        If a prime $P$ of the base field is specified, computes local
     314        reduction data at the prime ideal $P$ and a local minimal model.
     315        If no $P$ is specified, computes local information at all primes
     316        in the support of the discriminant of this model.
    326317
    327318        The model is not required to be integral on input.
    328         If P is principal, uses a generator as uniformizer, so it will not affect
    329         integrality or minimality at other primes.
    330         If P is not principal, the minimal model returned will preserve integrality
    331         at other primes, but not minimality.
     319
     320        If $P$ is principal, uses a generator as uniformizer, so it
     321        will not affect integrality or minimality at other primes.  If
     322        $P$ is not principal, the minimal model returned will preserve
     323        integrality at other primes, but not minimality.
    332324
    333325        INPUT:
    334326            self -- an elliptic curve over a number field.
    335             P    -- either None or a prime ideal of the base field of self.
    336             proof -- whether to only use provably correct methods (default controled by
    337                      global proof module).  Note that the proof module is number_field,
    338                      not elliptic_curves, since the functions that actually need the flag
    339                      are in number fields.
     327            $P$    -- either None or a prime ideal of the base field of self.
     328            proof -- whether to only use provably correct methods
     329                     (default controled by global proof module).  Note
     330                     that the proof module is number_field, not
     331                     elliptic_curves, since the functions that
     332                     actually need the flag are in number fields.
    340333                     
    341334        OUTPUT:
    342             If P specified, returns a 6-tuple with the following data:
    343               Emin -- a model (integral and) minimal at P
    344               p    -- the residue characteristic
    345               vpd  -- the valuation of the local minimal discriminant
    346               fp   -- valuation of the conductor
    347               KS   -- Kodaira symbol
    348               cp   -- Tamagawa number
    349             Otherwise, for all primes dividing the discriminant, returns a pair with the first
    350             member of the pair being that prime P, and the second being a tuple with the above
    351             data for that P.
     335
     336            If $P$ specified, returns the EllipticCurveLocalData object
     337            associated to the prime P for this curve.  Otherwise,
     338            returns a list of such objects, one for each prime $P$
     339            in the support of the discriminant.
    352340
    353341        EXAMPLES
    354342            sage: K.<i> = NumberField(x^2+1)
    355343            sage: E = EllipticCurve([1 + i  ,0  ,1  ,0  ,0  ])
    356             sage: E.local_information()
    357             [(Fractional ideal (-3*i - 2),
    358             (Elliptic Curve defined by y^2 + (i+1)*x*y + (4*i+7)*y = x^3 + 12*x^2 + (-i+47)*x + (-4*i+58) over Number Field in i with defining polynomial x^2 + 1, 13, 2, 1, I2, 2)),
    359             (Fractional ideal (2*i + 1),
    360             (Elliptic Curve defined by y^2 + (i+1)*x*y + (4*i+7)*y = x^3 + 12*x^2 + (-i+47)*x + (-4*i+58) over Number Field in i with defining polynomial x^2 + 1, 5, 1, 1, I1, 1))]
    361             sage: E.local_information(K.ideal(3))
    362             (Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1,
    363             3, 0, 0, I0, 1)
     344            sage: E.local_data()
     345            [Local data at Fractional ideal (-3*i - 2) of Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1:
     346            Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1
     347            Minimal discriminant valuation: 2
     348            Conductor exponent: 1
     349            Kodaira Symbol: I2
     350            Tamagawa Number: 2, Local data at Fractional ideal (2*i + 1) of Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1:
     351            Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1
     352            Minimal discriminant valuation: 1
     353            Conductor exponent: 1
     354            Kodaira Symbol: I1
     355            Tamagawa Number: 1]
     356            sage: E.local_data(K.ideal(3))
     357            Local data at Fractional ideal (3) of Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1:
     358            Local minimal model: Elliptic Curve defined by y^2 + (i+1)*x*y + y = x^3 over Number Field in i with defining polynomial x^2 + 1
     359            Minimal discriminant valuation: 0
     360            Conductor exponent: 0
     361            Kodaira Symbol: I0
     362            Tamagawa Number: 1
     363
     364        An example raised in \#3897:
     365            sage: E = EllipticCurve([1,1])
     366            sage: E.local_data(3)
     367            Local data at Principal ideal (3) of Integer Ring of Elliptic Curve defined by y^2  = x^3 + x +1 over Rational Field:
     368            Local minimal model: Elliptic Curve defined by y^2  = x^3 + x +1 over Rational Field
     369            Minimal discriminant valuation: 0
     370            Conductor exponent: 0
     371            Kodaira Symbol: I0
     372            Tamagawa Number: 1
    364373        """
    365374        if proof is None:
    366375            import sage.structure.proof.proof
    367376            # We use the "number_field" flag because the actual proof dependence is in Pari's number field functions.
    368377            proof = sage.structure.proof.proof.get_flag(None, "number_field")
     378
    369379        if P is None:
    370             primes = [f[0] for f in self.base_ring().ideal(self.discriminant()).factor()]
    371             return [(pr, self._tate(pr, proof)) for pr in primes]
    372         if not (is_NumberFieldFractionalIdeal(P) and P.is_prime() # and P.order() == self.base_ring().integers()
    373                 or is_NumberFieldElement(P) and P.parent().ideal(P).is_prime()
    374                 or self.base_ring() is QQ and (isinstance(P, Integer) and P.is_prime()
    375                                                or is_Ideal(P) and P.base_ring() is ZZ and P.is_prime())):
    376             raise TypeError, "second argument must be a prime ideal"
    377         if isinstance(P, RingElement):
    378             P = self.base_ring().ideal(P)
    379         return self.integral_model()[0]._tate(P, proof)
     380            primes = self.base_ring()(self.discriminant()).support()
     381            return [self._get_local_data(pr, proof) for pr in primes]
     382
     383        from sage.schemes.elliptic_curves.ell_local_data import check_prime
     384        P = check_prime(self.base_field(),P)
     385
     386        return self._get_local_data(P,proof)       
     387
     388    def _get_local_data(self, P, proof):
     389        """
     390        Internal function to create data for this elliptic curve at a prime.
     391       
     392        This function handles the caching of local data.  It is called
     393        by local_data() which is the user interface and which parses
     394        the input parameters P and proof.
     395        """
     396        try:
     397            return self._local_data[P]
     398        except AttributeError:
     399            self._local_data = {}
     400        except KeyError:
     401            pass
     402        from sage.schemes.elliptic_curves.ell_local_data import EllipticCurveLocalData   
     403        self._local_data[P] = EllipticCurveLocalData(self, P, proof)
     404        return self._local_data[P]       
    380405
    381406    def local_minimal_model(self, P, proof = None):
    382407        """
    class EllipticCurve_number_field(Ellipti 
    404429            sage: E=EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875])
    405430            sage: P=K.ideal(a)
    406431            sage: E.local_minimal_model(P).ainvs()
    407             [20, -87, 30, a - 277, 2*a - 213]
     432            [0, 1, 0, a - 33, -2*a + 64]
    408433        """
    409434        if proof is None:
    410435            import sage.structure.proof.proof
    411436            # We use the "number_field" flag because the actual proof dependence is in Pari's number field functions.
    412437            proof = sage.structure.proof.proof.get_flag(None, "number_field")
    413         if not (is_NumberFieldFractionalIdeal(P) and P.is_prime() # and P.order() == self.base_ring().integers()
    414                 or is_NumberFieldElement(P) and P.parent().ideal(P).is_prime()
    415                 or self.base_ring() is QQ and (isinstance(P, Integer) and P.is_prime()
    416                                                or is_Ideal(P) and P.base_ring() is ZZ and P.is_prime())):
    417             raise TypeError, "second argument must be a prime ideal"
    418         if isinstance(P, RingElement):
    419             P = self.base_ring().ideal(P)
    420         return self.local_information(P, proof)[0]
     438
     439        return self.local_data(P, proof).minimal_model()
     440
     441    def tamagawa_number(self, P, proof = None):
     442        """
     443        Returns the Tamagawa number of this elliptic curve at the prime P.
     444
     445        INPUT:
     446            self -- an elliptic curve over a number field.
     447            P -- a prime ideal of the base field of self, or a field
     448                 element generating such an ideal.
     449            proof -- whether to only use provably correct methods
     450                     (default controled by global proof module).  Note
     451                     that the proof module is number_field, not
     452                     elliptic_curves, since the functions that
     453                     actually need the flag are in number fields.
     454
     455        OUTPUT:
     456            c -- (positive integer) the Tamagawa number of the curve at P.
     457
     458        EXAMPLES:
     459            sage: K.<a>=NumberField(x^2-5)
     460            sage: E=EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875])
     461            sage: [E.tamagawa_number(P) for P in E.discriminant().support()]
     462            [1, 1, 1, 1]
     463            sage: K.<a> = QuadraticField(-11)
     464            sage: E = EllipticCurve('11a1').change_ring(K)
     465            sage: [E.tamagawa_number(P) for P in K(11).support()]
     466            [10]
     467        """
     468        if proof is None:
     469            import sage.structure.proof.proof
     470            # We use the "number_field" flag because the actual proof dependence is in Pari's number field functions.
     471            proof = sage.structure.proof.proof.get_flag(None, "number_field")
     472
     473        return self.local_data(P, proof).tamagawa_number()
     474
     475    def kodaira_symbol(self, P, proof = None):
     476        """
     477        Returns the Kodaira Symbol of this elliptic curve at the prime P.
     478
     479        INPUT:
     480            self -- an elliptic curve over a number field.
     481            P -- a prime ideal of the base field of self, or a field
     482                 element generating such an ideal.
     483            proof -- whether to only use provably correct methods
     484                     (default controled by global proof module).  Note
     485                     that the proof module is number_field, not
     486                     elliptic_curves, since the functions that
     487                     actually need the flag are in number fields.
     488
     489        OUTPUT:
     490            K -- (string) the Kodaira Symbol of the curve at P.
     491
     492        EXAMPLES:
     493            sage: K.<a>=NumberField(x^2-5)
     494            sage: E=EllipticCurve([20, 225, 750, 625*a + 6875, 31250*a + 46875])
     495            sage: bad_primes = E.discriminant().support(); bad_primes
     496            [Fractional ideal (7/2*a - 81/2),
     497            Fractional ideal (a + 52),
     498            Fractional ideal (-a),
     499            Fractional ideal (2)]
     500            sage: [E.kodaira_symbol(P) for P in bad_primes]
     501            [I1, I1, I0, II]
     502            sage: K.<a> = QuadraticField(-11)
     503            sage: E = EllipticCurve('11a1').change_ring(K)
     504            sage: [E.kodaira_symbol(P) for P in K(11).support()]
     505            [I10]
     506        """
     507        if proof is None:
     508            import sage.structure.proof.proof
     509            # We use the "number_field" flag because the actual proof dependence is in Pari's number field functions.
     510            proof = sage.structure.proof.proof.get_flag(None, "number_field")
     511
     512        return self.local_data(P, proof).kodaira_symbol()
     513
    421514
    422515    def conductor(self):
    423516        """
    class EllipticCurve_number_field(Ellipti 
    440533            sage: E.conductor()
    441534            Fractional ideal (1)
    442535        """
    443         ## Ported from John Cremona's code implementing Tate's algorithm.
    444         primes = [f[0] for f in self.base_ring().ideal(self.discriminant()).factor()]
    445         ans = self.base_ring().ideal(1)
    446         for P in primes:
    447             ans *= P**(self._tate(P)[3])
    448         return ans
     536        try:
     537            return self._conductor
     538        except AttributeError:
     539            pass
     540
     541        # Note: for number fields other than QQ we could initialize
     542        # N=K.ideal(1) or N=OK.ideal(1), which are the same, but for
     543        # K==QQ it has to be ZZ.ideal(1).
     544        OK = self.base_ring().ring_of_integers()
     545        self._conductor = prod([d.prime()**(d.conductor_valuation()) \
     546                                for d in self.local_data()],\
     547                               OK.ideal(1))
     548        return self._conductor
    449549
    450550    def global_minimal_model(self, proof = None):
    451551        """
    452         Returns a model of self that is minimal at all primes, and the conductor of self.
     552        Returns a model of self that is integral, minimal at all primes.
    453553       
    454         Note that this only works for class number 1.
     554        Note that this is only implemented for class number 1; in
     555        general such a model may or may not exist.
     556       
    455557        INPUT:
    456558            self -- an elliptic curve over a number field of class number
    457             proof -- whether to only use provably correct methods (default controled by
    458                      global proof module).  Note that the proof module is number_field,
    459                      not elliptic_curves, since the functions that actually need the flag
    460                      are in number fields.
     559            proof -- whether to only use provably correct methods
     560                     (default controled by global proof module).  Note
     561                     that the proof module is number_field, not
     562                     elliptic_curves, since the functions that
     563                     actually need the flag are in number fields.
    461564
    462565        OUTPUT:
    463             A 2-tuple consisting of a global minimal model, and
    464             the conductor of self as a fractional ideal of the base
    465             field.
     566            A global integral and minimal model.
    466567
    467568        EXAMPLES:
    468569            sage: K.<a> = NumberField(x^2-38)
    469570            sage: E = EllipticCurve([0,0,0, 21796814856932765568243810*a - 134364590724198567128296995, 121774567239345229314269094644186997594*a - 750668847495706904791115375024037711300])
    470571            sage: E.global_minimal_model()
    471             (Elliptic Curve defined by y^2 + a*x*y + (-39*a+237)*y = x^3 + (-5*a+19)*x^2 + (368258520200522046806318224*a-2270097978636731786720858047)*x + (8456608930180227786550494643437985949781*a-52130038506835491453281450568107193773505) over Number Field in a with defining polynomial x^2 - 38, Fractional ideal (1))
     572            Elliptic Curve defined by y^2 + a*x*y + (a+1)*y = x^3 + (a+1)*x^2 + (368258520200522046806318444*a-2270097978636731786720859345)*x + (8456608930173478039472018047583706316424*a-52130038506793883217874390501829588391299) over Number Field in a with defining polynomial x^2 - 38
    472573        """
    473         ## Ported from John Cremona's code implementing Tate's algorithm.
    474574        if proof is None:
    475575            import sage.structure.proof.proof
    476576            # We use the "number_field" flag because the actual proof dependence is in Pari's number field functions.
    class EllipticCurve_number_field(Ellipti 
    478578        K = self.base_ring()
    479579        if K.class_number() != 1:
    480580            raise ValueError, "global minimal models only exist in general for class number 1"
    481         primes = [f[0] for f in self.base_ring().ideal(self.discriminant()).factor()]
    482         N = K.ideal(1)
    483         E = self
     581
     582        E = self.global_integral_model()
     583        primes = self.base_ring()(self.discriminant()).support()
    484584        for P in primes:
    485             local_info = E._tate(P, proof)
    486             N *= P**local_info[3]
    487             E = local_info[0]
    488         return (E._tidy_model(), N)
     585            E = E.local_data(P,proof).minimal_model()
     586        return E._tidy_model()
    489587
    490     def _tate(self, P, proof = None):
    491         """
    492         Tate's algorithm for an elliptic curve over a number field:
    493         computes local reduction data at the prime ideal P and a local
    494         minimal model.
    495 
    496         The model is not required to be integral on input.  If P is
    497         principal, uses a generator as uniformizer, so it will not
    498         affect integrality or minimality at other primes.  If P is not
    499         principal, the minimal model returned will preserve
    500         integrality at other primes, but not minimality.
    501 
    502         INPUT:
    503             self -- an elliptic curve over a number field.
    504             P    -- a prime ideal of the base field of self.
    505 
    506         OUTPUT:
    507             Emin -- a model (integral and) minimal at P
    508             p    -- the residue characteristic
    509             vpd  -- the valuation of the local minimal discriminant
    510             fp   -- valuation of the conductor
    511             KS   -- Kodaira symbol
    512             cp   -- Tamagawa number
    513 
    514         EXAMPLES: see self.local_information()
    515         """
    516         ## Ported from John Cremona's code implementing Tate's algorithm.
    517         K = self.base_ring()
    518         OK = K.maximal_order()
    519         t = verbose("Running Tate's algorithm with P = %s"%P, level=1)
    520         F = OK.residue_field(P)
    521         p = F.characteristic()
    522         if P.is_principal():
    523             pi = P.gens_reduced()[0]
    524             verbose("P is principal, generator pi = %s"%pi, t, 1)
    525         else:
    526             pi = K.uniformizer(P, 'negative')
    527             verbose("P is not principal, uniformizer pi = %s"%pi, t, 1)
    528 
    529         def _pval(x):
    530             """
    531             Local function returning the valuation of x at P
    532             """
    533             if x==0: return Infinity
    534             return K.ideal(x).valuation(P)
    535         def _pdiv(x):
    536             """
    537             Local function returning True iff P divides x
    538             """
    539             return x==0 or _pval(x) > 0
    540         def _pinv(x):
    541             """
    542             Local function returning an inverse of x mod P
    543             """
    544             return F.lift(~F(x))
    545         def _proot(x, e):
    546             """
    547             Local function returning an e'th root of x mod P
    548             """
    549             L = F(x).nth_root(e, extend = False, all = True)
    550             assert len(L) > 0, "no e'th root exists mod P"
    551             return F.lift(L[0])
    552         def _preduce(x):
    553             """
    554             Local function returning x reduced modulo P
    555             """
    556             return F.lift(F(x))
    557         def _pquadroots(a, b, c):
    558             r"""
    559             Local function returning True iff $ax^2 + bx + c$ has roots modulo P
    560             """
    561             (a, b, c) = (F(a), F(b), F(c))
    562             if a == 0:
    563                 return (b != 0) or (c == 0)
    564             elif p == 2:
    565                 return len(PolynomialRing(F, "x")([c,b,a]).roots()) > 0
    566             else:
    567                 return (b**2 - 4*a*c).is_square()
    568         def _pcubicroots(b, c, d):
    569             r"""
    570             Local function returning the number of roots of $x^3 +
    571             b*x^2 + c*x + d$ modulo P, counting multiplicities
    572             """
    573             return sum([rr[1] for rr in PolynomialRing(F, 'x')([d, c, b, 1]).roots()],0)
    574 
    575         if p == 2:
    576             halfmodp = OK(Integer(0))
    577         else:
    578             halfmodp = _pinv(Integer(2))
    579 
    580         A = self.a_invariants()
    581         A = [0, A[0], A[1], A[2], A[3], 0, A[4]]
    582         indices = [1,2,3,4,6]
    583         if min([_pval(a) for a in A if a != 0]) < 0:
    584             verbose("Non-integral model at P: valuations are %s; making integral"%([_pval(a) for a in A if a != 0]), t, 1)
    585             e = 0
    586             for i in range(7):
    587                 if A[i] != 0:
    588                     e = max(e, (-_pval(A[i])/i).ceil())
    589             pie = pi**e
    590             for i in range(7):
    591                 if A[i] != 0:
    592                     A[i] *= pie**i
    593             verbose("P-integral model is %s, with valuations %s"%([A[i] for i in indices], [_pval(A[i]) for i in indices]), t, 1)
    594 
    595         (a1, a2, a3, a4, a6) = (A[1], A[2], A[3], A[4], A[6])
    596         while True:
    597             C = EllipticCurve([a1, a2, a3, a4, a6]);
    598             (b2, b4, b6, b8) = C.b_invariants()
    599             (c4, c6) = C.c_invariants()
    600             delta = C.discriminant()
    601             vpd = _pval(delta)
    602 
    603             if vpd == 0:
    604                 ## Good reduction already
    605                 cp = 1
    606                 fp = 0
    607                 KS = KodairaSymbol("I0")
    608                 break #return
    609 
    610             # Otherwise, we change coordinates so that p | a3, a4, a6
    611             if p == 2:
    612                 if _pdiv(b2):
    613                     r = _proot(a4, 2)
    614                     t = _proot(((r + a2)*r + a4)*r + a6, 2)
    615                 else:
    616                     temp = _pinv(a1)
    617                     r = temp * a3
    618                     t = temp * (a4 + r*r)
    619             elif p == 3:
    620                 if _pdiv(b2):
    621                     r = _proot(-b6, 3)
    622                 else:
    623                     r = -_pinv(b2) * b4
    624                 t = a1 * r + a3
    625             else:
    626                 if _pdiv(c4):
    627                     r = -_pinv(12) * b2
    628                 else:
    629                     r = -_pinv(12*c4) * (c6 + b2 * c4)
    630                 t = -halfmodp * (a1 * r + a3)
    631             r = _preduce(r)
    632             t = _preduce(t)
    633             # print "Before first tranform C = %s"%C
    634             # print "[a1,a2,a3,a4,a6] = %s"%([a1, a2, a3, a4, a6])
    635             C = C.rst_transform(r, 0, t)
    636             (a1, a2, a3, a4, a6) = C.a_invariants()
    637             (b2, b4, b6, b8) = C.b_invariants()
    638             if min([_pval(a) for a in (a1, a2, a3, a4, a6) if a != 0]) < 0:
    639                 raise RuntimeError, "Non-integral model after first transform!"
    640             verbose("After first transform %s\n, [a1,a2,a3,a4,a6] = %s\n, valuations = %s"%([r, 0, t], [a1, a2, a3, a4, a6], [_pval(a1), _pval(a2), _pval(a3), _pval(a4), _pval(a6)]), t, 2)
    641             if _pval(a3) == 0:
    642                 raise RuntimeError, "p does not divide a3 after first transform!"
    643             if _pval(a4) == 0:
    644                 raise RuntimeError, "p does not divide a4 after first transform!"
    645             if _pval(a6) == 0:
    646                 raise RuntimeError, "p does not divide a6 after first transform!"
    647 
    648             # Now we test for Types In, II, III, IV
    649             # Do we not have to update the c invariants?
    650             if not _pdiv(c4):
    651                 ## Type In (n = vpd)
    652                 if _pquadroots(1, a1, -a2):
    653                     cp = vpd
    654                 elif Integer(2).divides(vpd):
    655                     cp = 2
    656                 else:
    657                     cp = 1
    658                 KS = KodairaSymbol("I%s"%vpd)
    659                 fp = 1
    660                 break #return
    661             if _pval(a6) < 2:
    662                 ## Type II
    663                 KS = KodairaSymbol("II")
    664                 fp = vpd
    665                 cp = 1
    666                 break #return
    667             if _pval(b8) < 3:
    668                 ## Type III
    669                 KS = KodairaSymbol("III")
    670                 fp = vpd - 1
    671                 cp = 2
    672                 break #return
    673             if _pval(b6) < 3:
    674                 ## Type IV
    675                 if _pquadroots(1, a3 / pi, -a6/(pi*pi)):
    676                     cp = 3
    677                 else:
    678                     cp = 1
    679                 KS = KodairaSymbol("IV")
    680                 fp = vpd - 2
    681                 break #return
    682 
    683             # If our curve is none of these types, we change types so that p | a1, a2 and p^2 | a3, a4 and p^3 | a6
    684             if p == 2:
    685                 s = _proot(a2, 2)
    686                 t = pi*_proot(a6/(pi*pi), 2)
    687             elif p == 3:
    688                 s = a1
    689                 t = a3
    690             else:
    691                 s = -a1*halfmodp
    692                 t = -a3*halfmodp
    693             C = C.rst_transform(0, s, t)
    694             (a1, a2, a3, a4, a6) = C.a_invariants()
    695             (b2, b4, b6, b8) = C.b_invariants()
    696             verbose("After second transform %s\n[a1, a2, a3, a4, a6] = %s\nValuations: %s"%([0, s, t], [a1,a2,a3,a4,a6],[_pval(a1),_pval(a2),_pval(a3),_pval(a4),_pval(a6)]), t, 2)
    697             if _pval(a1) == 0:
    698                 raise RuntimeError, "p does not divide a1 after second transform!"
    699             if _pval(a2) == 0:
    700                 raise RuntimeError, "p does not divide a2 after second transform!"
    701             if _pval(a3) < 2:
    702                 raise RuntimeError, "p^2 does not divide a3 after second transform!"
    703             if _pval(a4) < 2:
    704                 raise RuntimeError, "p^2 does not divide a4 after second transform!"
    705             if _pval(a6) < 3:
    706                 raise RuntimeError, "p^3 does not divide a6 after second transform!"
    707             if min(_pval(a1), _pval(a2), _pval(a3), _pval(a4), _pval(a6)) < 0:
    708                 raise RuntimeError, "Non-integral model after second transform!"
    709 
    710             # Analyze roots of the cubic T^3 + bT^2 + cT + d = 0, where b = a2/p, c = a4/p^2, d = a6/p^3
    711             b = a2/pi
    712             c = a4/(pi*pi)
    713             d = a6/(pi**3)
    714             bb = b*b
    715             cc = c*c
    716             bc = b*c
    717             w = 27*d*d - bb*cc + 4*b*bb*d - 18*bc*d + 4*c*cc
    718             x = 3*c - bb
    719             if _pdiv(w):
    720                 if _pdiv(x):
    721                     sw = 3
    722                 else:
    723                     sw = 2
    724             else:
    725                 sw = 1
    726             verbose("Analyzing roots of cubic T^3 + %s*T^2 + %s*T + %s, case %s"%(b, c, d, sw), t, 1)
    727             if sw == 1:
    728                 ## Three distinct roots - Type I*0
    729                 verbose("Distinct roots", t, 1)
    730                 KS = KodairaSymbol("I0*")
    731                 cp = 1 + _pcubicroots(b, c, d)
    732                 fp = vpd - 4
    733                 break #return
    734             elif sw == 2:
    735                 ## One double root - Type I*m for some m
    736                 verbose("One double root", t, 1)
    737                 ## Change coords so that the double root is T = 0 mod p
    738                 if p == 2:
    739                     r = _proot(c, 2)
    740                 elif p == 3:
    741                     r = c * _pinv(b)
    742                 else:
    743                     r = (bc - 9*d)*_pinv(2*x)
    744                 r = pi * _preduce(r)
    745                 C = C.rst_transform(r, 0, 0)
    746                 (a1, a2, a3, a4, a6) = C.a_invariants()
    747                 (b2, b4, b6, b8) = C.b_invariants()
    748                 ix = 3; iy = 3; mx = pi*pi; my = pi*pi
    749                 while True:
    750                     a2t = a2 / pi
    751                     a3t = a3 / my
    752                     a4t = a4 / (pi*mx)
    753                     a6t = a6 / (mx*my)
    754                     if _pdiv(a3t*a3t + 4*a6t):
    755                         if p == 2:
    756                             t = my*_proot(a6t, 2)
    757                         else:
    758                             t = my*_preduce(-a3t*halfmodp)
    759                         C = C.rst_transform(0, 0, t)
    760                         (a1, a2, a3, a4, a6) = C.a_invariants()
    761                         (b2, b4, b6, b8) = C.b_invariants()
    762                         my = my*pi
    763                         iy += 1
    764                         a2t = a2/pi
    765                         a3t = a3/my
    766                         a4t = a4/(pi*mx)
    767                         a6t = a6/(mx*my)
    768                         if _pdiv(a4t*a4t - 4*a6t*a2t):
    769                             if p == 2:
    770                                 r = mx*_proot(a6t*_pinv(a2t), 2)
    771                             else:
    772                                 r = mx*_preduce(-a4t*_pinv(2*a2t))
    773                             C = C.rst_transform(r, 0, 0)
    774                             (a1, a2, a3, a4, a6) = C.a_invariants()
    775                             (b2, b4, b6, b8) = C.b_invariants()
    776                             mx = mx*pi
    777                             ix += 1 # and stay in loop
    778                         else:
    779                             if _pquadroots(a2t, a4t, a6t):
    780                                 cp = 4
    781                             else:
    782                                 cp = 2
    783                             break # exit loop
    784                     else:
    785                         if _pquadroots(1, a3t, -a6t):
    786                             cp = 4
    787                         else:
    788                             cp = 2
    789                         break
    790                 KS = KodairaSymbol("I%s*"%(ix+iy-5))
    791                 fp = vpd - ix - iy + 1
    792                 break #return
    793             else: # sw == 3
    794                 ## The cubic has a triple root
    795                 verbose("Triple root", t, 1)
    796                 ## First we change coordinates so that T = 0 mod p
    797                 if p == 2:
    798                     r = b
    799                 elif p == 3:
    800                     r = _proot(-d, 3)
    801                 else:
    802                     r = -b * _pinv(3)
    803                 r = pi*_preduce(r)
    804                 C = C.rst_transform(r, 0, 0)
    805                 (a1, a2, a3, a4, a6) = C.a_invariants()
    806                 (b2, b4, b6, b8) = C.b_invariants()
    807                 verbose("After third transform %s\n[a1,a2,a3,a4,a6] = %s\nValuations: %s"%([r,0,0],[a1,a2,a3,a4,a6],[_pval(ai) for ai in [a1,a2,a3,a4,a6]]), t, 2)
    808                 if min(_pval(ai) for ai in [a1,a2,a3,a4,a6]) < 0:
    809                     raise RuntimeError, "Non-integral model after third transform!"
    810                 if _pval(a2) < 2 or _pval(a4) < 3 or _pval(a6) < 4:
    811                     raise RuntimeError, "Cubic after transform does not have a triple root at 0"
    812                 a3t = a3/(pi*pi)
    813                 a6t = a6/(pi**4)
    814                 # We test for Type IV*
    815                 if not _pdiv(a3t*a3t + 4*a6t):
    816                     cp = 3 if _pquadroots(1, a3t, -a6t) else 1
    817                     KS = KodairaSymbol("IV*")
    818                     fp = vpd - 6
    819                     break #return
    820                 # Now change coordinates so that p^3|a3, p^5|a6
    821                 t =        -pi*pi*_proot(a6t, 2) if p==2 \
    822                       else  pi*pi*_preduce(-a3t*halfmodp)
    823                 C = C.rst_transform(0, 0, t)
    824                 (a1, a2, a3, a4, a6) = C.a_invariants()
    825                 (b2, b4, b6, b8) = C.b_invariants()
    826                 # We test for types III* and II*
    827                 if _pval(a4) < 4:
    828                     ## Type III*
    829                     KS = KodairaSymbol("III*")
    830                     fp = vpd - 7
    831                     cp = 2
    832                     break #return
    833                 if _pval(a6) < 6:
    834                     ## Type II*
    835                     KS = KodairaSymbol("II*")
    836                     fp = vpd - 8
    837                     cp = 1
    838                     break #return
    839                 a1 /= pi
    840                 a2 /= pi**2
    841                 a3 /= pi**3
    842                 a4 /= pi**4
    843                 a6 /= pi**6
    844                 verbose("Non-minimal equation, dividing out...\nNew model is %s"%([a1, a2, a3, a4, a6]), t, 1)
    845         return (C, p, vpd, fp, KS, cp)
    846    
    847    
    848588    def reduction(self,place):
    849589       """
    850590       Return the reduction of the elliptic curve at a place of good reduction
    class EllipticCurve_number_field(Ellipti 
    915655        # runs through primes, decomposes them into prime ideals
    916656        while k < number_of_places :
    917657            p = p.next_prime()
    918             f = K.factor(p)
     658            f = K.primes_above(p)
    919659            # runs through prime ideals above p
    920             for qq in [a[0] for a in f]:
     660            for qq in f:
    921661                fqq = qq.residue_class_degree()
    922662                charqq = qq.smallest_integer()
    923663                # take only places with small residue field (so that the
  • sage/schemes/elliptic_curves/ell_rational_field.py

    diff -r b1ff622d9c6e -r ae41d53e73be sage/schemes/elliptic_curves/ell_rational_field.py
    a b class EllipticCurve_rational_field(Ellip 
    347347                               limited to small conductor until mwrank
    348348                               gets integer factorization)
    349349                   "gp" -- use the GP interpreter.
    350                    "all" -- use both implementations, verify that the
     350                   "generic" -- use the general number field implementation
     351                   "all" -- use all four implementations, verify that the
    351352                            results are the same (or raise an error),
    352353                            and output the common value.
    353354                                     
    class EllipticCurve_rational_field(Ellip 
    359360            3006
    360361            sage: E.conductor(algorithm="gp")
    361362            3006
     363            sage: E.conductor(algorithm="generic")
     364            3006
    362365            sage: E.conductor(algorithm="all")
    363366            3006
    364367
    365         NOTE: The conductor computed using each algorithm is cached separately.
    366         Thus calling E.conductor("pari"), then E.conductor("mwrank") and
    367         getting the same result checks that both systems compute the same answer.
     368        NOTE: The conductor computed using each algorithm is cached
     369        separately.  Thus calling E.conductor("pari"), then
     370        E.conductor("mwrank") and getting the same result checks that both
     371        systems compute the same answer.
    368372        """
    369373
    370374        if algorithm == "pari":
    class EllipticCurve_rational_field(Ellip 
    391395                    self.__conductor_mwrank = Integer(self.minimal_model().mwrank_curve().conductor())
    392396            return self.__conductor_mwrank
    393397
     398        elif algorithm == "generic":
     399            try:
     400                return self.__conductor_generic
     401            except AttributeError:
     402                self.__conductor_generic = sage.schemes.elliptic_curves.ell_number_field.EllipticCurve_number_field.conductor(self).gen()
     403                return self.__conductor_generic
     404
    394405        elif algorithm == "all":
    395406            N1 = self.conductor("pari")
    396407            N2 = self.conductor("mwrank")
    397408            N3 = self.conductor("gp")
    398             if N1 != N2 or N2 != N3:
    399                 raise ArithmeticError, "Pari, mwrank and gp compute different conductors (%s,%s,%s) for %s"%(
    400                     N1, N2, N3, self)
     409            N4 = self.conductor("generic")
     410            if N1 != N2 or N2 != N3 or N2 != N4:
     411                raise ArithmeticError, "Pari, mwrank, gp and Sage compute different conductors (%s,%s,%s,%3) for %s"%(
     412                    N1, N2, N3, N4, self)
    401413            return N1
    402414        else:
    403415            raise RuntimeError, "algorithm '%s' is not known."%algorithm
    class EllipticCurve_rational_field(Ellip 
    22452257            assert z.denominator() == 1, "bug in global_integral_model: %s" % ai
    22462258        return constructor.EllipticCurve(ai)
    22472259
    2248     def integral_model(self):
    2249         r"""
    2250         Return a weierstrass model, $F$, of self with integral coefficients,
    2251         along with a morphism $\phi$ of points on self to points on $F$.
    2252        
    2253         EXAMPLES:
    2254             sage: E = EllipticCurve([1/2,0,0,5,1/3])
    2255             sage: F, phi = E.integral_model()
    2256             sage: F
    2257             Elliptic Curve defined by y^2 + 3*x*y  = x^3 + 6480*x + 15552 over Rational Field
    2258             sage: phi
    2259             Generic morphism:
    2260               From: Abelian group of points on Elliptic Curve defined by y^2 + 1/2*x*y  = x^3 + 5*x + 1/3 over Rational Field
    2261               To:   Abelian group of points on Elliptic Curve defined by y^2 + 3*x*y  = x^3 + 6480*x + 15552 over Rational Field
    2262               Via:  (u,r,s,t) = (1/6, 0, 0, 0)
    2263             sage: P = E([4/9,41/27])
    2264             sage: phi(P)
    2265             (16 : 328 : 1)
    2266             sage: phi(P) in F
    2267             True
    2268         """
    2269         F = self.global_integral_model()
    2270         return F, self.isomorphism_to(F)
    2271 
     2260    integral_model = global_integral_model
     2261   
    22722262    def integral_short_weierstrass_model(self):
    22732263        r"""
    22742264        Return a model of the form $y^2 = x^3 + a*x + b$ for this curve with $a,b\in\Z$.
  • sage/schemes/elliptic_curves/gp_simon.py

    diff -r b1ff622d9c6e -r ae41d53e73be sage/schemes/elliptic_curves/gp_simon.py
    a b def simon_two_descent(E, verbose=0, lim1 
    6161    current_randstate().set_seed_gp(gp)
    6262
    6363    K = E.base_ring()
    64     F, transform = E.integral_model()
     64    F = E.integral_model()
    6565   
    6666    if K != QQ:
    6767        # Simon's program requires that this name be y.
    def simon_two_descent(E, verbose=0, lim1 
    9696    def _gp_mod(*args):
    9797        return args[0]
    9898    ans = sage_eval(v, {'Mod': _gp_mod, 'y': K.gen(0)})
    99     inv_transform = ~transform
     99    inv_transform = F.isomorphism_to(E)
    100100    ans[2] = [inv_transform(F(P)) for P in ans[2]]
    101101    return ans
    102102