コード例 #1
0
ファイル: evalf.py プロジェクト: hridog00/Proyecto
def evalf_log(expr, prec, options):
    from sympy import Abs, Add, log
    if len(expr.args) > 1:
        expr = expr.doit()
        return evalf(expr, prec, options)
    arg = expr.args[0]
    workprec = prec + 10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(log(Abs(arg, evaluate=False), evaluate=False), prec,
                       options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = (mpf_cmp(xre, fzero) < 0)

    re = mpf_log(mpf_abs(xre), prec, rnd)
    size = fastlog(re)
    if prec - size > workprec and re != fzero:
        # We actually need to compute 1+x accurately, not x
        arg = Add(S.NegativeOne, arg, evaluate=False)
        xre, xim, _, _ = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        # xre is now x - 1 so we add 1 back here to calculate x
        re = mpf_log(mpf_abs(mpf_add(xre, fone, prec2)), prec, rnd)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
コード例 #2
0
ファイル: evalf.py プロジェクト: arghdos/sympy
def evalf_log(expr, prec, options):
    from sympy import Abs, Add, log
    if len(expr.args)>1:
        expr = expr.doit()
        return evalf(expr, prec, options)
    arg = expr.args[0]
    workprec = prec + 10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(
            log(Abs(arg, evaluate=False), evaluate=False), prec, options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = (mpf_cmp(xre, fzero) < 0)

    re = mpf_log(mpf_abs(xre), prec, rnd)
    size = fastlog(re)
    if prec - size > workprec and re != fzero:
        # We actually need to compute 1+x accurately, not x
        arg = Add(S.NegativeOne, arg, evaluate=False)
        xre, xim, _, _ = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        # xre is now x - 1 so we add 1 back here to calculate x
        re = mpf_log(mpf_abs(mpf_add(xre, fone, prec2)), prec, rnd)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
コード例 #3
0
ファイル: evalf.py プロジェクト: arghdos/sympy
def _create_evalf_table():
    global evalf_table
    from sympy.functions.combinatorial.numbers import bernoulli
    from sympy.concrete.products import Product
    from sympy.concrete.summations import Sum
    from sympy.core.add import Add
    from sympy.core.mul import Mul
    from sympy.core.numbers import Exp1, Float, Half, ImaginaryUnit, Integer, NaN, NegativeOne, One, Pi, Rational, Zero
    from sympy.core.power import Pow
    from sympy.core.symbol import Dummy, Symbol
    from sympy.functions.elementary.complexes import Abs, im, re
    from sympy.functions.elementary.exponential import exp, log
    from sympy.functions.elementary.integers import ceiling, floor
    from sympy.functions.elementary.piecewise import Piecewise
    from sympy.functions.elementary.trigonometric import atan, cos, sin
    from sympy.integrals.integrals import Integral
    evalf_table = {
        Symbol: evalf_symbol,
        Dummy: evalf_symbol,
        Float: lambda x, prec, options: (x._mpf_, None, prec, None),
        Rational: lambda x, prec, options: (from_rational(x.p, x.q, prec), None, prec, None),
        Integer: lambda x, prec, options: (from_int(x.p, prec), None, prec, None),
        Zero: lambda x, prec, options: (None, None, prec, None),
        One: lambda x, prec, options: (fone, None, prec, None),
        Half: lambda x, prec, options: (fhalf, None, prec, None),
        Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None),
        Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None),
        ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec),
        NegativeOne: lambda x, prec, options: (fnone, None, prec, None),
        NaN: lambda x, prec, options: (fnan, None, prec, None),

        exp: lambda x, prec, options: evalf_pow(
            Pow(S.Exp1, x.args[0], evaluate=False), prec, options),

        cos: evalf_trig,
        sin: evalf_trig,

        Add: evalf_add,
        Mul: evalf_mul,
        Pow: evalf_pow,

        log: evalf_log,
        atan: evalf_atan,
        Abs: evalf_abs,

        re: evalf_re,
        im: evalf_im,
        floor: evalf_floor,
        ceiling: evalf_ceiling,

        Integral: evalf_integral,
        Sum: evalf_sum,
        Product: evalf_prod,
        Piecewise: evalf_piecewise,

        bernoulli: evalf_bernoulli,
    }
