Example #1
0
def eval_hyp2f1(a,b,c,z):
    prec, rnd = prec_rounding
    ar, af, ac = parse_param(a)
    br, bf, bc = parse_param(b)
    cr, cf, cc = parse_param(c)
    absz = abs(z)
    if absz == 1:
        # TODO: determine whether it actually does, and otherwise
        # return infinity instead
        print "Warning: 2F1 might not converge for |z| = 1"
    if absz <= 1:
        # All rational
        if ar and br and cr:
            return sum_hyp2f1_rat(ar[0], br[0], cr[0], z)
        return hypsum(ar+br, af+bf, ac+bc, cr, cf, cc, z)
    # Use 1/z transformation
    a = (ar and _as_num(ar[0])) or convert_lossless(a)
    b = (br and _as_num(br[0])) or convert_lossless(b)
    c = (cr and _as_num(cr[0])) or convert_lossless(c)
    orig = mp.prec
    try:
        mp.prec = orig + 15
        h1 = eval_hyp2f1(a, mpq_1-c+a, mpq_1-b+a, 1/z)
        h2 = eval_hyp2f1(b, mpq_1-c+b, mpq_1-a+b, 1/z)
        #s1 = G(c)*G(b-a)/G(b)/G(c-a) * (-z)**(-a) * h1
        #s2 = G(c)*G(a-b)/G(a)/G(c-b) * (-z)**(-b) * h2
        f1 = gammaprod([c,b-a],[b,c-a])
        f2 = gammaprod([c,a-b],[a,c-b])
        s1 = f1 * (-z)**(mpq_0-a) * h1
        s2 = f2 * (-z)**(mpq_0-b) * h2
        v = s1 + s2
    finally:
        mp.prec = orig
    return +v
