Ejemplo n.º 1
0
    def __init__(self,
                 conductor,
                 gammaV,
                 weight,
                 eps,
                 poles=None,
                 residues='automatic',
                 prec=53,
                 init=None):
        """
        Initialization of Dokchitser calculator EXAMPLES::

            sage: L = Dokchitser(conductor=1, gammaV=[0], weight=1, eps=1, poles=[1], residues=[-1], init='1')
            sage: L.num_coeffs()
            4
        """
        self.conductor = conductor
        self.gammaV = gammaV
        self.weight = weight
        self.eps = eps
        self.poles = poles if poles is not None else []
        self.residues = residues
        self.prec = prec
        self.__CC = ComplexField(self.prec)
        self.__RR = self.__CC._real_field()
        self.__initialized = False
        if init is not None:
            self.init_coeffs(init)
Ejemplo n.º 2
0
def _do_sqrt(x, prec=None, extend=True, all=False):
    r"""
        Used internally to compute the square root of x.
        
        INPUT:
        
        -  ``x`` - a number
        
        -  ``prec`` - None (default) or a positive integer
           (bits of precision) If not None, then compute the square root
           numerically to prec bits of precision.
        
        -  ``extend`` - bool (default: True); this is a place
           holder, and is always ignored since in the symbolic ring everything
           has a square root.
        
        -  ``extend`` - bool (default: True); whether to extend
           the base ring to find roots. The extend parameter is ignored if
           prec is a positive integer.
        
        -  ``all`` - bool (default: False); whether to return
           a list of all the square roots of x.
        
        
        EXAMPLES::
        
            sage: from sage.functions.other import _do_sqrt
            sage: _do_sqrt(3)
            sqrt(3)
            sage: _do_sqrt(3,prec=10)
            1.7
            sage: _do_sqrt(3,prec=100)
            1.7320508075688772935274463415
            sage: _do_sqrt(3,all=True)
            [sqrt(3), -sqrt(3)]
        
        Note that the extend parameter is ignored in the symbolic ring::
        
            sage: _do_sqrt(3,extend=False)
            sqrt(3)
        """
    from sage.rings.all import RealField, ComplexField
    if prec:
        if x >= 0:
            return RealField(prec)(x).sqrt(all=all)
        else:
            return ComplexField(prec)(x).sqrt(all=all)
    if x == -1:
        from sage.symbolic.pynac import I
        z = I
    else:
        z = SR(x)**one_half

    if all:
        if z:
            return [z, -z]
        else:
            return [z]
    return z
Ejemplo n.º 3
0
    def _evalf_(self, x, parent_d=None):
        """
        EXAMPLES::

            sage: arg(0.0)
            0.000000000000000
            sage: arg(3.0)
            0.000000000000000
            sage: arg(3.00000000000000000000000000)
            0.00000000000000000000000000
            sage: arg(3.00000000000000000000000000).prec()
            90
            sage: arg(ComplexIntervalField(90)(3)).prec()
            90
            sage: arg(ComplexIntervalField(90)(3)).parent()
            Real Interval Field with 90 bits of precision
            sage: arg(3.0r)
            0.000000000000000
            sage: arg(RDF(3))
            0.0
            sage: arg(RDF(3)).parent()
            Real Double Field
            sage: arg(-2.5)
            3.14159265358979
            sage: arg(2.0+3*i)
            0.982793723247329
        """
        try:
            return x.arg()
        except AttributeError:
            pass
        # try to find a parent that support .arg()
        if parent_d is None:
            parent_d = parent(x)
        try:
            parent_d = parent_d.complex_field()
        except AttributeError:
            from sage.rings.complex_field import ComplexField
            try:
                parent_d = ComplexField(x.prec())
            except AttributeError:
                parent_d = ComplexField()

        return parent_d(x).arg()