コード例 #4
0
def _create_evalf_table():
    global evalf_table
    from sympy.functions.combinatorial.numbers import bernoulli
    from sympy.concrete.products import Product
    from sympy.concrete.summations import Sum
    from sympy.core.add import Add
    from sympy.core.mul import Mul
    from sympy.core.numbers import Exp1, Float, Half, ImaginaryUnit, Integer, NaN, NegativeOne, One, Pi, Rational, Zero
    from sympy.core.power import Pow
    from sympy.core.symbol import Dummy, Symbol
    from sympy.functions.elementary.complexes import Abs, im, re
    from sympy.functions.elementary.exponential import exp, log
    from sympy.functions.elementary.integers import ceiling, floor
    from sympy.functions.elementary.piecewise import Piecewise
    from sympy.functions.elementary.trigonometric import atan, cos, sin
    from sympy.integrals.integrals import Integral
    evalf_table = {
        Symbol: evalf_symbol,
        Dummy: evalf_symbol,
        Float: lambda x, prec, options: (x._mpf_, None, prec, None),
        Rational: lambda x, prec, options: (from_rational(x.p, x.q, prec), None, prec, None),
        Integer: lambda x, prec, options: (from_int(x.p, prec), None, prec, None),
        Zero: lambda x, prec, options: (None, None, prec, None),
        One: lambda x, prec, options: (fone, None, prec, None),
        Half: lambda x, prec, options: (fhalf, None, prec, None),
        Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None),
        Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None),
        ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec),
        NegativeOne: lambda x, prec, options: (fnone, None, prec, None),
        NaN : lambda x, prec, options: (fnan, None, prec, None),

        exp: lambda x, prec, options: evalf_pow(
            Pow(S.Exp1, x.args[0], evaluate=False), prec, options),

        cos: evalf_trig,
        sin: evalf_trig,

        Add: evalf_add,
        Mul: evalf_mul,
        Pow: evalf_pow,

        log: evalf_log,
        atan: evalf_atan,
        Abs: evalf_abs,

        re: evalf_re,
        im: evalf_im,
        floor: evalf_floor,
        ceiling: evalf_ceiling,

        Integral: evalf_integral,
        Sum: evalf_sum,
        Product: evalf_prod,
        Piecewise: evalf_piecewise,

        bernoulli: evalf_bernoulli,
    }
コード例 #5
0
ファイル: evalf.py プロジェクト: skirpichev/diofant
def _create_evalf_table():
    global evalf_table
    from ..functions.combinatorial.numbers import bernoulli
    from ..concrete.products import Product
    from ..concrete.summations import Sum
    from .add import Add
    from .mul import Mul
    from .numbers import (Exp1, Float, Half, ImaginaryUnit,
                          Integer, NaN, NegativeOne, One, Pi,
                          Rational, Zero)
    from .power import Pow
    from .symbol import Dummy, Symbol
    from ..functions.elementary.complexes import Abs, im, re
    from ..functions.elementary.exponential import log
    from ..functions.elementary.piecewise import Piecewise
    from ..functions.elementary.trigonometric import atan, cos, sin
    from ..integrals.integrals import Integral
    evalf_table = {
        Symbol: evalf_symbol,
        Dummy: evalf_symbol,
        Float: lambda x, prec, options: (x._mpf_, None, prec if prec <= x._prec else x._prec, None),
        Rational: lambda x, prec, options: (from_rational(x.numerator, x.denominator, prec),
                                            None, prec, None),
        Integer: lambda x, prec, options: (from_int(x.numerator, prec),
                                           None, prec, None),
        Zero: lambda x, prec, options: (None, None, prec, None),
        One: lambda x, prec, options: (fone, None, prec, None),
        Half: lambda x, prec, options: (fhalf, None, prec, None),
        Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None),
        Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None),
        ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec),
        NegativeOne: lambda x, prec, options: (fnone, None, prec, None),
        NaN: lambda x, prec, options: (fnan, None, prec, None),

        cos: evalf_trig,
        sin: evalf_trig,

        Add: evalf_add,
        Mul: evalf_mul,
        Pow: evalf_pow,

        log: evalf_log,
        atan: evalf_atan,
        Abs: evalf_abs,

        re: evalf_re,
        im: evalf_im,

        Integral: evalf_integral,
        Sum: evalf_sum,
        Product: evalf_prod,
        Piecewise: evalf_piecewise,

        bernoulli: evalf_bernoulli,
    }
