Ticket #10973: Trac10973.5.patch

File Trac10973.5.patch, 41.8 KB (added by Alyson Deines, 11 years ago)

Replaces previous patch, corrects Authors.

  • sage/schemes/elliptic_curves/all.py

    # HG changeset patch
    # User Author Justin C. Walker <justin@mac.com>
    # Date 1301015058 25200
    # Node ID 4d5f9318cce36f199d723d729d472484332a38e2
    # Parent  b2c0ed2e09a453751e4b2fe092667487f530eac3
    Trac 10973: Corrected Authors.
    
    diff -r b2c0ed2e09a4 -r 4d5f9318cce3 sage/schemes/elliptic_curves/all.py
    a b  
    4040from ell_curve_isogeny import EllipticCurveIsogeny, isogeny_codomain_from_kernel
    4141
    4242from heegner import heegner_points, heegner_point
     43
     44
  • new file sage/schemes/elliptic_curves/ell_int_points.py

    diff -r b2c0ed2e09a4 -r 4d5f9318cce3 sage/schemes/elliptic_curves/ell_int_points.py
    - +  
     1r"""
     2Integral Points of Elliptic Curves over Number Fields
     3
     4The following examples are from trac ticket #10152.  Previously Magma was finding more
     5integral points on these curves than Sage.  We resolved this issue.
     6
     7EXAMPLES::
     8
     9        sage: E = EllipticCurve('2082a1')
     10        sage: E.integral_points()
     11        [(-11 : 29 : 1), (-2 : 29 : 1), (4 : 11 : 1), (13 : 29 : 1)]
     12        sage: from sage.schemes.elliptic_curves.ell_int_points import integral_points
     13        sage: integral_points(E)
     14        [(-11 : -19 : 1), (-2 : 29 : 1), (4 : -16 : 1), (13 : -43 : 1), (507525709 : 11433453531221 : 1)]
     15   
     16    ::
     17   
     18        sage: E = EllipticCurve('6104b1')
     19        sage: E.integral_points()
     20        [(-41 : 266 : 1), (-27 : 294 : 1), (-13 : 266 : 1), (19 : 74 : 1), (22 : 49 : 1), (27 : 6 : 1),
     21        (29 : 14 : 1), (43 : 154 : 1), (53 : 266 : 1), (71 : 490 : 1), (414 : 8379 : 1), (1639 : 66346
     22        : 1), (1667 : 68054 : 1)]
     23        sage: from sage.schemes.elliptic_curves.ell_int_points import integral_points
     24        sage: integral_points(E)
     25        [(-41 : -266 : 1), (-27 : 294 : 1), (-13 : 266 : 1), (19 : 74 : 1), (22
     26        : -49 : 1), (27 : -6 : 1), (29 : -14 : 1), (43 : -154 : 1), (53 : 266 :
     27        1), (71 : 490 : 1), (414 : -8379 : 1), (1639 : 66346 : 1), (1667 :
     28        -68054 : 1), (23036693 : 110568192854 : 1)]
     29   
     30    ::
     31   
     32        sage: E = EllipticCurve('8470g1')
     33        sage: E.integral_points()
     34        [(-1 : 0 : 1), (0 : 6 : 1), (3 : 12 : 1), (10 : 33 : 1), (15 : 56 : 1), (24 : 110 : 1), (43 : 264
     35        : 1), (98 : 924 : 1), (395 : 7656 : 1)]
     36        sage: from sage.schemes.elliptic_curves.ell_int_points import integral_points
     37        sage: integral_points(E)
     38        [(-1 : 0 : 1), (0 : -7 : 1), (3 : 12 : 1), (10 : -44 : 1), (15 : 56 :
     39        1), (24 : 110 : 1), (43 : 264 : 1), (98 : -1023 : 1), (395 : -8052 : 1),
     40        (1681690 : 2179974753 : 1)]
     41   
     42    ::
     43   
     44        sage: E = EllipticCurve('8470g2')
     45        sage: E.integral_points()
     46        [(-14 : 17 : 1), (-12 : 33 : 1), (-7 : 38 : 1), (-1 : 22 : 1), (0 : 17 : 1), (13 : 8 : 1), (14
     47        : 17 : 1), (21 : 66 : 1), (33 : 158 : 1), (44 : 257 : 1), (63 : 458 : 1), (98 : 913 : 1), (175
     48        : 2222 : 1), (1533 : 59258 : 1), (1561 : 60896 : 1)]
     49        sage: from sage.schemes.elliptic_curves.ell_int_points import integral_points
     50        sage: integral_points(E)
     51        [(-14 : 17 : 1), (-12 : -22 : 1), (-7 : 38 : 1), (-1 : 22 : 1), (0 : -18
     52        : 1), (13 : -22 : 1), (14 : -32 : 1), (21 : 66 : 1), (33 : -192 : 1),
     53        (44 : 257 : 1), (63 : 458 : 1), (98 : -1012 : 1), (175 : -2398 : 1),
     54        (1533 : -60792 : 1), (1561 : 60896 : 1), (18888968 : -82103620687 : 1)]
     55       
     56    ::
     57   
     58        sage: from sage.schemes.elliptic_curves.ell_int_points import integral_points
     59        sage: len(integral_points(EllipticCurve('15a1'))) == len(EllipticCurve('15a1').integral_points())
     60        True
     61
     62
     63
     64
     65AUTHORS:
     66
     67- this file is based on work of Thotsaphon "Nook" Thongjunthug that was initially
     68  ported to Sage by Radoslav Kirov and Jackie Anderson.
     69
     70- Radoslav Kirov, Jackie Anderson (2010): first version
     71
     72- Justin Walker, Gagan Sekhon (2011): clean up
     73
     74- Alyson Deines, Jen Balakrishnan (2011): Documentation, clean up, fixing bugs so this works for all examples in the paper [SMART]_
     75
     76REFERENCE:
     77
     78.. [SMART] Smart, N. P. and Stephens, N. M., Integral Points on Elliptic Curves over Number Fields.
     79Math. Proc. Camb. Phil. Soc. (1997), 122, 9
     80
     81"""
     82
     83
     84##############################################################################
     85#       Copyright (C) 2011 William Stein <wstein@gmail.com>
     86#
     87#  Distributed under the terms of the GNU General Public License (GPL)
     88#
     89#    This code is distributed in the hope that it will be useful,
     90#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     91#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     92#    General Public License for more details.
     93#
     94#  The full text of the GPL is available at:
     95#
     96#                  http://www.gnu.org/licenses/
     97##############################################################################
     98
     99
     100from copy import copy
     101from sage.functions.all import sqrt
     102from sage.matrix.all import zero_matrix, MatrixSpace, matrix
     103from sage.modules.free_module_element import vector
     104from sage.misc.all import verbose, n, prod
     105from sage.rings.all import is_RealField, polygen, ZZ, RealField, ComplexField
     106from sage.rings.all import QQ, integer_ceil, integer_floor, PolynomialRing
     107from sage.schemes.elliptic_curves.ell_number_field import EllipticCurve
     108
     109
     110def abs_log_height(X, gcd_one = True, precision = None):
     111    r"""
     112    Computes the height of a point in a projective space over field `K`.
     113    It assumes the coordinates have gcd equal to 1.
     114    If not use gcd_one flag.
     115   
     116    INPUT:
     117   
     118    - ``X`` -- Point in projective space over a number field `K`
     119   
     120    - ``gcd_one`` -- (default: True) if false this throws in the
     121      places at the numerators in addition to the places at the denominator.
     122   
     123    - ``precision`` -- (default: None) bits of precision of the real and complex fields
     124   
     125    OUTPUT:
     126   
     127    The absolute logarithmic height of the point.
     128   
     129   
     130    EXAMPLES::
     131   
     132        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     133        sage: E = EllipticCurve('5077a')
     134        sage: P1,P2,P3 = E.gens()
     135        sage: ellpts.abs_log_height(list(P2))
     136        1.09861228866811
     137       
     138    ::
     139   
     140        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     141        sage: K.<a> = NumberField(x^2-x-1)
     142        sage: F = EllipticCurve(K,[0,-a,1,-a-1,2*a+1])
     143        sage: P1,P2 = F.gens()
     144        sage: P2
     145        (-3/4*a + 1/4 : -5/4*a - 5/8 : 1)
     146        sage: ellpts.abs_log_height(list(P2))
     147        2.56625746464637
     148
     149   
     150    """
     151    assert isinstance(X,list)
     152    K = X[0].parent()
     153    if precision is None:
     154        RR = RealField()
     155        CC = ComplexField()
     156    else:
     157        RR = RealField(precision)
     158        CC = ComplexField(precision)
     159    places = set([])
     160    if K == QQ:
     161        embs = K.embeddings(RR)
     162        Xideal = X
     163    else:
     164        embs = K.places(precision)
     165        # skipping zero as it currently over K breaks Sage
     166        Xideal = [K.ideal(x) for x in X if not x.is_zero()]
     167    for x in Xideal:
     168        places = places.union(x.denominator().prime_factors())
     169        if not gcd_one:
     170            places = places.union(x.numerator().prime_factors())
     171    if K == QQ:
     172        non_arch = sum([max([RR(P)**(-x.valuation(P)) for x in X]).log() for P in places])
     173    else:
     174        non_arch = sum([P.residue_class_degree() *
     175                        P.absolute_ramification_index() *
     176                        max([x.abs_non_arch(P, precision) for x in X]).log() for P in places])
     177    arch = 0
     178    r,s = K.signature()
     179    for i,f in enumerate(embs):
     180        if i<r:
     181            arch += max([f(x).abs() for x in X]).log()
     182        else:
     183            arch += max([f(x).abs()**2 for x in X]).log()
     184    return (arch+non_arch)/K.degree()
     185   
     186def _compute_c6(E,emb):
     187    r"""
     188    Computes the `c_6` invariant from [SMART]_
     189   
     190    EXAMPLES::
     191   
     192        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     193        sage: K.<a> = NumberField(x^2+5)
     194        sage: E = EllipticCurve(K,[-112,400])
     195        sage: embs = K.embeddings(CC)
     196        sage: ellpts._compute_c6(E,embs[0])
     197        24.0994429807464
     198
     199    """
     200    F = emb.codomain()
     201    if is_RealField(F):
     202        x = polygen(ComplexField(F.prec()))
     203    else:
     204        x = polygen(F)
     205    #f = x**3-27*emb(E.c4())*x-54*emb(E.c6())
     206    f = x**3-emb(E.c4()/48)*x-emb(E.c6()/864)
     207    R = f.roots(multiplicities = False)
     208    m = max([r.abs() for r in R])
     209    return 2*m
     210
     211def _compute_c8(L):
     212    r"""
     213    Computes the `c_8` invariant from [SMART]_
     214   
     215    Original code transformed the lattice generators.
     216    Here we assume they are of standard form.
     217   
     218    INPUT:
     219   
     220    - `L` -- a basis for the period lattice of an elliptic curve over a number field
     221      via a given embedding
     222   
     223    EXAMPLES::
     224   
     225        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     226        sage: K.<a> = NumberField(x^2+5)
     227        sage: E = EllipticCurve(K,[-112,400])
     228        sage: embs = K.embeddings(CC)
     229        sage: Periods = E.period_lattice(embs[0]).normalised_basis();
     230        sage: ellpts._compute_c8(Periods)
     231        1.27486778253862
     232   
     233    """
     234    CC=ComplexField()
     235    w1, w2 = L
     236    m = max(CC(w1).abs(), CC(w2).abs(), CC(w1+w2).abs())
     237    return m
     238
     239def _c3(E,L):
     240    r"""
     241    Computes the `c_3` invariant of [SMART]_ which is the least eigenvalue of the
     242    height pairing matrix of the Mordell-Weil basis.
     243   
     244    INPUT:
     245   
     246    - `E` -- an elliptic curve over a number field
     247   
     248    - `L` -- a list of points of `E` which generate the Mordell-Weil group
     249   
     250    EXAMPLES::
     251   
     252        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     253        sage: K.<a> = NumberField(x^2+5)
     254        sage: E = EllipticCurve(K,[-112,400])
     255        sage: ellpts._c3(E,[E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))])
     256        0.366347735724767
     257
     258   
     259    """
     260    import warnings
     261    with warnings.catch_warnings():
     262       warnings.simplefilter("ignore")
     263       return min(map(abs,E.height_pairing_matrix(L).eigenvalues()))
     264
     265def _h_E(E):
     266    r"""
     267    Computes the height of the ellpitc curve `E`.
     268       
     269    INPUT:
     270   
     271    -`E` -- an elliptic curve
     272   
     273    EXAMPLES::
     274   
     275        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     276        sage: K.<a> = NumberField(x^2+5)
     277        sage: E = EllipticCurve(K,[-112,400])
     278        sage: ellpts._h_E(E)
     279        17.4513334798896
     280   
     281    """
     282    K = E.base_field()
     283    j = E.j_invariant()
     284    c4, c6 = E.c_invariants()
     285    g2, g3 = c4/12, c6/216
     286    return max(abs_log_height([K(1), g2, g3]), abs_log_height([K(1), j]))
     287
     288def _h_m(E, P, ElogEmbedP, D7):
     289    r"""
     290    Computes the list of modified height of a point `P` on `E(K)` given a list of embeddings
     291   
     292    INPUT:
     293   
     294    - `E` -- an elliptic curve
     295   
     296    - `P` -- a point on `E`
     297   
     298    - `ElogEmbedP` -- elliptic logarithm of `P` in some embedding
     299   
     300    - `D7` -- constant `d_7`
     301   
     302    EXAMPLES::
     303   
     304        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     305        sage: K.<a> = NumberField(x^2+5)
     306        sage: embs = K.embeddings(CC)
     307        sage: E = EllipticCurve(K,[-112,400])
     308        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     309        sage: Elog = [ P.elliptic_logarithm(embs[0], precision = 300) for P in L]
     310        sage: ellpts._h_m(E, L[0], Elog[0], 3.28)
     311        17.4513334798896
     312   
     313 
     314    """
     315    K = E.base_field()
     316    M1 =  max([P.height(), _h_E(E), D7/K.degree()*abs((ElogEmbedP).log())**2])
     317    M2 =  max([P.height(), _h_E(E), D7/K.degree()*abs(ElogEmbedP)**2])
     318    #assert M1==M2
     319    return M2
     320   
     321def _Extra_h_m(E, Periods, D7):
     322    r"""
     323    Computes two extra `h_m`'s given periods.
     324   
     325    INPUT:
     326   
     327    - `E` -- elliptic curve
     328   
     329    - `Periods` -- list of two periods of the fundamental parallelogram
     330   
     331    - `D7` -- constant `d_7`
     332   
     333    EXAMPLES::
     334   
     335        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     336        sage: K.<a> = NumberField(x^2+5)
     337        sage: embs = K.embeddings(CC)
     338        sage: E = EllipticCurve(K,[-112,400])
     339        sage: Periods = E.period_lattice(embs[0]).normalised_basis()
     340        sage: ellpts._Extra_h_m(E, Periods, 90.3)
     341        [48.6392854292010, 24.7424615832146]
     342       
     343    """
     344
     345    D = E.base_field().degree()
     346    h = _h_E(E)
     347    return map(lambda x: max([0, h, D7/D*abs(x)**2]), Periods)
     348
     349def _d8(E, L, Elog, Periods, D7):
     350    r"""
     351    INPUT:
     352   
     353    - `E` -- elliptic curve
     354   
     355    - `L` -- a list of points in `E(K)` (e.g. a basis for the Mordell-Weil group)
     356   
     357    - `Elog` -- a sequence of precomputed elliptic logs of each point in `L`
     358   
     359    - `D7` -- constant `d_7`
     360   
     361    EXAMPLES::
     362     
     363        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     364        sage: K.<a> = NumberField(x^2+5)
     365        sage: embs = K.embeddings(CC)
     366        sage: E = EllipticCurve(K,[-112,400])
     367        sage: Periods = E.period_lattice(embs[0]).normalised_basis()
     368        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     369        sage: Elog = [ P.elliptic_logarithm(embs[0], precision = 300) for P in L]
     370        sage: ellpts._d8(E, L, Elog, Periods, 90.3)
     371        47.4376426807629
     372
     373    """
     374    RR=RealField()
     375    C = [RR(1).exp() * _h_E(E)]
     376    D = E.base_field().degree()
     377    for i in range(len(L)):
     378        C.append(_h_m(E, L[i], Elog[i], D7) / D)
     379    C += [t / D for t in _Extra_h_m(E, Periods, D7)]
     380    return max(C);
     381
     382def _d9(E, L, Elog, Periods, D7):
     383    r"""
     384    INPUT:
     385   
     386    - `E` -- elliptic curve
     387   
     388    - `L` -- a list of points in `E(K)` (e.g. a basis for the Mordell-Weil group)
     389   
     390    - `Elog` -- a sequence of precomputed elliptic logs of each point in `L`
     391   
     392    - `D7` -- constant `d_7`
     393   
     394    EXAMPLES::
     395     
     396        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     397        sage: K.<a> = NumberField(x^2+5)
     398        sage: embs = K.embeddings(CC)
     399        sage: E = EllipticCurve(K,[-112,400])
     400        sage: Periods = E.period_lattice(embs[0]).normalised_basis()
     401        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     402        sage: Elog = [ P.elliptic_logarithm(embs[0], precision = 300) for P in L]
     403        sage: ellpts._d9(E, L, Elog, Periods, 90.3)
     404        2.71828182845904
     405
     406    """
     407    RR=RealField()
     408    D = E.base_field().degree()
     409    C = []
     410    for i in range(len(L)):
     411        tmp = RR(1.0).exp() * sqrt(D * _h_m(E, L[i], Elog[i], D7) / D7)
     412        C.append( tmp / abs(Elog[i]))
     413    Ehm = _Extra_h_m(E, Periods, D7)
     414    C += [RR(1).exp() * sqrt(D*Ehm[i]/D7) / abs(Periods[i]) for i in [0,1]]
     415    verbose("d9: C = %s"%(C,))
     416    return min(C);
     417
     418def _d10(E, L, Elog, Periods, D7):
     419    r"""
     420    INPUT:
     421   
     422    - `E` -- elliptic curve
     423   
     424    - `L` -- a list of points in `E(K)` (e.g. a basis for the Mordell-Weil group)
     425   
     426    - `Elog` -- a sequence of precomputed elliptic logs of each point in `L`
     427   
     428    - `D7` -- constant `d_7`
     429   
     430    EXAMPLES::
     431     
     432        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     433        sage: K.<a> = NumberField(x^2+5)
     434        sage: embs = K.embeddings(CC)
     435        sage: E = EllipticCurve(K,[-112,400])
     436        sage: Periods = E.period_lattice(embs[0]).normalised_basis()
     437        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     438        sage: Elog = [ P.elliptic_logarithm(embs[0], precision = 300) for P in L]
     439        sage: ellpts._d10(E, L, Elog, Periods, 90.3)
     440        1.19716657228519e226
     441   
     442    """
     443    RR=RealField()
     444    D = E.base_field().degree()
     445    n = len(L)+2
     446    scalar = 2 * 10**(8 + 7*n) * (2/RR(1).exp())**(2*n**2)
     447    scalar *= (n+1)**(4*n**2 + 10*n) * D**(2*n + 2)
     448    scalar *= (RR(_d9(E, L, Elog, Periods, D7)).log())**(-2*n-1)
     449    for i in range(len(L)):
     450        scalar *= _h_m(E, L[i], Elog[i], D7)
     451    scalar *= prod(_Extra_h_m(E, Periods, D7))   
     452    return scalar
     453
     454def _RHS(D, r, C9, C10, D9, D10, h, Q, expTors):
     455    r"""
     456    Computes the right hand side of the principal inequality.
     457   
     458    INPUT:
     459   
     460    - `D` -- degree of field extension
     461   
     462    - `r` -- Mordell-Weil rank
     463   
     464    - `C9` -- `c_9` invariant from [SMART]_
     465   
     466    - `C19` -- `c_{10}` invariant from [SMART]_
     467   
     468    - `D9` -- `D_9` invariant
     469   
     470    - `D10` -- `d_{10}` invariant
     471   
     472    - `h` -- `h_E(E)` where `E` is an elliptic curve
     473   
     474    - `Q` -- initial bound for the coefficients of `P_i`'s, where
     475      `P_i`'s are in the Mordell-Weil basis
     476       
     477    - `expTors` -- the exponent of the torsion subgroup of `E`
     478   
     479    EXAMPLES: 
     480   
     481        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     482        sage: K.<a> = NumberField(x^2+5)
     483        sage: E = EllipticCurve(K,[-112,400])
     484        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     485        sage: C9 =  3425.58431073226
     486        sage: C10 = 0.183173867862383
     487        sage: Q0 =  5.12358476153997
     488        sage: D8 =  47.4376426807629
     489        sage: D9 =  6.19404412950310
     490        sage: D10 =  2.39513899842427e221
     491        sage: h =  17.4513334798896
     492        sage: expTors = 1
     493        sage: ellpts._RHS(K.degree(), len(L), C9, C10, D9, D10, h, 1000000000000000000000, expTors)
     494        3.02137037238302e233
     495   
     496    """
     497    RR=RealField()
     498    bound = (RR(RR(Q*r*expTors).log()).log() + h + RR(D*D9).log())**(r+3)
     499    bound *= D10*(RR(Q*r*expTors).log() + RR(D*D9).log())
     500    bound += RR(C9*expTors).log()
     501    bound /= C10
     502    return bound
     503
     504def _InitialQ(D, r, Q0, C9, C10, D8, D9, D10, h, expTors):
     505    r"""
     506    Computes the initial bound on `Q = max_{1 \leq i \leq r}(|q_i|)`.
     507   
     508    INPUT:
     509   
     510    - `D` -- degree of field extension
     511   
     512    - `r` -- Mordell-Weil rank
     513   
     514    - `Q0` -- the `K_0` constant in [SMART]_
     515   
     516    - `C9` -- `c_9` invariant from [SMART]_
     517   
     518    - `C10` -- `c_{10}` invariant from [SMART]_
     519   
     520    - `D9` -- `D_9` invariant
     521   
     522    - `D10` -- `d_{10}` invariant
     523   
     524    - `h` -- `h_E(E)` where `E` is an elliptic curve
     525       
     526    - `expTors` -- the exponent of the torsion subgroup of `E`
     527   
     528    EXAMPLES::
     529   
     530        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     531        sage: K.<a> = NumberField(x^2+5)
     532        sage: E = EllipticCurve(K,[-112,400])
     533        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     534        sage: C9 =  3425.58431073226
     535        sage: C10 = 0.183173867862383
     536        sage: Q0 =  5.12358476153997
     537        sage: D8 =  47.4376426807629
     538        sage: D9 =  6.19404412950310
     539        sage: D10 =  2.39513899842427e221
     540        sage: h =  17.4513334798896
     541        sage: expTors = 1
     542        sage: ellpts._InitialQ(K.degree(), len(L), Q0, C9, C10, D8, D9, D10, h, expTors)
     543        118
     544
     545    """
     546
     547    RR=RealField()
     548    minQ = max(Q0, RR(D8).exp())
     549    Q = minQ + 1
     550    x = integer_ceil(Q.log(10)) # x = log_10(Q)
     551    verbose("x: %s, %s"%(type(Q), type(x)))
     552    exp_OK = 0   # the exponent that satisfies P.I.
     553    exp_fail = 0 # the exponent that fails P.I.
     554    verbose("Looping on %s < RHS(%s, %s, %s, %s %s, %s, %s, %s, %s"%( 10**(2*x), D, r, C9, C10, D9, D10, h, 10**x, expTors))
     555    while 10**(2*x) < _RHS(D, r, C9, C10, D9, D10, h, 10**x, expTors):
     556        exp_OK = x # Principal Inequality satisfied
     557        x *= 2     # double x, and retry
     558    exp_fail = x # x that fails the Principal Inequality
     559   
     560   
     561    # So now x = log_10(Q) must lie between exp_OK and exp_fail
     562    # Refine x further using "binary search"
     563    while True:
     564        x = integer_floor((exp_OK + exp_fail)/2)
     565        if 10**(2*x) >= _RHS(D, r, C9, C10, D9, D10, h, 10**x, expTors):
     566            exp_fail = x
     567        else:
     568            exp_OK = x
     569        if (exp_fail - exp_OK) <= 1:
     570            break
     571    return exp_fail # over-estimate
     572
     573def _Faltings_height(E):
     574    r"""
     575    Faltings's height of the elliptic curve `E`.
     576    This is double the formula in Silverman Math Comp 1990 page 725.
     577   
     578    EXAMPLE::
     579   
     580        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     581        sage: K.<a> = NumberField(x^2+5)
     582        sage: E = EllipticCurve(K,[-112,400])
     583        sage: ellpts._Faltings_height(E)
     584        4.29484994110149
     585
     586    """
     587    RR=RealField()
     588    K = E.base_field()
     589    c = RR(2).log()
     590    if E.b2().is_zero():
     591        c = 0
     592    h1 = abs_log_height([K(E.discriminant()), K(1)])/6
     593    h2 = K(E.j_invariant()).global_height_arch()/6
     594    h3 = K(E.b2()/12).global_height_arch()
     595    return n(h1 + h2/2 + h3/2 + c)
     596
     597def _ReducedQ(E, f, LGen, Elog, C9, C10, Periods, expTors, initQ):
     598    r"""
     599    Internal reduction function which reduces the bound on `Q`.
     600   
     601    INPUT:
     602   
     603    - `E` -- elliptic curve over `K`
     604   
     605    - `f` -- embedding of `K` into `\mathbb{C}`
     606   
     607    - `LGen` -- a list of points in `E(K)` (e.g. a basis for the Mordell-Weil group)
     608   
     609    - `Elog` -- a sequence of precomputed elliptic logs of each point in `L`
     610
     611    - `C9` -- `c_9` invariant from [SMART]_
     612   
     613    - `C10` -- `c_{10}` invariant from [SMART]_
     614   
     615    - `Periods` -- list of two periods of the fundamental parallelogram
     616   
     617    - `expTors` -- the exponent of the torsion subgroup of `E`
     618     
     619    - `initQ` -- inital guess for `Q` which is then reduced by LLL
     620     
     621    EXAMPLES::
     622     
     623        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     624        sage: K.<a> = NumberField(x^2+5)
     625        sage: E = EllipticCurve(K,[-112,400])
     626        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     627        sage: embs = K.embeddings(CC)
     628        sage: Elog = [ P.elliptic_logarithm(embs[0], precision = 300) for P in L]
     629        sage: Periods = Periods = E.period_lattice(embs[0]).normalised_basis()
     630        sage: C9 =  3425.58431073226
     631        sage: C10 = 0.183173867862383
     632        sage: expTors = 1   
     633        sage: initQ = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     634        sage: ellpts._ReducedQ(E, embs[0], L, Elog, C9, C10, Periods, expTors, initQ)
     635        13
     636   
     637    """
     638
     639    RR=RealField()
     640    w1, w2 = Periods
     641    r = len(LGen)
     642    newQ = initQ
     643    # Repeat LLL reduction until no further reduction is possible
     644    while True:
     645        Q = newQ
     646        S = r*(Q**2)*(expTors**2)
     647        T = 3*r*Q*expTors/sqrt(2.0)
     648        # Create the basis matrix
     649        C = 1
     650        while True:
     651            C *= Q**integer_ceil((r+2)/2)
     652            precbits = int(RR(C).log(2)+10)*4
     653            L = copy(zero_matrix(ZZ, r+2))
     654            # Elliptic logarithm should have precision "suitable to" C
     655            # e.g. If C = 10**100, then Re(Elog[i]) should be computed
     656            # correctly to at least 100 decimal places
     657            if precbits > Elog[0].prec():
     658                verbose( "Need higher precision, recompute elliptic logarithm ...")
     659                # Re-compute elliptic logarithm to the right precision
     660                verbose( "precision in bits %i" % precbits)
     661                Elog = [ P.elliptic_logarithm(f, precision = precbits) for P in LGen]
     662                verbose( "Elliptic logarithm recomputed")
     663                w1, w2 = E.period_lattice(f).normalised_basis( prec = precbits)
     664            # Assign all non-zero entries
     665            for i in range(r):
     666                L[i, i] = 1
     667                L[r, i]   = (C*Elog[i].real_part()).trunc()
     668                L[r+1, i] = (C*Elog[i].imag_part()).trunc()
     669            L[r , r ]   = (C*w1.real_part()).trunc()
     670            L[r , r+1 ] = (C*w2.real_part()).trunc()
     671            L[r+1, r]   = (C*w1.imag_part()).trunc()
     672            L[r+1, r+1] = (C*w2.imag_part()).trunc()
     673            # LLL reduction and constants
     674            L = L.transpose()
     675            L = L.LLL()
     676            b1 = L[0] # 1st row of reduced basis
     677            #Norm(b1) = square of Euclidean norm
     678            normb1 = sum([i**2 for i in b1])
     679            lhs = RR(2)**(-r-1)*normb1 - S
     680            if (lhs >= 0) and (sqrt(lhs) > T):
     681                break
     682        newQ = ( RR(C*C9*expTors).log() - RR(sqrt(lhs) - T).log() ) / C10
     683        newQ = integer_floor(sqrt(newQ))
     684        verbose( "After reduction, Q <= %f" % newQ)
     685        if ((Q - newQ) <= 1) or (newQ <= 1):
     686            break
     687    return newQ
     688
     689
     690def _cyc_iter(id, gens, mult, both_signs = False):
     691    r"""
     692    Cyclic group iterator
     693   
     694    INPUT:
     695   
     696    - `id` -- identity element
     697   
     698    - `gens` -- generators of the group
     699   
     700    - `mult` -- orders of the generators
     701   
     702    - ``both_signs`` --(Default: False) whether to return all elements or one per each {element, inverse} pair
     703   
     704    OUTPUT:
     705   
     706    Returns all elements of the cyclic group, remembering all intermediate steps
     707   
     708    EXAMPLE::
     709   
     710        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     711        sage: E = EllipticCurve('57b')
     712        sage: ord = [P.order() for P in E.torsion_points()]
     713        sage: P_list = [i for i in ellpts._cyc_iter(E(0),E.torsion_points(),ord)]
     714        sage: P_list
     715        [((0 : 1 : 0), [0, 0, 0, 0]), ((7/4 : -11/8 : 1), [0, 0, 0, 1]), ((1 :
     716        -1 : 1), [0, 0, 1, 0]), ((-3 : 1 : 1), [0, 0, 1, 1]), ((-3 : 1 : 1), [1,
     717        0, 0, 0]), ((1 : -1 : 1), [1, 0, 0, 1]), ((7/4 : -11/8 : 1), [1, 0, 1,
     718        0]), ((0 : 1 : 0), [1, 0, 1, 1])]
     719   
     720   
     721    """
     722    if len(gens) == 0:
     723        yield id,[]
     724    else:
     725        P = gens[0]
     726        cur = id
     727        if both_signs:
     728            ran = xrange(mult[0])
     729        else:
     730            ran = xrange(mult[0]/2 + 1)
     731        for k in ran:
     732            for rest, coefs in _cyc_iter(id, gens[1:], mult[1:], both_signs or k != 0):
     733                yield cur + rest, [k] + coefs
     734            cur += P
     735
     736#generates elements of form a_1G_1 + ... + a_nG_n
     737#where |a_i| <= bound and the first non-zero coefficient is positive
     738def _L_points_iter(id, gens, bound, all_zero = True):
     739    r"""
     740    Generates elements of form `a_1G_1 + ... + a_nG_n`
     741    where `|a_i| \leq` bound and the first non-zero coefficient is positive
     742   
     743    INPUT:
     744   
     745    - ``id`` -- identity element
     746   
     747    - ``gens`` -- a list of generators, `G_1,...,G_n`
     748   
     749    - ``bound`` -- a bound on the absolute value of the `a_i`'s, the coefficients of the elements in terms
     750      of the generators.
     751   
     752    - ``all_zero`` --(default: True)
     753   
     754    OUTPUT:
     755   
     756    An iterator that generates elements of the form `a_1G_1 + ... + a_nG_n`
     757   
     758    EXAMPLES::
     759   
     760        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     761        sage: K.<a> = NumberField(x^2+2)
     762        sage: E = EllipticCurve(K,[-16,16])
     763        sage: P_list = [[P,Pcoeff] for P,Pcoeff in ellpts._L_points_iter(E(0),[E((0,4)),E((2,-2*a))],24)]
     764        sage: P_list[0:5]
     765        [[(0 : 1 : 0), [0, 0]], [(2 : -2*a : 1), [0, 1]], [(-9/2 : -5/4*a : 1),
     766        [0, 2]], [(418/169 : 4514/2197*a : 1), [0, 3]], [(-30241/200 :
     767        5257039/4000*a : 1), [0, 4]]]
     768       
     769   
     770    """
     771    if len(gens) == 0:
     772        yield id, []
     773    else:
     774        P = gens[0]
     775        cur = id
     776        for k in xrange(bound+1):
     777            for rest, coefs in _L_points_iter(id, gens[1:], bound, all_zero = (all_zero and k == 0)):
     778                yield cur + rest, [k] + coefs 
     779                if k!=0 and not all_zero:
     780                   yield -cur + rest, [-k] + coefs
     781            cur += P
     782
     783def _integral_points_with_Q(E, L, Q):
     784    r"""
     785    Given an elliptic curve `E` over a number field, its Mordell-Weil basis L,and a positive integer Q,
     786    return the sequence of all integral points modulo `[-1]` of the form `P = q_1*L[1] + ... + q_r*L[r] + T`
     787    with some torsion point `T` and `|q_i| \leq Q`.     
     788    INPUT:
     789   
     790    - ``E`` -- an elliptic curve
     791   
     792    - ``L`` -- a basis for the Mordel-Weil group of `E`
     793   
     794    - ``Q`` -- positive integer, maximum for the absolute bound on all coefficients in the linear combination of points in `L`
     795   
     796        OUTPUT:
     797   
     798    Returns the sequence of all integral points modulo `[-1]`
     799   
     800    EXAMPLE::
     801   
     802        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     803        sage: K.<a> = NumberField(x^2-x-1)
     804        sage: E = EllipticCurve(K,[2-a,-a-1,1-a,a,1])
     805        sage: L = E.gens()
     806        sage: ellpts._integral_points_with_Q(E,L,25)
     807        [(a : 1 : 1)]
     808       
     809    """
     810    CC=ComplexField()
     811    if L == []:
     812        try:
     813            L = E.gens()
     814        except ValueError:
     815            raise ValueError, "Generators of the Mordel-Weil group must be supplied."
     816    Tors = E.torsion_subgroup()
     817    expTors = Tors.exponent()
     818    Tpoints = E.torsion_points()
     819    id = E([0,1,0])
     820    verbose( "Generators = %s" % L)
     821    PtsList = []
     822     
     823    verbose( "Exact arithmetic")
     824    for P, Pcoeff in _L_points_iter(id, L, Q):
     825            for T in Tpoints:
     826                R = P+T
     827                if R[0].is_integral() and R[1].is_integral() and R != id:
     828                    if R not in PtsList and -R not in PtsList:
     829                        PtsList.append(R)
     830    verbose( "*"*45)
     831    return PtsList
     832   
     833
     834def _calculate_Q(E,L):
     835    r"""
     836    This calculates `Q`, one of the bounds in [SMART]_.  `Q` is a positive integer,
     837    maximum for the absolute bound on all coefficients in the linear combination of points in `L`
     838   
     839    INPUT:
     840   
     841    - ``E`` -- Elliptic Curve
     842   
     843    - ``L`` -- a basis for the Mordel-Weil group of `E`
     844     
     845   
     846    OUTPUT:
     847    A positive integer, maximum for the absolute bound on all coefficients in the linear combination of points in `L`
     848   
     849    EXAMPLE::
     850   
     851        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     852        sage: K.<a> = NumberField(x^2+5)
     853        sage: E = EllipticCurve(K,[-112,400])
     854        sage: L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))]
     855        sage: ellpts._calculate_Q(E,L)
     856        13
     857    """
     858
     859    from math import pi as Rpi
     860    CC=ComplexField()
     861   
     862    if len(L) == 0:
     863        return 0
     864    K = E.base_ring()
     865    expTors = E.torsion_subgroup().exponent()
     866    r, s = K.signature()
     867    RR = RealField()
     868    pi = RR(Rpi)
     869    b2 = E.b_invariants()[0]
     870    # Global constants (independent to the embedding of E)
     871    gl_con = {}
     872    #C2 = E.silverman_height_bounds[1] matches with [SMART]
     873    #C2 = -E.silverman_height_bound[0] matches with Nook's implementation in Magma
     874    #both return correct sets of integral points . . .
     875    gl_con['c2'] = C2 = -E.silverman_height_bounds()[0]
     876    gl_con['c3'] = C3 = _c3(E,L)
     877    gl_con['h_E'] = h = _h_E(E)
     878    verbose( "Global constants")
     879    for name, val in gl_con.iteritems():
     880        verbose( '%s = %s'%(name, val))
     881    verbose( "-"*45)
     882    Q = []
     883    # Find the most reduced bound on each embedding of E
     884    # Sage bug, QQ.places() is not implemented
     885    # and K.embeddings gives each complex places twice
     886    if K is QQ:
     887        infplaces = K.embeddings(CC) 
     888    else:
     889        infplaces = K.places()
     890    for i, f in enumerate(infplaces):
     891        # Bug in P.complex_logarithm(QQ.embeddings(CC)[0])
     892        if K is QQ:
     893            emb = None
     894        else:
     895            emb = f
     896        if i < r:
     897            nv = 1
     898            verbose( "Real embedding #%i" % i )
     899        else:
     900            nv = 2
     901            verbose( "Complex embedding #%i" % (i-r))
     902        # Create complex embedding of E
     903        # Embedding of all points in Mordell-Weil basis
     904        # Find complex elliptic logarithm of each embedded point
     905        precbits = integer_floor(100*RR(10).log(2))
     906        Elog = [P.elliptic_logarithm(emb, precision = precbits) for P in L]
     907        Periods = E.period_lattice(emb).normalised_basis();
     908        # Local constants (depending on embedding)
     909        # C9, C10 are used for the upper bound on the linear form in logarithm
     910        loc_con = {}
     911        loc_con['c4'] = C4 = C3 * K.degree() / RR(nv*(r+s))
     912        loc_con['c5'] = C5 = C2 * K.degree() / RR(nv*(r+s))
     913        loc_con['c6'] = C6 = _compute_c6(E,f)
     914        loc_con['delta'] = delta = 1 + (nv-1)*pi
     915        loc_con['c8'] = C8 = _compute_c8(Periods)
     916        loc_con['c7'] = C7 = RR(8)*(delta**2) + (C8**2)*abs(f(b2))/RR(12)
     917        #C9 = sqrt(C7)*RR(C5/2).exp() is a tigher bound, but [SMART] only uses
     918        #C9 = C7*RR(C5/2).exp() . . .
     919        #additionally, we could never get our C9 values to match with [SMART]
     920        loc_con['c9'] = C9  = C7*RR(C5/2).exp()
     921        #C10 was often correct to 3 or so digits
     922        loc_con['c10'] = C10 = C4/2
     923        #Q0 (K0 in [SMART]) is often correct to 1 or 2 digits
     924        #These descrepancies don't seem to matter . . .
     925        loc_con['Q0'] = Q0 = sqrt( ( RR(C6+abs(f(b2))/12).log() + C5) / C4 )
     926        # Constants for David's lower bound on the linear form in logarithm
     927        # Magma and Sage output periods in different order, need to swap w1 and w2
     928        w2, w1 = Periods # N.B. periods are already in "standard" form
     929        loc_con['d7'] = D7 = 3*pi / ((abs(w2)**2) * (w2/w1).imag_part())
     930        loc_con['d8'] = D8 = _d8(E, L, Elog, Periods, D7)
     931        loc_con['d9'] = D9 = _d9(E, L, Elog, Periods, D7)
     932        loc_con['d10'] = D10 = _d10(E, L, Elog, Periods, D7)
     933        for name, val in loc_con.iteritems():
     934            verbose( "{0} = {1}".format(name, val))
     935        # Find the reduced bound for the coefficients in the linear logarithmic form
     936        loginitQ = _InitialQ(K.degree(), len(L), Q0, C9, C10, D8, D9, D10, h, expTors)
     937        verbose( "Initial Q <= 10^%f" % loginitQ)
     938        initQ = 10**loginitQ
     939        Q.append(_ReducedQ(E, emb, L, Elog, C9, C10, Periods, expTors, initQ))
     940        verbose( "-"*45)
     941    Q = max(Q)
     942    verbose( "Maximum absolute bound on coefficients = %i"% Q)
     943    return Q
     944
     945def integral_points(self, L=None, both_signs = False):
     946    r"""
     947    Given an elliptic curve over a number field and its Mordell-Weil basis, return the sequence of all integral points modulo [-1]. 
     948    both_signs = True gives the set of all integral points.
     949   
     950   
     951    INPUT:
     952       
     953    - ``L`` -- (default: `L` = self.gens()) a basis for the Mordel-Weil group of self
     954   
     955    - ``both_signs`` -- (default: False) This gives the entire set of points, `P` and `-P` for each integral point.  If set to True,
     956      this just gives the `P` and not `-P`.
     957                 
     958                 
     959    OUTPUT:
     960   
     961    Returns the sequence of all integral points modulo `[-1]`
     962   
     963    .. note::
     964
     965        The complexity increases exponentially in the rank of curve
     966        E. The computation time (but not the output!) depends on
     967        the Mordell-Weil basis. If mw_base is given but is not a
     968        basis for the Mordell-Weil group (modulo torsion), integral
     969        points which are not in the subgroup generated by the given
     970        points will almost certainly not be listed.
     971       
     972        All examples from [SMART]_ have been tested and return the correct integral points. 
     973
     974   
     975    EXAMPLES::
     976   
     977        sage: import sage.schemes.elliptic_curves.ell_int_points as ellpts
     978        sage: E = EllipticCurve('5077a')
     979        sage: ellpts.integral_points(E,E.gens(),both_signs = True)
     980        [(-3 : -1 : 1), (-3 : 0 : 1), (-2 : -4 : 1), (-2 : 3 : 1), (-1 : -4 : 1), (-1 : 3 : 1), (0 : -3 : 1),
     981        (0 : 2 : 1), (1 : -1 : 1), (1 : 0 : 1), (2 : -1 : 1), (2 : 0 : 1), (3 : -4 : 1), (3 : 3 : 1), (4 :
     982        -7 : 1), (4 : 6 : 1), (8 : -22 : 1), (8 : 21 : 1), (11 : -36 : 1), (11 : 35 : 1), (14 : -52 : 1),
     983        (14 : 51 : 1), (21 : -96 : 1), (21 : 95 : 1), (37 : -225 : 1), (37 : 224 : 1), (52 : -375 : 1), (52
     984        : 374 : 1), (93 : -897 : 1), (93 : 896 : 1), (342 : -6325 : 1), (342 : 6324 : 1), (406 : -8181 : 1),
     985        (406 : 8180 : 1), (816 : -23310 : 1), (816 : 23309 : 1)]
     986       
     987    Example 1 from [SMART]_::
     988   
     989        sage: K.<a> = NumberField(x^2+5)
     990        sage: E = EllipticCurve(K,[-112,400])
     991        sage: E.integral_points(L = [E((4,-4)),E((0,-20)),E((-4,-28)),E((-89/5,-637*a/25))])  # long time
     992        [(8 : 4 : 1), (148 : 1796 : 1), (1 : 17 : 1), (84 : -764 : 1), (1368 : -50596 : 1), (9 : -11 : 1), (16
     993        : 52 : 1), (12 : -28 : 1), (32 : 172 : 1), (-8 : 28 : 1), (-12 : 4 : 1), (208 : 2996 : 1), (25 : -115 :
     994        1), (44 : 284 : 1), (56 : -412 : 1), (-7 : -29 : 1), (372 : -7172 : 1), (1624 : -65444 : 1), (3264 : 186476
     995        : 1), (-4 : -28 : 1), (0 : -20 : 1), (4 : -4 : 1)]
     996
     997       
     998    Example 2 from [SMART]_::
     999   
     1000        sage: K.<a> = NumberField(x^2+2)
     1001        sage: E = EllipticCurve(K,[-16,16])
     1002        sage: E.integral_points([E((0,4)),E((2,-2*a))])
     1003        [(4*a : 8*a - 12 : 1), (-4*a : -8*a - 12 : 1), (4 : 4 : 1), (4*a - 4 : 20 : 1), (-4*a - 4 : 20 : 1), (-4 : -4
     1004        : 1), (-40*a + 60 : -480*a + 316 : 1), (40*a + 60 : 480*a + 316 : 1), (8 : -20 : 1), (1 : -1 : 1), (-4*a - 10
     1005        : -18*a + 28 : 1), (4*a - 10 : 18*a + 28 : 1), (24 : 116 : 1), (2 : -2*a : 1), (0 : 4 : 1)]
     1006
     1007    Example 3 from [SMART]_, also an example where we can not compute generators using the simon two descent::
     1008     
     1009        sage: K.<a> = NumberField(x^3+3*x-1)
     1010        sage: E = EllipticCurve(K,[3,0])
     1011        sage: E.integral_points(L = [E((1,2)),E((a,1))])
     1012        [(3*a^2 + 9 : -9*a^2 - 3*a - 27 : 1), (3 : -6 : 1), (6*a^2 + 2*a + 17 : -24*a^2 - 6*a - 74 : 1), (12 : 42 : 1),
     1013        (204*a^2 + 65*a + 632 : -5286*a^2 - 1704*a - 16405 : 1), (0 : 0 : 1), (a : 1 : 1), (1 : 2 : 1)]
     1014        sage: E.integral_points()
     1015        Traceback (most recent call last):
     1016        ...
     1017        ValueError: Cannot compute a provable set of generators, please supply generators of the Mordel-Weil group.
     1018       
     1019       
     1020    REFERENCE:
     1021
     1022    .. [SMART] Smart, N. P. and Stephens, N. M., Integral Points on Elliptic Curves over Number Fields.
     1023       Math. Proc. Camb. Phil. Soc. (1997), 122, 9
     1024    """
     1025    if L is None or L == []:
     1026        try:
     1027            L = self.gens()
     1028            r = self.rank()
     1029        except ValueError:
     1030            raise ValueError, "Cannot compute a provable set of generators, please supply generators of the Mordel-Weil group."
     1031        assert len(L) == r
     1032     
     1033    Q = _calculate_Q(self,L)
     1034    int_points = _integral_points_with_Q(self, L, Q)
     1035    if both_signs:
     1036        int_points += [-P for P in int_points]
     1037       
     1038    #need this so doc tests will always have points in the same order
     1039    int_points.sort()
     1040    return int_points
  • sage/schemes/elliptic_curves/ell_number_field.py

    diff -r b2c0ed2e09a4 -r 4d5f9318cce3 sage/schemes/elliptic_curves/ell_number_field.py
    a b  
    110110from sage.structure.element import RingElement
    111111from sage.rings.infinity import Infinity # just for verbose output
    112112from sage.rings.arith import valuation
     113from ell_int_points import integral_points
    113114
    114115class EllipticCurve_number_field(EllipticCurve_field):
    115116    r"""
     
    279280        prob_gens = [self(P) for P in t[2]]
    280281        self._simon_two_descent_data[lim1,lim3,limtriv,maxprob,limbigprime] = (prob_rank, two_selmer_rank, prob_gens)
    281282        return prob_rank, two_selmer_rank, prob_gens
     283       
     284    integral_points = integral_points
     285               
     286               
     287    def silverman_height_bounds(self):
     288        r"""
     289        Return the Silverman height bound.  This is a positive real
     290        (floating point) number B such that for all points `P` on the
     291        curve over any number field, `|h(P) - \hat{h}(P)| \leq B`,
     292        where `h(P)` is the naive logarithmic height of `P` and
     293        `\hat{h}(P)` is the canonical height.
     294
     295        NOTES:
     296
     297           - Silverman's paper is 'The Difference Between the Weil
     298             Height and the Canonical Height on Elliptic Curves',
     299             Math. Comp., Volume 55, Number 192, pages 723-743.  We
     300             use a correction by Bremner with 0.973 replaced by 0.961,
     301             as explained in the source code to mwrank (htconst.cc).
     302             
     303        EXAMPLES::
     304       
     305            sage: E=EllipticCurve('37a1')
     306           
     307                       
     308        """
     309        from sage.rings.all import CC
     310        Delta   = self.discriminant()
     311        j       = self.j_invariant()
     312        b2      = self.b2()
     313        K       = self.base_field()
     314        r,s     = K.signature()
     315        infplaces = K.embeddings(CC) if K is QQ else K.places()
     316        nvs = [1 if i < r else 2 for i,_ in enumerate(infplaces)]
     317       
     318        twostar = 2 if b2 else 1
     319        from math import log
     320        from ell_int_points import abs_log_height
     321        def h(x):
     322            return abs_log_height([K(x),K(1)])
     323        def h_oo(x):
     324            return sum(nvs[i]*log(max(abs(v(x)),1)) for i,v in enumerate(infplaces))/K.degree()
     325        mu    = h(Delta)/12 + h_oo(j)/12 + h_oo(b2/12)/2 + log(twostar)/2
     326        lower = 2*(-h(j)/24 - mu - 0.961)
     327        upper = 2*(mu + 1.07)
     328        return lower, upper
    282329               
    283330    def height_pairing_matrix(self, points=None, precision=None):
    284331        r"""
  • sage/schemes/elliptic_curves/ell_rational_field.py

    diff -r b2c0ed2e09a4 -r 4d5f9318cce3 sage/schemes/elliptic_curves/ell_rational_field.py
    a b  
    2727
    2828- Christian Wuthrich (2010-01): moved Galois reps and modular
    2929  parametrization in a separate file
     30 
    3031
    3132"""
    3233
     
    52205221        return ans
    52215222
    52225223    prove_BSD = BSD.prove_BSD
    5223 
     5224   
    52245225    def integral_points(self, mw_base='auto', both_signs=False, verbose=False):
    52255226        """
    52265227        Computes all integral points (up to sign) on this elliptic curve.
     
    56085609        if verbose:
    56095610            print 'Total number of integral points:',len(int_points)
    56105611        return int_points
    5611        
     5612
    56125613    def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, proof=None):
    56135614        """
    56145615        Computes all S-integral points (up to sign) on this elliptic curve.