Ejemplo n.º 4
0
    def __init__(self, lfun, prec=None):
        """
        Initialization of the L-function from a PARI L-function.

        INPUT:

        - lfun -- a PARI :pari:`lfun` object or an instance of :class:`lfun_generic`
        - prec -- integer (default: 53) number of *bits* of precision

        EXAMPLES::

            sage: from sage.lfunctions.pari import lfun_generic, LFunction
            sage: lf = lfun_generic(conductor=1, gammaV=[0], weight=1, eps=1, poles=[1], residues=[-1], v=pari('k->vector(k,n,1)'))
            sage: L = LFunction(lf)
            sage: L.num_coeffs()
            4
        """
        if isinstance(lfun, lfun_generic):
            # preparation using motivic data
            self._L = lfun.__pari__()
            if prec is None:
                prec = lfun.prec
        elif isinstance(lfun, Gen):
            # already some PARI lfun
            self._L = lfun
        else:
            # create a PARI lfunction from other input data
            self._L = pari.lfuncreate(lfun)

        self._conductor = ZZ(self._L[4])  # needs check
        self._weight = ZZ(self._L[3])  # needs check
        if prec is None:
            self.prec = 53
        else:
            self.prec = PyNumber_Index(prec)
        self._RR = RealField(self.prec)
        self._CC = ComplexField(self.prec)
        # Complex field used for inputs, which ensures exact 1-to-1
        # conversion to/from PARI. Since PARI objects have a precision
        # in machine words (not bits), this is typically higher. For
        # example, the default of 53 bits of precision would become 64.
        self._CCin = ComplexField(pari.bitprecision(self._RR(1)))
Ejemplo n.º 5
0
def zeta_symmetric(s):
    r"""
    Completed function `\xi(s)` that satisfies
    `\xi(s) = \xi(1-s)` and has zeros at the same points as the
    Riemann zeta function.

    INPUT:


    -  ``s`` - real or complex number


    If s is a real number the computation is done using the MPFR
    library. When the input is not real, the computation is done using
    the PARI C library.

    More precisely,

    .. MATH::

                xi(s) = \gamma(s/2 + 1) * (s-1) * \pi^{-s/2} * \zeta(s).



    EXAMPLES::

        sage: zeta_symmetric(0.7)
        0.497580414651127
        sage: zeta_symmetric(1-0.7)
        0.497580414651127
        sage: RR = RealField(200)
        sage: zeta_symmetric(RR(0.7))
        0.49758041465112690357779107525638385212657443284080589766062
        sage: C.<i> = ComplexField()
        sage: zeta_symmetric(0.5 + i*14.0)
        0.000201294444235258 + 1.49077798716757e-19*I
        sage: zeta_symmetric(0.5 + i*14.1)
        0.0000489893483255687 + 4.40457132572236e-20*I
        sage: zeta_symmetric(0.5 + i*14.2)
        -0.0000868931282620101 + 7.11507675693612e-20*I

    REFERENCE:

    - I copied the definition of xi from
      http://web.viu.ca/pughg/RiemannZeta/RiemannZetaLong.html
    """
    if not (is_ComplexNumber(s) or is_RealNumber(s)):
        s = ComplexField()(s)

    R = s.parent()
    if s == 1:  # deal with poles, hopefully
        return R(0.5)

    return (s / 2 + 1).gamma() * (s - 1) * (R.pi()**(-s / 2)) * s.zeta()
Ejemplo n.º 6
0
    def map_to_complex_numbers(self, z, prec=None):
        """
        Evaluate ``self`` at a point `z \in X_0(N)` where `z` is given by
        a representative in the upper half plane, returning a point in
        the complex numbers.

        All computations are done with ``prec`` bits
        of precision.  If ``prec`` is not given, use the precision of `z`.
        Use self(z) to compute the image of z on the Weierstrass equation
        of the curve.

        EXAMPLES::

            sage: E = EllipticCurve('37a'); phi = E.modular_parametrization()
            sage: tau = (sqrt(7)*I - 17)/74
            sage: z = phi.map_to_complex_numbers(tau); z
            0.929592715285395 - 1.22569469099340*I
            sage: E.elliptic_exponential(z)
            (...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
            sage: phi(tau)
            (...e-16 - ...e-16*I : ...e-16 + ...e-16*I : 1.00000000000000)
        """
        if prec is None:
            try:
                prec = z.parent().prec()
            except AttributeError:
                prec = 53
        CC = ComplexField(prec)
        if z in QQ:
            raise NotImplementedError
        z = CC(z)
        if z.imag() <= 0:
            raise ValueError("Point must be in the upper half plane")
        # TODO: for very small imaginary part, maybe try to transform under
        # \Gamma_0(N) to a better representative?
        q = (2 * CC.gen() * CC.pi() * z).exp()
        #  nterms'th term is less than 2**-(prec+10) (c.f. eclib code)
        nterms = (-(prec + 10) / q.abs().log2()).ceil()
        # Use Horner's rule to sum the integral of the form
        enumerated_an = list(enumerate(self._E.anlist(nterms)))[1:]
        lattice_point = 0
        for n, an in reversed(enumerated_an):
            lattice_point += an / n
            lattice_point *= q
        return lattice_point