コード例 #6
0
ファイル: evalf.py プロジェクト: Blendify/diofant
def _create_evalf_table():
    global evalf_table
    from ..functions.combinatorial.numbers import bernoulli
    from ..concrete.products import Product
    from ..concrete.summations import Sum
    from .add import Add
    from .mul import Mul
    from .numbers import (Exp1, Float, Half, ImaginaryUnit,
                          Integer, NaN, NegativeOne, One, Pi,
                          Rational, Zero)
    from .power import Pow
    from .symbol import Dummy, Symbol
    from ..functions.elementary.complexes import Abs, im, re
    from ..functions.elementary.exponential import log
    from ..functions.elementary.piecewise import Piecewise
    from ..functions.elementary.trigonometric import atan, cos, sin
    from ..integrals.integrals import Integral
    evalf_table = {
        Symbol: evalf_symbol,
        Dummy: evalf_symbol,
        Float: lambda x, prec, options: (x._mpf_, None, prec if prec <= x._prec else x._prec, None),
        Rational: lambda x, prec, options: (from_rational(x.numerator, x.denominator, prec),
                                            None, prec, None),
        Integer: lambda x, prec, options: (from_int(x.numerator, prec),
                                           None, prec, None),
        Zero: lambda x, prec, options: (None, None, prec, None),
        One: lambda x, prec, options: (fone, None, prec, None),
        Half: lambda x, prec, options: (fhalf, None, prec, None),
        Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None),
        Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None),
        ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec),
        NegativeOne: lambda x, prec, options: (fnone, None, prec, None),
        NaN: lambda x, prec, options: (fnan, None, prec, None),

        cos: evalf_trig,
        sin: evalf_trig,

        Add: evalf_add,
        Mul: evalf_mul,
        Pow: evalf_pow,

        log: evalf_log,
        atan: evalf_atan,
        Abs: evalf_abs,

        re: evalf_re,
        im: evalf_im,

        Integral: evalf_integral,
        Sum: evalf_sum,
        Product: evalf_prod,
        Piecewise: evalf_piecewise,

        bernoulli: evalf_bernoulli,
    }
コード例 #7
0
ファイル: partitions_.py プロジェクト: AStorus/sympy
def npartitions(n, verbose=False):
    """
    Calculate the partition function P(n), i.e. the number of ways that
    n can be written as a sum of positive integers.

    P(n) is computed using the Hardy-Ramanujan-Rademacher formula [1]_.


    The correctness of this implementation has been tested through 10**10.

    Examples
    ========

    >>> from sympy.ntheory import npartitions
    >>> npartitions(25)
    1958

    References
    ==========

    .. [1] http://mathworld.wolfram.com/PartitionFunctionP.html

    """
    n = int(n)
    if n < 0:
        return 0
    if n <= 5:
        return [1, 1, 2, 3, 5, 7][n]
    if '_factor' not in globals():
        _pre()
    # Estimate number of bits in p(n). This formula could be tidied
    pbits = int((
        math.pi*(2*n/3.)**0.5 -
        math.log(4*n))/math.log(10) + 1) * \
        math.log(10, 2)
    prec = p = int(pbits*1.1 + 100)
    s = fzero
    M = max(6, int(0.24*n**0.5 + 4))
    if M > 10**5:
        raise ValueError("Input too big") # Corresponds to n > 1.7e11
    sq23pi = mpf_mul(mpf_sqrt(from_rational(2, 3, p), p), mpf_pi(p), p)
    sqrt8 = mpf_sqrt(from_int(8), p)
    for q in range(1, M):
        a = _a(n, q, p)
        d = _d(n, q, p, sq23pi, sqrt8)
        s = mpf_add(s, mpf_mul(a, d), prec)
        if verbose:
            print("step", q, "of", M, to_str(a, 10), to_str(d, 10))
        # On average, the terms decrease rapidly in magnitude.
        # Dynamically reducing the precision greatly improves
        # performance.
        p = bitcount(abs(to_int(d))) + 50
    return int(to_int(mpf_add(s, fhalf, prec)))