Example #2
0
def jacobi_elliptic_cn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.2.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_cn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:                   # cn collapses to cos(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 0'
        return cos(u)
    elif m == one:                  # cn collapses to sech(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 1'
        return sech(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        v = (pi * u) / (two*ellipk(k**2))

    sum = zero
    term = zero                     # series starts at zero

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_cn: calculating'
    while True:
        factor1 = (q**(term + onehalf)) / (one + q**(two*term + one))
        factor2 = cos((two*term + one)*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two*pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Example #3
0
def jacobi_theta_3(z, m):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    delta_sum = 1
    term = 1                    # series starts at 1

    zero = mpf('0')
    sum = zero

    if z == zero:
        factor2 = mpf('1')
        while True:

            factor1 = q**(term*term)
            term_n = factor1                # suboptimal, kept for readability
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1

    else:
        while True:
            factor1 = q**(term*term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2*term*z)

            term_n = factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            if factor2 != mpf('0'):      # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2*sum
Example #4
0
def jacobi_theta_3(z, m):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    delta_sum = 1
    term = 1  # series starts at 1

    zero = mpf('0')
    sum = zero

    if z == zero:
        factor2 = mpf('1')
        while True:

            factor1 = q**(term * term)
            term_n = factor1  # suboptimal, kept for readability
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1

    else:
        while True:
            factor1 = q**(term * term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2 * term * z)

            term_n = factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            if factor2 != mpf('0'):  # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2 * sum
Example #5
0
def jacobi_elliptic_cn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.2.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_cn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # cn collapses to cos(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 0'
        return cos(u)
    elif m == one:  # cn collapses to sech(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 1'
        return sech(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        v = (pi * u) / (two * ellipk(k**2))

    sum = zero
    term = zero  # series starts at zero

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_cn: calculating'
    while True:
        factor1 = (q**(term + onehalf)) / (one + q**(two * term + one))
        factor2 = cos((two * term + one) * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two * pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Example #6
0
def eval_hyp2f1(a, b, c, z):
    prec, rnd = prec_rounding
    ar, af, ac = parse_param(a)
    br, bf, bc = parse_param(b)
    cr, cf, cc = parse_param(c)
    absz = abs(z)
    if absz == 1:
        # TODO: determine whether it actually does, and otherwise
        # return infinity instead
        print "Warning: 2F1 might not converge for |z| = 1"
    if absz <= 1:
        # All rational
        if ar and br and cr:
            return sum_hyp2f1_rat(ar[0], br[0], cr[0], z)
        return hypsum(ar + br, af + bf, ac + bc, cr, cf, cc, z)
    # Use 1/z transformation
    a = (ar and _as_num(ar[0])) or convert_lossless(a)
    b = (br and _as_num(br[0])) or convert_lossless(b)
    c = (cr and _as_num(cr[0])) or convert_lossless(c)
    orig = mp.prec
    try:
        mp.prec = orig + 15
        h1 = eval_hyp2f1(a, mpq_1 - c + a, mpq_1 - b + a, 1 / z)
        h2 = eval_hyp2f1(b, mpq_1 - c + b, mpq_1 - a + b, 1 / z)
        #s1 = G(c)*G(b-a)/G(b)/G(c-a) * (-z)**(-a) * h1
        #s2 = G(c)*G(a-b)/G(a)/G(c-b) * (-z)**(-b) * h2
        f1 = gammaprod([c, b - a], [b, c - a])
        f2 = gammaprod([c, a - b], [a, c - b])
        s1 = f1 * (-z)**(mpq_0 - a) * h1
        s2 = f2 * (-z)**(mpq_0 - b) * h2
        v = s1 + s2
    finally:
        mp.prec = orig
    return +v
Example #7
0
def jacobi_elliptic_dn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.3.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_dn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:           # dn collapes to 1
        return one
    elif m == one:          # dn collapses to sech(u)
        return sech(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two*ellipk(k**2))

    sum = zero
    term = one                  # series starts at one

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_dn: calculating'
    while True:
        factor1 = (q**term) / (one + q**(two*term))
        factor2 = cos(two*term*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    K = ellipk(k**2)
    answer = (pi / (two*K)) + (two*pi*sum)/(ellipk(k**2))

    return answer
Example #8
0
def jacobi_elliptic_dn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.3.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_dn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # dn collapes to 1
        return one
    elif m == one:  # dn collapses to sech(u)
        return sech(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two * ellipk(k**2))

    sum = zero
    term = one  # series starts at one

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_dn: calculating'
    while True:
        factor1 = (q**term) / (one + q**(two * term))
        factor2 = cos(two * term * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    K = ellipk(k**2)
    answer = (pi / (two * K)) + (two * pi * sum) / (ellipk(k**2))

    return answer
Example #9
0
def transform(f, a, b):
    """
    Given an integrand f defined over the interval [a, b], return an
    equivalent integrand g defined on the standard interval [-1, 1].

    If a and b are finite, this is achived by means of a linear change
    of variables. If at least one point is infinite, the substitution
    t = 1/x is used.
    """
    a = convert_lossless(a)
    b = convert_lossless(b)
    if (a, b) == (-1, 1):
        return f
    one = mpf(1)
    half = mpf(0.5)
    # The transformation 1/x sends [1, inf] to [0, 1], which in turn
    # can be transformed to [-1, 1] the usual way. For a double
    # infinite interval, we simply evaluate the function symmetrically
    if (a, b) == (-inf, inf):
        # return transform(lambda x: (f(-1/x+1)+f(1/x-1))/x**2, 0, 1)
        def y(x):
            u = 2 / (x + one)
            w = one - u
            return half * (f(w) + f(-w)) * u**2

        return y
    if a == -inf:
        # return transform(lambda x: f(-1/x+b+1)/x**2, 0, 1)
        b1 = b + 1

        def y(x):
            u = 2 / (x + one)
            return half * f(b1 - u) * u**2

        return y
    if b == inf:
        # return transform(lambda x: f(1/x+a-1)/x**2, 0, 1)
        a1 = a - 1

        def y(x):
            u = 2 / (x + one)
            return half * f(a1 + u) * u**2

        return y
    # Simple linear change of variables
    C = (b - a) / 2
    D = (b + a) / 2

    def g(x):
        return C * f(D + C * x)

    return g
Example #10
0
def calculate_nome(k):
    """
    Calculate the nome, q, from the value for k.

    Useful factoids:

    k**2 = m;   m is used in Abramowitz
    """
    k = convert_lossless(k)

    if k > mpf('1'):             # range error
        raise ValueError

    zero = mpf('0')
    one = mpf('1')

    if k == zero:
        return zero
    elif k == one:
        return one
    else:
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        top = ellipk(kprimesquared)
        bottom = ellipk(k**2)

        argument = mpf('-1')*pi*top/bottom

        nome = exp(argument)
        return nome
Example #11
0
def npdf(x, mu=0, sigma=1):
    """
    npdf(x, mu=0, sigma=1) -- probability density function of a
    normal distribution with mean value mu and variance sigma^2.
    """
    sigma = convert_lossless(sigma)
    return exp(-(x-mu)**2/(2*sigma**2)) / (sigma*sqrt(2*pi))
Example #12
0
def calculate_k(q, verbose=False):
    """
    Calculates the value of k for a particular nome, q.

    Uses special cases of the jacobi theta functions, with
    q as an argument, rather than m.

    k = (v2(0, q)/v3(0, q))**2
    """
    zero = mpf('0')
    one = mpf('1')

    q = convert_lossless(q)
    if q > one or q < zero:
        raise ValueError

    # calculate v2(0, q)
    sum = zero
    term = zero                     # series starts at zero
    while True:
        factor1 = q**(term*(term + 1))
        term_n = factor1            # suboptimal, kept for readability
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if factor1 == zero:         # all further terms will be zero
            break
        #if log(term_n, '10') < -1*mpf.dps:
        if abs(term_n) < eps:
            break

        term = term + 1

    v2 = 2*q**(mpf('0.25'))*sum

    # calculate v3(0, q)
    sum = zero
    term = one                          # series starts at one
    while True:
        factor1 = q**(term*term)
        term_n = factor1                # suboptimal, kept for readability
        sum = sum + term_n

        if factor1 == mpf('0'):      # all further terms will be zero
            break
        #if log(term_n, '10') < -1*mpf.dps:
        if abs(term_n) < eps:
            break

        term = term + 1

    v3 = one + 2*sum

    k = v2**2/v3**2

    return k
Example #13
0
def npdf(x, mu=0, sigma=1):
    """
    npdf(x, mu=0, sigma=1) -- probability density function of a
    normal distribution with mean value mu and variance sigma^2.
    """
    sigma = convert_lossless(sigma)
    return exp(-(x - mu)**2 / (2 * sigma**2)) / (sigma * sqrt(2 * pi))
Example #14
0
def calculate_nome(k):
    """
    Calculate the nome, q, from the value for k.

    Useful factoids:

    k**2 = m;   m is used in Abramowitz
    """
    k = convert_lossless(k)

    if k > mpf('1'):  # range error
        raise ValueError

    zero = mpf('0')
    one = mpf('1')

    if k == zero:
        return zero
    elif k == one:
        return one
    else:
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        top = ellipk(kprimesquared)
        bottom = ellipk(k**2)

        argument = mpf('-1') * pi * top / bottom

        nome = exp(argument)
        return nome
Example #15
0
def calculate_k(q, verbose=False):
    """
    Calculates the value of k for a particular nome, q.

    Uses special cases of the jacobi theta functions, with
    q as an argument, rather than m.

    k = (v2(0, q)/v3(0, q))**2
    """
    zero = mpf('0')
    one = mpf('1')

    q = convert_lossless(q)
    if q > one or q < zero:
        raise ValueError

    # calculate v2(0, q)
    sum = zero
    term = zero  # series starts at zero
    while True:
        factor1 = q**(term * (term + 1))
        term_n = factor1  # suboptimal, kept for readability
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if factor1 == zero:  # all further terms will be zero
            break
        #if log(term_n, '10') < -1*mpf.dps:
        if abs(term_n) < eps:
            break

        term = term + 1

    v2 = 2 * q**(mpf('0.25')) * sum

    # calculate v3(0, q)
    sum = zero
    term = one  # series starts at one
    while True:
        factor1 = q**(term * term)
        term_n = factor1  # suboptimal, kept for readability
        sum = sum + term_n

        if factor1 == mpf('0'):  # all further terms will be zero
            break
        #if log(term_n, '10') < -1*mpf.dps:
        if abs(term_n) < eps:
            break

        term = term + 1

    v3 = one + 2 * sum

    k = v2**2 / v3**2

    return k
Example #16
0
def sign(x):
    """Return sign(x), defined as x/abs(x), or 0 for x = 0."""
    x = convert_lossless(x)
    if not x or isnan(x):
        return x
    if isinstance(x, mpf):
        return cmp(x, 0)
    return x / abs(x)
Example #17
0
def sign(x):
    """Return sign(x), defined as x/abs(x), or 0 for x = 0."""
    x = convert_lossless(x)
    if not x or isnan(x):
        return x
    if isinstance(x, mpf):
        return cmp(x, 0)
    return x / abs(x)
Example #18
0
def transform(f, a, b):
    """
    Given an integrand f defined over the interval [a, b], return an
    equivalent integrand g defined on the standard interval [-1, 1].

    If a and b are finite, this is achived by means of a linear change
    of variables. If at least one point is infinite, the substitution
    t = 1/x is used.
    """
    a = convert_lossless(a)
    b = convert_lossless(b)
    if (a, b) == (-1, 1):
        return f
    one = mpf(1)
    half = mpf(0.5)
    # The transformation 1/x sends [1, inf] to [0, 1], which in turn
    # can be transformed to [-1, 1] the usual way. For a double
    # infinite interval, we simply evaluate the function symmetrically
    if (a, b) == (-inf, inf):
        # return transform(lambda x: (f(-1/x+1)+f(1/x-1))/x**2, 0, 1)
        def y(x):
            u = 2/(x+one)
            w = one - u
            return half * (f(w)+f(-w)) * u**2
        return y
    if a == -inf:
        # return transform(lambda x: f(-1/x+b+1)/x**2, 0, 1)
        b1 = b+1
        def y(x):
            u = 2/(x+one)
            return half * f(b1-u) * u**2
        return y
    if b == inf:
        # return transform(lambda x: f(1/x+a-1)/x**2, 0, 1)
        a1 = a-1
        def y(x):
            u = 2/(x+one)
            return half * f(a1+u) * u**2
        return y
    # Simple linear change of variables
    C = (b-a)/2
    D = (b+a)/2
    def g(x):
        return C * f(D + C*x)
    return g
Example #19
0
 def g(*args, **kwargs):
     orig = mp.prec
     try:
         args = [convert_lossless(z) for z in args]
         mp.prec = orig + 10
         v = f(*args, **kwargs)
     finally:
         mp.prec = orig
     return +v
Example #20
0
 def g(*args, **kwargs):
     orig = mp.prec
     try:
         args = [convert_lossless(z) for z in args]
         mp.prec = orig + 10
         v = f(*args, **kwargs)
     finally:
         mp.prec = orig
     return +v
Example #21
0
def parse_param(x):
    if isinstance(x, tuple):
        p, q = x
        return [[p, q]], [], []
    if isinstance(x, (int, long)):
        return [[x, 1]], [], []
    x = convert_lossless(x)
    if isinstance(x, mpf):
        return [], [x._mpf_], []
    if isinstance(x, mpc):
        return [], [], [x._mpc_]
Example #22
0
def parse_param(x):
    if isinstance(x, tuple):
        p, q = x
        return [[p, q]], [], []
    if isinstance(x, (int, long)):
        return [[x, 1]], [], []
    x = convert_lossless(x)
    if isinstance(x, mpf):
        return [], [x._mpf_], []
    if isinstance(x, mpc):
        return [], [], [x._mpc_]
Example #23
0
def quadosc(f, interval, period=None, zeros=None, alt=1):
    """
    Integrates f(x) over interval = [a, b] where at least one of a and
    b is infinite and f is a slowly decaying oscillatory function. The
    zeros of f must be provided, either by specifying a period (suitable
    when f contains a pure sine or cosine factor) or providing a function
    that returns the nth zero (suitable when the oscillation is not
    strictly periodic).
    """
    a, b = AS_POINTS(interval)
    a = convert_lossless(a)
    b = convert_lossless(b)
    if period is None and zeros is None:
        raise ValueError( \
            "either the period or zeros keyword parameter must be specified")
    if a == -inf and b == inf:
        s1 = quadosc(f, [a, 0], zeros=zeros, period=period, alt=alt)
        s2 = quadosc(f, [0, b], zeros=zeros, period=period, alt=alt)
        return s1 + s2
    if a == -inf:
        if zeros:
            return quadosc(lambda x:f(-x), [-b,-a], lambda n: zeros(-n), alt=alt)
        else:
            return quadosc(lambda x:f(-x), [-b,-a], period=period, alt=alt)
    if b != inf:
        raise ValueError("quadosc requires an infinite integration interval")
    if not zeros:
        zeros = lambda n: n*period/2
    for n in range(1,10):
        p = zeros(n)
        if p > a:
            break
    if n >= 9:
        raise ValueError("zeros do not appear to be correctly indexed")
    if alt == 0:
        s = quadgl(f, [a, zeros(n+1)])
        s += sumrich(lambda k: quadgl(f, [zeros(2*k), zeros(2*k+2)]), [n, inf])
    else:
        s = quadgl(f, [a, zeros(n)])
        s += sumsh(lambda k: quadgl(f, [zeros(k), zeros(k+1)]), [n, inf])
    return s
Example #24
0
def gammaprod(a, b):
    """
    Computes the product / quotient of gamma functions

        G(a_0) G(a_1) ... G(a_p)
        ------------------------
        G(b_0) G(b_1) ... G(a_q)

    with proper cancellation of poles (interpreting the expression as a
    limit). Returns +inf if the limit diverges.
    """
    a = [convert_lossless(x) for x in a]
    b = [convert_lossless(x) for x in b]
    poles_num = []
    poles_den = []
    regular_num = []
    regular_den = []
    for x in a:
        [regular_num, poles_num][isnpint(x)].append(x)
    for x in b:
        [regular_den, poles_den][isnpint(x)].append(x)
    # One more pole in numerator or denominator gives 0 or inf
    if len(poles_num) < len(poles_den): return mpf(0)
    if len(poles_num) > len(poles_den): return mpf('+inf')
    # All poles cancel
    # lim G(i)/G(j) = (-1)**(i+j) * gamma(1-j) / gamma(1-i)
    p = mpf(1)
    orig = mp.prec
    try:
        mp.prec = orig + 15
        while poles_num:
            i = poles_num.pop()
            j = poles_den.pop()
            p *= (-1)**(i + j) * gamma(1 - j) / gamma(1 - i)
        for x in regular_num:
            p *= gamma(x)
        for x in regular_den:
            p /= gamma(x)
    finally:
        mp.prec = orig
    return +p
Example #25
0
def psi(m, z):
    """
    Gives the polygamma function of order m of z, psi^(m)(z). Special
    cases are the digamma function (psi0), trigamma function (psi1),
    tetragamma (psi2) and pentagamma (psi4) functions.

    The parameter m should be a nonnegative integer.
    """
    z = convert_lossless(z)
    m = int(m)
    if isinstance(z, mpf):
        return make_mpf(gammazeta.mpf_psi(m, z._mpf_, *prec_rounding))
    else:
        return make_mpc(gammazeta.mpc_psi(m, z._mpc_, *prec_rounding))
Example #26
0
def psi(m, z):
    """
    Gives the polygamma function of order m of z, psi^(m)(z). Special
    cases are the digamma function (psi0), trigamma function (psi1),
    tetragamma (psi2) and pentagamma (psi4) functions.

    The parameter m should be a nonnegative integer.
    """
    z = convert_lossless(z)
    m = int(m)
    if isinstance(z, mpf):
        return make_mpf(gammazeta.mpf_psi(m, z._mpf_, *prec_rounding))
    else:
        return make_mpc(gammazeta.mpc_psi(m, z._mpc_, *prec_rounding))
Example #27
0
def gammaprod(a, b):
    """
    Computes the product / quotient of gamma functions

        G(a_0) G(a_1) ... G(a_p)
        ------------------------
        G(b_0) G(b_1) ... G(a_q)

    with proper cancellation of poles (interpreting the expression as a
    limit). Returns +inf if the limit diverges.
    """
    a = [convert_lossless(x) for x in a]
    b = [convert_lossless(x) for x in b]
    poles_num = []
    poles_den = []
    regular_num = []
    regular_den = []
    for x in a: [regular_num, poles_num][isnpint(x)].append(x)
    for x in b: [regular_den, poles_den][isnpint(x)].append(x)
    # One more pole in numerator or denominator gives 0 or inf
    if len(poles_num) < len(poles_den): return mpf(0)
    if len(poles_num) > len(poles_den): return mpf('+inf')
    # All poles cancel
    # lim G(i)/G(j) = (-1)**(i+j) * gamma(1-j) / gamma(1-i)
    p = mpf(1)
    orig = mp.prec
    try:
        mp.prec = orig + 15
        while poles_num:
            i = poles_num.pop()
            j = poles_den.pop()
            p *= (-1)**(i+j) * gamma(1-j) / gamma(1-i)
        for x in regular_num: p *= gamma(x)
        for x in regular_den: p /= gamma(x)
    finally:
        mp.prec = orig
    return +p
Example #28
0
def hyper(a_s, b_s, z):
    """
    Hypergeometric function pFq,

          [ a_1, a_2, ..., a_p |    ]
      pFq [                    |  z ]
          [ b_1, b_2, ..., b_q |    ]

    The parameter lists a_s and b_s may contain real or complex numbers.
    Exact rational parameters can be given as tuples (p, q).
    """
    p = len(a_s)
    q = len(b_s)
    z = convert_lossless(z)
    degree = p, q
    if degree == (0, 1):
        br, bf, bc = parse_param(b_s[0])
        if br:
            return sum_hyp0f1_rat(br[0], z)
        return hypsum([], [], [], br, bf, bc, z)
    if degree == (1, 1):
        ar, af, ac = parse_param(a_s[0])
        br, bf, bc = parse_param(b_s[0])
        if ar and br:
            a, b = ar[0], br[0]
            return sum_hyp1f1_rat(a, b, z)
        return hypsum(ar, af, ac, br, bf, bc, z)
    if degree == (2, 1):
        return eval_hyp2f1(a_s[0], a_s[1], b_s[0], z)
    ars, afs, acs, brs, bfs, bcs = [], [], [], [], [], []
    for a in a_s:
        r, f, c = parse_param(a)
        ars += r
        afs += f
        acs += c
    for b in b_s:
        r, f, c = parse_param(b)
        brs += r
        bfs += f
        bcs += c
    return hypsum(ars, afs, acs, brs, bfs, bcs, z)
Example #29
0
def hyper(a_s, b_s, z):
    """
    Hypergeometric function pFq,

          [ a_1, a_2, ..., a_p |    ]
      pFq [                    |  z ]
          [ b_1, b_2, ..., b_q |    ]

    The parameter lists a_s and b_s may contain real or complex numbers.
    Exact rational parameters can be given as tuples (p, q).
    """
    p = len(a_s)
    q = len(b_s)
    z = convert_lossless(z)
    degree = p, q
    if degree == (0, 1):
        br, bf, bc = parse_param(b_s[0])
        if br:
            return sum_hyp0f1_rat(br[0], z)
        return hypsum([], [], [], br, bf, bc, z)
    if degree == (1, 1):
        ar, af, ac = parse_param(a_s[0])
        br, bf, bc = parse_param(b_s[0])
        if ar and br:
            a, b = ar[0], br[0]
            return sum_hyp1f1_rat(a, b, z)
        return hypsum(ar, af, ac, br, bf, bc, z)
    if degree == (2, 1):
        return eval_hyp2f1(a_s[0], a_s[1], b_s[0], z)
    ars, afs, acs, brs, bfs, bcs = [], [], [], [], [], []
    for a in a_s:
        r, f, c = parse_param(a)
        ars += r
        afs += f
        acs += c
    for b in b_s:
        r, f, c = parse_param(b)
        brs += r
        bfs += f
        bcs += c
    return hypsum(ars, afs, acs, brs, bfs, bcs, z)
Example #30
0
 def f(x, **kwargs):
     if not isinstance(x, mpnumeric):
         x = convert_lossless(x)
     prec, rounding = prec_rounding
     if kwargs:
         prec = kwargs.get('prec', prec)
         if 'dps' in kwargs:
             prec = dps_to_prec(kwargs['dps'])
         rounding = kwargs.get('rounding', rounding)
     if isinstance(x, mpf):
         try:
             return make_mpf(real_f(x._mpf_, prec, rounding))
         except ComplexResult:
             # Handle propagation to complex
             if mp.trap_complex:
                 raise
             return make_mpc(complex_f((x._mpf_, libmpf.fzero), prec, rounding))
     elif isinstance(x, mpc):
         return make_mpc(complex_f(x._mpc_, prec, rounding))
     elif isinstance(x, mpi):
         if interval_f:
             return make_mpi(interval_f(x._val, prec))
     raise NotImplementedError("%s of a %s" % (name, type(x)))
Example #31
0
 def f(x, **kwargs):
     if not isinstance(x, mpnumeric):
         x = convert_lossless(x)
     prec, rounding = prec_rounding
     if kwargs:
         prec = kwargs.get('prec', prec)
         if 'dps' in kwargs:
             prec = dps_to_prec(kwargs['dps'])
         rounding = kwargs.get('rounding', rounding)
     if isinstance(x, mpf):
         try:
             return make_mpf(real_f(x._mpf_, prec, rounding))
         except ComplexResult:
             # Handle propagation to complex
             if mp.trap_complex:
                 raise
             return make_mpc(
                 complex_f((x._mpf_, libmpf.fzero), prec, rounding))
     elif isinstance(x, mpc):
         return make_mpc(complex_f(x._mpc_, prec, rounding))
     elif isinstance(x, mpi):
         if interval_f:
             return make_mpi(interval_f(x._val, prec))
     raise NotImplementedError("%s of a %s" % (name, type(x)))
Example #32
0
def power(x, y):
    """Converts x and y to mpf or mpc and returns x**y = exp(y*log(x))."""
    return convert_lossless(x)**convert_lossless(y)
Example #33
0
def jacobi_elliptic_sn(u, m, verbose=False):
    """
    Implements the jacobi elliptic sn function, using the expansion in
    terms of q, from Abramowitz 16.23.1.

    u is any complex number, m is the parameter

    Alternative implementation:

    Expansion in terms of jacobi theta functions appears to fail with
    round off error, despite   I also think that the expansion in
    terms of q is much faster than four expansions in terms of q.

    **********************************
    Previous implementation kept here:

    if not isinstance(u, mpf):
        raise TypeError
    if not isinstance(m, mpf):
        raise TypeError

    zero = mpf('0')

    if u == zero and m == 0:
        return zero
    else:
        q = calculate_nome(sqrt(m))

        v3 = jacobi_theta_3(zero, q)
        v2 = jacobi_theta_2(zero, q)        # mathworld says v4

        arg1 = u / (v3*v3)

        v1 = jacobi_theta_1(arg1, q)
        v4 = jacobi_theta_4(arg1, q)

        sn = (v3/v2)*(v1/v4)

        return sn
    **********************************
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_sn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:           # sn collapes to sin(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 0'
        return sin(u)
    elif m == one:          # sn collapses to tanh(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 1'
        return tanh(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two*ellipk(k**2))

    if v == pi or v == zero:     # sin factor always zero
        return zero

    sum = zero
    term = zero                     # series starts at zero

    while True:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_elliptic_sn: calculating'
        factor1 = (q**(term + onehalf)) / (one - q**(two*term + one))
        factor2 = sin((two*term + one)*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two*pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Example #34
0
def jacobi_theta_4(z, m):
    """
    Implements the series expansion of the jacobi theta function
    1, where z == 0.

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    delta_sum = 1
    term = 1                    # series starts at 1

    zero = mpf('0')

    if z == zero:
        factor2 = mpf('1')
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term*term)
            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1
    else:
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term*term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2*term*z)

            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            if factor2 != mpf('0'):      # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2*sum
Example #35
0
def hypot(x, y):
    """Returns the Euclidean distance sqrt(x*x + y*y). Both x and y
    must be real."""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return make_mpf(libmpf.mpf_hypot(x._mpf_, y._mpf_, *prec_rounding))
Example #36
0
def jacobi_elliptic_sn(u, m, verbose=False):
    """
    Implements the jacobi elliptic sn function, using the expansion in
    terms of q, from Abramowitz 16.23.1.

    u is any complex number, m is the parameter

    Alternative implementation:

    Expansion in terms of jacobi theta functions appears to fail with
    round off error, despite   I also think that the expansion in
    terms of q is much faster than four expansions in terms of q.

    **********************************
    Previous implementation kept here:

    if not isinstance(u, mpf):
        raise TypeError
    if not isinstance(m, mpf):
        raise TypeError

    zero = mpf('0')

    if u == zero and m == 0:
        return zero
    else:
        q = calculate_nome(sqrt(m))

        v3 = jacobi_theta_3(zero, q)
        v2 = jacobi_theta_2(zero, q)        # mathworld says v4

        arg1 = u / (v3*v3)

        v1 = jacobi_theta_1(arg1, q)
        v4 = jacobi_theta_4(arg1, q)

        sn = (v3/v2)*(v1/v4)

        return sn
    **********************************
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_sn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # sn collapes to sin(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 0'
        return sin(u)
    elif m == one:  # sn collapses to tanh(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 1'
        return tanh(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two * ellipk(k**2))

    if v == pi or v == zero:  # sin factor always zero
        return zero

    sum = zero
    term = zero  # series starts at zero

    while True:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_elliptic_sn: calculating'
        factor1 = (q**(term + onehalf)) / (one - q**(two * term + one))
        factor2 = sin((two * term + one) * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two * pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Example #37
0
def frexp(x):
    """Convert x to a scaled number y in the range [0.5, 1). Returns
    (y, n) such that x = y * 2**n. No rounding is performed."""
    x = convert_lossless(x)
    y, n = libmpf.mpf_frexp(x._mpf_)
    return make_mpf(y), n
Example #38
0
def jacobi_theta_2(z, m, verbose=False):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_theta_2'

    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if verbose:
        print >> sys.stderr, '\tk: %f ' % k
        print >> sys.stderr, '\tq: %f ' % q

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    term = 0  # series starts at zero

    zero = mpf('0')

    if q == zero:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: q == 0, return 0'
        return zero
    else:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: calculating'
        if z == zero:
            factor2 = mpf('1')
            while True:
                factor1 = q**(term * (term + 1))
                term_n = factor1  # suboptimal, kept for readability
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:  # all further terms will be zero
                    break
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

                term = term + 1
        else:
            while True:
                factor1 = q**(term * (term + 1))
                if z == zero:
                    factor2 = 1
                else:
                    factor2 = cos((2 * term + 1) * z)

                term_n = factor1 * factor2
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:  # all further terms will be zero
                    break
                if factor2 != zero:  # check precision iff cos != 0
                    #if log(term_n, '10') < -1*mpf.dps:
                    if abs(term_n) < eps:
                        break

                term = term + 1

        return (2 * q**(0.25)) * sum

    # can't get here
    print >> sys.stderr, 'elliptic.jacobi_theta_2 in impossible state'
    sys.exit(2)
Example #39
0
def hypot(x, y):
    """Returns the Euclidean distance sqrt(x*x + y*y). Both x and y
    must be real."""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return make_mpf(libmpf.mpf_hypot(x._mpf_, y._mpf_, *prec_rounding))
Example #40
0
def ldexp(x, n):
    """Calculate mpf(x) * 2**n efficiently. No rounding is performed."""
    x = convert_lossless(x)
    return make_mpf(libmpf.mpf_shift(x._mpf_, n))
Example #41
0
def frexp(x):
    """Convert x to a scaled number y in the range [0.5, 1). Returns
    (y, n) such that x = y * 2**n. No rounding is performed."""
    x = convert_lossless(x)
    y, n = libmpf.mpf_frexp(x._mpf_)
    return make_mpf(y), n
Example #42
0
def power(x, y):
    """Converts x and y to mpf or mpc and returns x**y = exp(y*log(x))."""
    return convert_lossless(x) ** convert_lossless(y)
Example #43
0
def jacobi_theta_2(z, m, verbose=False):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_theta_2'

    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if verbose:
        print >> sys.stderr, '\tk: %f ' % k
        print >> sys.stderr, '\tq: %f ' % q

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    term = 0                    # series starts at zero

    zero = mpf('0')

    if q == zero:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: q == 0, return 0'
        return zero
    else:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: calculating'
        if z == zero:
            factor2 = mpf('1')
            while True:
                factor1 = q**(term*(term + 1))
                term_n = factor1            # suboptimal, kept for readability
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:         # all further terms will be zero
                    break
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

                term = term + 1
        else:
            while True:
                factor1 = q**(term*(term + 1))
                if z == zero:
                    factor2 = 1
                else:
                    factor2 = cos((2*term + 1)*z)

                term_n = factor1 * factor2
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:         # all further terms will be zero
                    break
                if factor2 != zero:         # check precision iff cos != 0
                    #if log(term_n, '10') < -1*mpf.dps:
                    if abs(term_n) < eps:
                        break

                term = term + 1

        return (2*q**(0.25))*sum

    # can't get here
    print >> sys.stderr, 'elliptic.jacobi_theta_2 in impossible state'
    sys.exit(2)
Example #44
0
def polyroots(coeffs, maxsteps=50, cleanup=True, extraprec=10, error=False):
    """
    Numerically locate all (complex) roots of a polynomial using the
    Durand-Kerner method.

    With error=True, this function returns a tuple (roots, err) where roots
    is a list of complex numbers sorted by absolute value, and err is an
    estimate of the maximum error. The polynomial should be given as a list
    of coefficients, in the same format as accepted by polyval(). The
    leading coefficient must be nonzero.

    These are the roots of x^3 - x^2 - 14*x + 24 and 4x^2 + 3x + 2:

        >>> nprint(polyroots([1,-1,-14,24]), 4)
        [-4.0, 2.0, 3.0]
        >>> nprint(polyroots([4,3,2], error=True))
        ([(-0.375 - 0.599479j), (-0.375 + 0.599479j)], 2.22045e-16)

    """
    if len(coeffs) <= 1:
        if not coeffs or not coeffs[0]:
            raise ValueError("Input to polyroots must not be the zero polynomial")
        # Constant polynomial with no roots
        return []

    orig = mp.prec
    weps = +eps
    try:
        mp.prec += 10
        deg = len(coeffs) - 1
        # Must be monic
        lead = convert_lossless(coeffs[0])
        if lead == 1:
            coeffs = map(convert_lossless, coeffs)
        else:
            coeffs = [c/lead for c in coeffs]
        f = lambda x: polyval(coeffs, x)
        roots = [mpc((0.4+0.9j)**n) for n in xrange(deg)]
        err = [mpf(1) for n in xrange(deg)]
        for step in xrange(maxsteps):
            if max(err).ae(0):
                break
            for i in xrange(deg):
                if not err[i].ae(0):
                    p = roots[i]
                    x = f(p)
                    for j in range(deg):
                        if i != j:
                            try:
                                x /= (p-roots[j])
                            except ZeroDivisionError:
                                continue
                    roots[i] = p - x
                    err[i] = abs(x)
        if cleanup:
            for i in xrange(deg):
                if abs(roots[i].imag) < weps:
                    roots[i] = roots[i].real
                elif abs(roots[i].real) < weps:
                    roots[i] = roots[i].imag * 1j
        roots.sort(key=lambda x: (abs(x.imag), x.real))
    finally:
        mp.prec = orig
    if error:
        err = max(err)
        err = max(err, ldexp(1, -orig+1))
        return [+r for r in roots], +err
    else:
        return [+r for r in roots]
Example #45
0
def jacobi_theta_4(z, m):
    """
    Implements the series expansion of the jacobi theta function
    1, where z == 0.

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    delta_sum = 1
    term = 1  # series starts at 1

    zero = mpf('0')

    if z == zero:
        factor2 = mpf('1')
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term * term)
            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1
    else:
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term * term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2 * term * z)

            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            if factor2 != mpf('0'):  # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2 * sum
Example #46
0
def modf(x, y):
    """Converts x and y to mpf or mpc and returns x % y"""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return x % y
Example #47
0
def ldexp(x, n):
    """Calculate mpf(x) * 2**n efficiently. No rounding is performed."""
    x = convert_lossless(x)
    return make_mpf(libmpf.mpf_shift(x._mpf_, n))
Example #48
0
def modf(x,y):
    """Converts x and y to mpf or mpc and returns x % y"""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return x % y
Example #49
0
def atan2(y,x):
    """atan2(y, x) has the same magnitude as atan(y/x) but accounts for
    the signs of y and x. (Defined for real x and y only.)"""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return make_mpf(libelefun.mpf_atan2(y._mpf_, x._mpf_, *prec_rounding))
Example #50
0
def atan2(y, x):
    """atan2(y, x) has the same magnitude as atan(y/x) but accounts for
    the signs of y and x. (Defined for real x and y only.)"""
    x = convert_lossless(x)
    y = convert_lossless(y)
    return make_mpf(libelefun.mpf_atan2(y._mpf_, x._mpf_, *prec_rounding))