Ejemplo n.º 7
0
    def _evalf_(self, x, y, parent=None, algorithm='mpmath'):
        """
        EXAMPLES::

            sage: gamma_inc_lower(3,2.)
            0.646647167633873
            sage: gamma_inc_lower(3,2).n(200)
            0.646647167633873081060005050275155...
            sage: gamma_inc_lower(0,2.)
            +infinity
        """
        R = parent or s_parent(x)
        # C is the complex version of R
        # prec is the precision of R
        if R is float:
            prec = 53
            C = complex
        else:
            try:
                prec = R.precision()
            except AttributeError:
                prec = 53
            try:
                C = R.complex_field()
            except AttributeError:
                C = R
        if algorithm == 'pari':
            try:
                v = ComplexField(prec)(x).gamma() - ComplexField(prec)(
                    x).gamma_inc(y)
            except AttributeError:
                if not (is_ComplexNumber(x)):
                    if is_ComplexNumber(y):
                        C = y.parent()
                    else:
                        C = ComplexField()
                        x = C(x)
            v = ComplexField(prec)(x).gamma() - ComplexField(prec)(
                x).gamma_inc(y)
        else:
            import mpmath
            v = ComplexField(prec)(mpmath_utils.call(mpmath.gammainc,
                                                     x,
                                                     0,
                                                     y,
                                                     parent=R))
        if v.is_real():
            return R(v)
        else:
            return C(v)
Ejemplo n.º 8
0
    def _evalf_(self, x, y, parent=None):
        """
        EXAMPLES::

            sage: gamma_inc(0,2)
            -Ei(-2)
            sage: gamma_inc(0,2.)
            0.0489005107080611
            sage: gamma_inc(3,2).n()
            1.35335283236613
        """
        try:
            return x.gamma_inc(y)
        except AttributeError:
            if not (is_ComplexNumber(x)):
                if is_ComplexNumber(y):
                    C = y.parent()
                else:
                    C = ComplexField()
                    x = C(x)
            return x.gamma_inc(y)
Ejemplo n.º 9
0
    def _evalf_(self, x, y, parent=None, algorithm='pari'):
        """
        EXAMPLES::

            sage: gamma_inc(0,2)
            -Ei(-2)
            sage: gamma_inc(0,2.)
            0.0489005107080611
            sage: gamma_inc(0,2).n(algorithm='pari')
            0.0489005107080611
            sage: gamma_inc(0,2).n(200)
            0.048900510708061119567239835228...
            sage: gamma_inc(3,2).n()
            1.35335283236613

        TESTS:

        Check that :trac:`7099` is fixed::

            sage: R = RealField(1024)
            sage: gamma(R(9), R(10^-3))  # rel tol 1e-308
            40319.99999999999999999999999999988898884344822911869926361916294165058203634104838326009191542490601781777105678829520585311300510347676330951251563007679436243294653538925717144381702105700908686088851362675381239820118402497959018315224423868693918493033078310647199219674433536605771315869983788442389633
            sage: numerical_approx(gamma(9, 10^(-3)) - gamma(9), digits=40)  # abs tol 1e-36
            -1.110111598370794007949063502542063148294e-28

        Check that :trac:`17328` is fixed::

            sage: gamma_inc(float(-1), float(-1))
            (-0.8231640121031085+3.141592653589793j)
            sage: gamma_inc(RR(-1), RR(-1))
            -0.823164012103109 + 3.14159265358979*I
            sage: gamma_inc(-1, float(-log(3))) - gamma_inc(-1, float(-log(2)))  # abs tol 1e-15
            (1.2730972164471142+0j)

        Check that :trac:`17130` is fixed::

            sage: r = gamma_inc(float(0), float(1)); r
            0.21938393439552029
            sage: type(r)
            <... 'float'>
        """
        R = parent or s_parent(x)
        # C is the complex version of R
        # prec is the precision of R
        if R is float:
            prec = 53
            C = complex
        else:
            try:
                prec = R.precision()
            except AttributeError:
                prec = 53
            try:
                C = R.complex_field()
            except AttributeError:
                C = R

        if algorithm == 'pari':
            v = ComplexField(prec)(x).gamma_inc(y)
        else:
            import mpmath
            v = ComplexField(prec)(mpmath_utils.call(mpmath.gammainc,
                                                     x,
                                                     y,
                                                     parent=R))
        if v.is_real():
            return R(v)
        else:
            return C(v)