コード例 #8
0
def npartitions(n, verbose=False):
    """
    Calculate the partition function P(n), i.e. the number of ways that
    n can be written as a sum of positive integers.

    P(n) is computed using the Hardy-Ramanujan-Rademacher formula [1]_.


    The correctness of this implementation has been tested through 10**10.

    Examples
    ========

    >>> from sympy.ntheory import npartitions
    >>> npartitions(25)
    1958

    References
    ==========

    .. [1] http://mathworld.wolfram.com/PartitionFunctionP.html

    """
    n = int(n)
    if n < 0:
        return 0
    if n <= 5:
        return [1, 1, 2, 3, 5, 7][n]
    if '_factor' not in globals():
        _pre()
    # Estimate number of bits in p(n). This formula could be tidied
    pbits = int((
        math.pi*(2*n/3.)**0.5 -
        math.log(4*n))/math.log(10) + 1) * \
        math.log(10, 2)
    prec = p = int(pbits * 1.1 + 100)
    s = fzero
    M = max(6, int(0.24 * n**0.5 + 4))
    if M > 10**5:
        raise ValueError("Input too big")  # Corresponds to n > 1.7e11
    sq23pi = mpf_mul(mpf_sqrt(from_rational(2, 3, p), p), mpf_pi(p), p)
    sqrt8 = mpf_sqrt(from_int(8), p)
    for q in range(1, M):
        a = _a(n, q, p)
        d = _d(n, q, p, sq23pi, sqrt8)
        s = mpf_add(s, mpf_mul(a, d), prec)
        if verbose:
            print("step", q, "of", M, to_str(a, 10), to_str(d, 10))
        # On average, the terms decrease rapidly in magnitude.
        # Dynamically reducing the precision greatly improves
        # performance.
        p = bitcount(abs(to_int(d))) + 50
    return int(to_int(mpf_add(s, fhalf, prec)))
コード例 #9
0
ファイル: partitions_.py プロジェクト: A-turing-machine/sympy
def _d(n, j, prec, sq23pi, sqrt8):
    """
    Compute the sinh term in the outer sum of the HRR formula.
    The constants sqrt(2/3*pi) and sqrt(8) must be precomputed.
    """
    j = from_int(j)
    pi = mpf_pi(prec)
    a = mpf_div(sq23pi, j, prec)
    b = mpf_sub(from_int(n), from_rational(1, 24, prec), prec)
    c = mpf_sqrt(b, prec)
    ch, sh = mpf_cosh_sinh(mpf_mul(a, c), prec)
    D = mpf_div(mpf_sqrt(j, prec), mpf_mul(mpf_mul(sqrt8, b), pi), prec)
    E = mpf_sub(mpf_mul(a, ch), mpf_div(sh, c, prec), prec)
    return mpf_mul(D, E)
コード例 #10
0
def _d(n, j, prec, sq23pi, sqrt8):
    """
    Compute the sinh term in the outer sum of the HRR formula.
    The constants sqrt(2/3*pi) and sqrt(8) must be precomputed.
    """
    j = from_int(j)
    pi = mpf_pi(prec)
    a = mpf_div(sq23pi, j, prec)
    b = mpf_sub(from_int(n), from_rational(1, 24, prec), prec)
    c = mpf_sqrt(b, prec)
    ch, sh = mpf_cosh_sinh(mpf_mul(a, c), prec)
    D = mpf_div(mpf_sqrt(j, prec), mpf_mul(mpf_mul(sqrt8, b), pi), prec)
    E = mpf_sub(mpf_mul(a, ch), mpf_div(sh, c, prec), prec)
    return mpf_mul(D, E)
