Ticket #6045: 6045-heegner-fixes.patch

File 6045-heegner-fixes.patch, 5.2 KB (added by robertwb, 12 years ago)
  • sage/schemes/elliptic_curves/ell_rational_field.py

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1246437022 25200
    # Node ID b0ca7b122de526b147903018e18258e5ff92806f
    # Parent  bf9420e831ac438847a6f4991dd32af21570f1ee
    Heegner point referee updates
    
    diff -r bf9420e831ac -r b0ca7b122de5 sage/schemes/elliptic_curves/ell_rational_field.py
    a b  
    52765276        self.__heegner_sha_an[(D,prec)] = sha_an
    52775277        return sha_an
    52785278       
    5279     def _heegner_forms_list(self, D):
     5279    def _heegner_forms_list(self, D, beta=None, expected_count=None):
    52805280        """
    52815281        Returns a list of quadratic forms corresponding to Heegner points
    5282         with discriminant `D`. Specifically, given a quadratic form
     5282        with discriminant `D` and a choice of `\beta` a square root of
     5283        `D` mod `4N`. Specifically, given a quadratic form
    52835284        `f = Ax^2 + Bxy + Cy^2` we let `\tau_f` be a root of `Ax^2 + Bx + C`
    52845285        and the discriminant `\Delta(\tau_f) = \Delta(f) = D` must be
    52855286        invariant under multiplication by `N`, the conductor of self.
     
    52905291       
    52915292            sage: E = EllipticCurve('37a')
    52925293            sage: E._heegner_forms_list(-7)
    5293             [37*x^2 + 17*x*y + 2*y^2, 37*x^2 + 57*x*y + 22*y^2]
     5294            [37*x^2 + 17*x*y + 2*y^2]
     5295            sage: E._heegner_forms_list(-195)
     5296            [37*x^2 + 29*x*y + 7*y^2, 259*x^2 + 29*x*y + y^2, 111*x^2 + 177*x*y + 71*y^2, 2627*x^2 + 177*x*y + 3*y^2]
     5297            sage: E._heegner_forms_list(-195)[-1].discriminant()
     5298            -195
     5299            sage: len(E._heegner_forms_list(-195))
     5300            4
     5301            sage: QQ[sqrt(-195)].class_number()
     5302            4
     5303
    52945304            sage: E = EllipticCurve('389a')
    52955305            sage: E._heegner_forms_list(-7)
    5296             [389*x^2 + 185*x*y + 22*y^2, 389*x^2 + 593*x*y + 226*y^2]
    5297             sage: E._heegner_forms_list(-55)
    5298             [389*x^2 + 201*x*y + 26*y^2, 778*x^2 + 201*x*y + 13*y^2, 5057*x^2 + 201*x*y + 2*y^2, 389*x^2 + 577*x*y + 214*y^2, 778*x^2 + 577*x*y + 107*y^2, 41623*x^2 + 577*x*y + 2*y^2]
    5299         """
     5306            [389*x^2 + 185*x*y + 22*y^2]
     5307            sage: E._heegner_forms_list(-59)
     5308            [389*x^2 + 313*x*y + 63*y^2, 1167*x^2 + 313*x*y + 21*y^2, 3501*x^2 + 313*x*y + 7*y^2]
     5309        """
     5310        if expected_count is None:
     5311            expected_count = number_field.QuadraticField(D, 'a').class_number()
     5312        N = self.conductor()
     5313        if beta is None:
     5314            beta = Integers(4*N)(D).sqrt(extend=False)
     5315        else:
     5316            assert beta**2 == Integers(4*N)(D)
    53005317        from sage.quadratic_forms.all import BinaryQF
    5301         N = self.conductor()
     5318        b = ZZ(beta) % (2*N)
    53025319        all = []
    53035320        seen = []
    5304         betas = Integers(4*N)(D).sqrt(all=True)
    5305         for b  in set([(beta % (2*N)).lift() for beta in betas]):
     5321        # TODO: This may give a sub-optimal list of forms.
     5322        while True:
    53065323            R = (b**2-D)//(4*N)
    53075324            for d in R.divisors():
    53085325                f = BinaryQF([d*N, b, R//d])
     
    53105327                if fr not in seen:
    53115328                    seen.append(fr)
    53125329                    all.append(f)
    5313             seen = []
    5314         return all
     5330                    if len(all) == expected_count:
     5331                        return all
     5332            b += 2*N
    53155333   
    53165334    def _heegner_best_tau(self, D, prec=None):
    53175335        """
    53185336        Given a discrimanent `D`, find the Heegner point `\tau` in the
    53195337        upper half plane with largest imaginary part (which is optimal
    53205338        for evaluating the modular parametrization). If the optional
    5321         parameter ``prec`` is give, return `\tau` to ``prec`` bits of
     5339        parameter ``prec`` is given, return `\tau` to ``prec`` bits of
    53225340        precision, otherwise return it exactly as a symbolic object.
    53235341       
    53245342        EXAMPLES::
     
    53285346            1/74*sqrt(-7) - 17/74
    53295347            sage: EllipticCurve('389a')._heegner_best_tau(-11)
    53305348            1/778*sqrt(-11) - 355/778
    5331         """
    5332         best = None
    5333         for f in self._heegner_forms_list(D):
    5334             if best is None or f[1] < best[1]:
    5335                 best = f
    5336         A, B, C = best
    5337         return (-B + best.discriminant().sqrt(prec=prec)) / (2*A)
     5349            sage: EllipticCurve('389a')._heegner_best_tau(-11, prec=100)
     5350            -0.45629820051413881748071979434 + 0.0042630138693514136878083968338*I
     5351        """
     5352        # We know that N|A, so A = N is optimal.
     5353        N = self.conductor()
     5354        b = ZZ(Integers(4*N)(D).sqrt(extend=False) % (2*N))
     5355        return (-b + D.sqrt(prec=prec)) / (2*N)
    53385356
    53395357    def heegner_point(self, D, prec=None, max_prec=2000):
    53405358        """
    53415359        Returns the heegner point of this curve and the quadratic imaginary
    5342         field `K=\QQ(\sqrt{D})`. If the optional parameter ``prec`` is give,
     5360        field `K=\QQ(\sqrt{D})`. If the optional parameter ``prec`` is given,
    53435361        it is computed with ``prec`` bits of working precision, otherwise it
    53445362        attempts to recognize it exactly over the Hilbert class field of `K`.
    53455363        In this  latter case, the answer is *not* proveably correct but a