Ejemplo n.º 10
0
    def _coerce_map_from_(self, P):
        r"""
        Return whether ``P`` coerces into this symbolic subring.

        INPUT:

        - ``P`` -- a parent.

        OUTPUT:

        A boolean or ``None``.

        TESTS::

            sage: from sage.symbolic.subring import GenericSymbolicSubring
            sage: GenericSymbolicSubring(vars=tuple()).has_coerce_map_from(SR)  # indirect doctest  # not tested see #19231
            False

        ::
            sage: from sage.symbolic.subring import SymbolicSubring
            sage: C = SymbolicSubring(no_variables=True)
            sage: C.has_coerce_map_from(ZZ)  # indirect doctest
            True
            sage: C.has_coerce_map_from(QQ)  # indirect doctest
            True
            sage: C.has_coerce_map_from(RR)  # indirect doctest
            True
            sage: C.has_coerce_map_from(RIF)  # indirect doctest
            True
            sage: C.has_coerce_map_from(CC)  # indirect doctest
            True
            sage: C.has_coerce_map_from(CIF)  # indirect doctest
            True
            sage: C.has_coerce_map_from(AA)  # indirect doctest
            True
            sage: C.has_coerce_map_from(QQbar)  # indirect doctest
            True
            sage: C.has_coerce_map_from(SR)  # indirect doctest
            False
        """
        if P == SR:
            # Workaround; can be deleted once #19231 is fixed
            return False

        from sage.rings.real_mpfr import mpfr_prec_min
        from sage.rings.all import (ComplexField, RLF, CLF, AA, QQbar,
                                    InfinityRing)
        from sage.rings.real_mpfi import is_RealIntervalField
        from sage.rings.complex_interval_field import is_ComplexIntervalField

        if isinstance(P, type):
            return SR._coerce_map_from_(P)

        elif RLF.has_coerce_map_from(P) or \
             CLF.has_coerce_map_from(P) or \
             AA.has_coerce_map_from(P) or \
             QQbar.has_coerce_map_from(P):
            return True

        elif (P is InfinityRing or is_RealIntervalField(P)
              or is_ComplexIntervalField(P)):
            return True

        elif ComplexField(mpfr_prec_min()).has_coerce_map_from(P):
            return P not in (RLF, CLF, AA, QQbar)