コード例 #11
0
ファイル: partitions_.py プロジェクト: naveensaigit/diofant
def npartitions(n):
    """Calculate the partition function P(n), i.e. the number of ways that
    n can be written as a sum of positive integers.

    P(n) is computed using the Hardy-Ramanujan-Rademacher formula.

    The correctness of this implementation has been tested for 10**n
    up to n = 8.

    Examples
    ========

    >>> npartitions(25)
    1958

    References
    ==========

    * https://mathworld.wolfram.com/PartitionFunctionP.html

    """
    n = int(n)
    if n < 0:
        return 0
    if n <= 5:
        return [1, 1, 2, 3, 5, 7][n]
    # Estimate number of bits in p(n). This formula could be tidied
    pbits = int((math.pi*(2*n/3.)**0.5 - math.log(4*n))/math.log(10) + 1) * \
        math.log(10, 2)
    prec = p = int(pbits * 1.1 + 100)
    s = fzero
    M = max(6, int(0.24 * n**0.5 + 4))
    sq23pi = mpf_mul(mpf_sqrt(from_rational(2, 3, p), p), mpf_pi(p), p)
    sqrt8 = mpf_sqrt(from_int(8), p)
    for q in range(1, M):
        a = _a(n, q, p)
        d = _d(n, q, p, sq23pi, sqrt8)
        s = mpf_add(s, mpf_mul(a, d), prec)
        debug('step', q, 'of', M, to_str(a, 10), to_str(d, 10))
        # On average, the terms decrease rapidly in magnitude. Dynamically
        # reducing the precision greatly improves performance.
        p = bitcount(abs(to_int(d))) + 50
    return int(to_int(mpf_add(s, fhalf, prec)))
コード例 #12
0
ファイル: evalf.py プロジェクト: yang603/sympy
def _create_evalf_table():
    global evalf_table
    evalf_table = {
        C.Symbol: evalf_symbol,
        C.Dummy: evalf_symbol,
        C.Float: lambda x, prec, options: (x._mpf_, None, prec, None),
        C.Rational: lambda x, prec, options: (from_rational(x.p, x.q, prec), None, prec, None),
        C.Integer: lambda x, prec, options: (from_int(x.p, prec), None, prec, None),
        C.Zero: lambda x, prec, options: (None, None, prec, None),
        C.One: lambda x, prec, options: (fone, None, prec, None),
        C.Half: lambda x, prec, options: (fhalf, None, prec, None),
        C.Pi: lambda x, prec, options: (mpf_pi(prec), None, prec, None),
        C.Exp1: lambda x, prec, options: (mpf_e(prec), None, prec, None),
        C.ImaginaryUnit: lambda x, prec, options: (None, fone, None, prec),
        C.NegativeOne: lambda x, prec, options: (fnone, None, prec, None),
        C.NaN : lambda x, prec, options: (fnan, None, prec, None),

        C.exp: lambda x, prec, options: evalf_pow(C.Pow(S.Exp1, x.args[0],
        evaluate=False), prec, options),

        C.cos: evalf_trig,
        C.sin: evalf_trig,

        C.Add: evalf_add,
        C.Mul: evalf_mul,
        C.Pow: evalf_pow,

        C.log: evalf_log,
        C.atan: evalf_atan,
        C.Abs: evalf_abs,

        C.re: evalf_re,
        C.im: evalf_im,
        C.floor: evalf_floor,
        C.ceiling: evalf_ceiling,

        C.Integral: evalf_integral,
        C.Sum: evalf_sum,
        C.Product: evalf_prod,
        C.Piecewise: evalf_piecewise,

        C.bernoulli: evalf_bernoulli,
    }
コード例 #13
0
ファイル: partitions_.py プロジェクト: skirpichev/diofant
def npartitions(n):
    """Calculate the partition function P(n), i.e. the number of ways that
    n can be written as a sum of positive integers.

    P(n) is computed using the Hardy-Ramanujan-Rademacher formula.

    The correctness of this implementation has been tested for 10**n
    up to n = 8.

    Examples
    ========

    >>> npartitions(25)
    1958

    References
    ==========

    * http://mathworld.wolfram.com/PartitionFunctionP.html

    """
    n = int(n)
    if n < 0:
        return 0
    if n <= 5:
        return [1, 1, 2, 3, 5, 7][n]
    # Estimate number of bits in p(n). This formula could be tidied
    pbits = int((math.pi*(2*n/3.)**0.5 - math.log(4*n))/math.log(10) + 1) * \
        math.log(10, 2)
    prec = p = int(pbits*1.1 + 100)
    s = fzero
    M = max(6, int(0.24*n**0.5 + 4))
    sq23pi = mpf_mul(mpf_sqrt(from_rational(2, 3, p), p), mpf_pi(p), p)
    sqrt8 = mpf_sqrt(from_int(8), p)
    for q in range(1, M):
        a = _a(n, q, p)
        d = _d(n, q, p, sq23pi, sqrt8)
        s = mpf_add(s, mpf_mul(a, d), prec)
        debug("step", q, "of", M, to_str(a, 10), to_str(d, 10))
        # On average, the terms decrease rapidly in magnitude. Dynamically
        # reducing the precision greatly improves performance.
        p = bitcount(abs(to_int(d))) + 50
    return int(to_int(mpf_add(s, fhalf, prec)))