Ejemplo n.º 11
0
def hilbert_class_polynomial(D, algorithm=None):
    r"""
    Return the Hilbert class polynomial for discriminant `D`.

    INPUT:

    - ``D`` (int) -- a negative integer congruent to 0 or 1 modulo 4.

    - ``algorithm`` (string, default None).

    OUTPUT:

    (integer polynomial) The Hilbert class polynomial for the
    discriminant `D`.

    ALGORITHM:

    - If ``algorithm`` = "arb" (default): Use Arb's implementation which uses complex interval arithmetic.

    - If ``algorithm`` = "sage": Use complex approximations to the roots.

    - If ``algorithm`` = "magma": Call the appropriate Magma function (if available).

    AUTHORS:

    - Sage implementation originally by Eduardo Ocampo Alvarez and
      AndreyTimofeev

    - Sage implementation corrected by John Cremona (using corrected precision bounds from Andreas Enge)

    - Magma implementation by David Kohel

    EXAMPLES::

        sage: hilbert_class_polynomial(-4)
        x - 1728
        sage: hilbert_class_polynomial(-7)
        x + 3375
        sage: hilbert_class_polynomial(-23)
        x^3 + 3491750*x^2 - 5151296875*x + 12771880859375
        sage: hilbert_class_polynomial(-37*4)
        x^2 - 39660183801072000*x - 7898242515936467904000000
        sage: hilbert_class_polynomial(-37*4, algorithm="magma") # optional - magma
        x^2 - 39660183801072000*x - 7898242515936467904000000
        sage: hilbert_class_polynomial(-163)
        x + 262537412640768000
        sage: hilbert_class_polynomial(-163, algorithm="sage")
        x + 262537412640768000
        sage: hilbert_class_polynomial(-163, algorithm="magma") # optional - magma
        x + 262537412640768000

    TESTS::

        sage: all([hilbert_class_polynomial(d, algorithm="arb") == \
        ....:      hilbert_class_polynomial(d, algorithm="sage") \
        ....:        for d in range(-1,-100,-1) if d%4 in [0,1]])
        True

    """
    if algorithm is None:
        algorithm = "arb"

    D = Integer(D)
    if D >= 0:
        raise ValueError("D (=%s) must be negative" % D)
    if not (D % 4 in [0, 1]):
        raise ValueError("D (=%s) must be a discriminant" % D)

    if algorithm == "arb":
        import sage.libs.arb.arith
        return sage.libs.arb.arith.hilbert_class_polynomial(D)

    if algorithm == "magma":
        magma.eval("R<x> := PolynomialRing(IntegerRing())")
        f = str(magma.eval("HilbertClassPolynomial(%s)" % D))
        return IntegerRing()['x'](f)

    if algorithm != "sage":
        raise ValueError("%s is not a valid algorithm" % algorithm)

    from sage.quadratic_forms.binary_qf import BinaryQF_reduced_representatives
    from sage.rings.all import RR, ComplexField
    from sage.functions.all import elliptic_j

    # get all primitive reduced quadratic forms, (necessary to exclude
    # imprimitive forms when D is not a fundamental discriminant):

    rqf = BinaryQF_reduced_representatives(D, primitive_only=True)

    # compute needed precision
    #
    # NB: [https://arxiv.org/abs/0802.0979v1], quoting Enge (2006), is
    # incorrect.  Enge writes (2009-04-20 email to John Cremona) "The
    # source is my paper on class polynomials
    # [https://hal.inria.fr/inria-00001040] It was pointed out to me by
    # the referee after ANTS that the constant given there was
    # wrong. The final version contains a corrected constant on p.7
    # which is consistent with your example. It says:

    # "The logarithm of the absolute value of the coefficient in front
    # of X^j is bounded above by
    #
    # log (2*k_2) * h + pi * sqrt(|D|) * sum (1/A_i)
    #
    # independently of j", where k_2 \approx 10.163.

    h = len(rqf)  # class number
    c1 = 3.05682737291380  # log(2*10.63)
    c2 = sum([1 / RR(qf[0]) for qf in rqf], RR(0))
    prec = c2 * RR(3.142) * RR(D).abs().sqrt() + h * c1  # bound on log
    prec = prec * 1.45  # bound on log_2 (1/log(2) = 1.44..)
    prec = 10 + prec.ceil()  # allow for rounding error

    # set appropriate precision for further computing

    Dsqrt = D.sqrt(prec=prec)
    R = ComplexField(prec)['t']
    t = R.gen()
    pol = R(1)
    for qf in rqf:
        a, b, c = list(qf)
        tau = (b + Dsqrt) / (a << 1)
        pol *= (t - elliptic_j(tau))

    coeffs = [cof.real().round() for cof in pol.coefficients(sparse=False)]
    return IntegerRing()['x'](coeffs)
Ejemplo n.º 12
0
"""
Complex Elliptic Curve L-series

"""

from sage.structure.sage_object import SageObject
from sage.rings.all import (RealField, RationalField, ComplexField)
from math import sqrt, exp, ceil
import sage.functions.transcendental as transcendental
R = RealField()
Q = RationalField()
C = ComplexField()
import sage.misc.all as misc


class Lseries_ell(SageObject):
    """
    An elliptic curve $L$-series.

    EXAMPLES:
    
    """
    def __init__(self, E):
        """
        Create an elliptic curve $L$-series.

        EXAMPLES:
            sage: EllipticCurve([1..5]).lseries()
            Complex L-series of the Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Rational Field
        """
        self.__E = E