コード例 #14
0
ファイル: partitions_.py プロジェクト: AStorus/sympy
def _a(n, k, prec):
    """ Compute the inner sum in HRR formula [1]_

    References
    ==========

    .. [1] http://msp.org/pjm/1956/6-1/pjm-v6-n1-p18-p.pdf

    """
    if k == 1:
        return fone

    k1 = k
    e = 0
    p = _factor[k]
    while k1 % p == 0:
        k1 //= p
        e += 1
    k2 = k//k1 # k2 = p^e
    v = 1 - 24*n
    pi = mpf_pi(prec)

    if k1 == 1:
        # k  = p^e
        if p == 2:
            mod = 8*k
            v = mod + v % mod
            v = (v*pow(9, k - 1, mod)) % mod
            m = _sqrt_mod_prime_power(v, 2, e + 3)[0]
            arg = mpf_div(mpf_mul(
                from_int(4*m), pi, prec), from_int(mod), prec)
            return mpf_mul(mpf_mul(
                from_int((-1)**e*jacobi_symbol(m - 1, m)),
                mpf_sqrt(from_int(k), prec), prec),
                mpf_sin(arg, prec), prec)
        if p == 3:
            mod = 3*k
            v = mod + v % mod
            if e > 1:
                v = (v*pow(64, k//3 - 1, mod)) % mod
            m = _sqrt_mod_prime_power(v, 3, e + 1)[0]
            arg = mpf_div(mpf_mul(from_int(4*m), pi, prec),
                from_int(mod), prec)
            return mpf_mul(mpf_mul(
                from_int(2*(-1)**(e + 1)*legendre_symbol(m, 3)),
                mpf_sqrt(from_int(k//3), prec), prec),
                mpf_sin(arg, prec), prec)
        v = k + v % k
        if v % p == 0:
            if e == 1:
                return mpf_mul(
                    from_int(jacobi_symbol(3, k)),
                    mpf_sqrt(from_int(k), prec), prec)
            return fzero
        if not is_quad_residue(v, p):
            return fzero
        _phi = p**(e - 1)*(p - 1)
        v = (v*pow(576, _phi - 1, k))
        m = _sqrt_mod_prime_power(v, p, e)[0]
        arg = mpf_div(
            mpf_mul(from_int(4*m), pi, prec),
            from_int(k), prec)
        return mpf_mul(mpf_mul(
            from_int(2*jacobi_symbol(3, k)),
            mpf_sqrt(from_int(k), prec), prec),
            mpf_cos(arg, prec), prec)

    if p != 2 or e >= 3:
        d1, d2 = igcd(k1, 24), igcd(k2, 24)
        e = 24//(d1*d2)
        n1 = ((d2*e*n + (k2**2 - 1)//d1)*
            pow(e*k2*k2*d2, _totient[k1] - 1, k1)) % k1
        n2 = ((d1*e*n + (k1**2 - 1)//d2)*
            pow(e*k1*k1*d1, _totient[k2] - 1, k2)) % k2
        return mpf_mul(_a(n1, k1, prec), _a(n2, k2, prec), prec)
    if e == 2:
        n1 = ((8*n + 5)*pow(128, _totient[k1] - 1, k1)) % k1
        n2 = (4 + ((n - 2 - (k1**2 - 1)//8)*(k1**2)) % 4) % 4
        return mpf_mul(mpf_mul(
            from_int(-1),
            _a(n1, k1, prec), prec),
            _a(n2, k2, prec))
    n1 = ((8*n + 1)*pow(32, _totient[k1] - 1, k1)) % k1
    n2 = (2 + (n - (k1**2 - 1)//8) % 2) % 2
    return mpf_mul(_a(n1, k1, prec), _a(n2, k2, prec), prec)
コード例 #15
0
def _a(n, k, prec):
    """ Compute the inner sum in HRR formula [1]_

    References
    ==========

    .. [1] http://msp.org/pjm/1956/6-1/pjm-v6-n1-p18-p.pdf

    """
    if k == 1:
        return fone

    k1 = k
    e = 0
    p = _factor[k]
    while k1 % p == 0:
        k1 //= p
        e += 1
    k2 = k // k1  # k2 = p^e
    v = 1 - 24 * n
    pi = mpf_pi(prec)

    if k1 == 1:
        # k  = p^e
        if p == 2:
            mod = 8 * k
            v = mod + v % mod
            v = (v * pow(9, k - 1, mod)) % mod
            m = _sqrt_mod_prime_power(v, 2, e + 3)[0]
            arg = mpf_div(mpf_mul(from_int(4 * m), pi, prec), from_int(mod),
                          prec)
            return mpf_mul(
                mpf_mul(from_int((-1)**e * jacobi_symbol(m - 1, m)),
                        mpf_sqrt(from_int(k), prec), prec), mpf_sin(arg, prec),
                prec)
        if p == 3:
            mod = 3 * k
            v = mod + v % mod
            if e > 1:
                v = (v * pow(64, k // 3 - 1, mod)) % mod
            m = _sqrt_mod_prime_power(v, 3, e + 1)[0]
            arg = mpf_div(mpf_mul(from_int(4 * m), pi, prec), from_int(mod),
                          prec)
            return mpf_mul(
                mpf_mul(from_int(2 * (-1)**(e + 1) * legendre_symbol(m, 3)),
                        mpf_sqrt(from_int(k // 3), prec), prec),
                mpf_sin(arg, prec), prec)
        v = k + v % k
        if v % p == 0:
            if e == 1:
                return mpf_mul(from_int(jacobi_symbol(3, k)),
                               mpf_sqrt(from_int(k), prec), prec)
            return fzero
        if not is_quad_residue(v, p):
            return fzero
        _phi = p**(e - 1) * (p - 1)
        v = (v * pow(576, _phi - 1, k))
        m = _sqrt_mod_prime_power(v, p, e)[0]
        arg = mpf_div(mpf_mul(from_int(4 * m), pi, prec), from_int(k), prec)
        return mpf_mul(
            mpf_mul(from_int(2 * jacobi_symbol(3, k)),
                    mpf_sqrt(from_int(k), prec), prec), mpf_cos(arg, prec),
            prec)

    if p != 2 or e >= 3:
        d1, d2 = igcd(k1, 24), igcd(k2, 24)
        e = 24 // (d1 * d2)
        n1 = ((d2 * e * n + (k2**2 - 1) // d1) *
              pow(e * k2 * k2 * d2, _totient[k1] - 1, k1)) % k1
        n2 = ((d1 * e * n + (k1**2 - 1) // d2) *
              pow(e * k1 * k1 * d1, _totient[k2] - 1, k2)) % k2
        return mpf_mul(_a(n1, k1, prec), _a(n2, k2, prec), prec)
    if e == 2:
        n1 = ((8 * n + 5) * pow(128, _totient[k1] - 1, k1)) % k1
        n2 = (4 + ((n - 2 - (k1**2 - 1) // 8) * (k1**2)) % 4) % 4
        return mpf_mul(mpf_mul(from_int(-1), _a(n1, k1, prec), prec),
                       _a(n2, k2, prec))
    n1 = ((8 * n + 1) * pow(32, _totient[k1] - 1, k1)) % k1
    n2 = (2 + (n - (k1**2 - 1) // 8) % 2) % 2
    return mpf_mul(_a(n1, k1, prec), _a(n2, k2, prec), prec)