python

时间:2018-03-19 23:19:48

标签: evaluation numerical arbitrary-precision

我需要评估绝对值增加的有限数字和,但是它们是交替的。问题是:绝对值增长太快,并开始累积数值误差。这些函数定义,一个(Gj_full)直接到它而另一个(Gj)递归。 fact_quo是一个简单的阶乘函数。

def fact_quo(n, m=1):

    if (type(n) != int) or (type(m) != int):
        raise TypeError("Arguments must be integers.")
    if (n < 0) or (m < 0):
        raise ValueError("n=" + str(n) + "\t m=" + str(m))
    if (n == 0) or (n == 1) or (n == m):
        return 1
    if (n < m):
        raise ValueError("n=" + str(n) + "\t m=" + str(m))
    f = n
    while n > (m+1):
        n -= 1
        f *= n
    return f

def Gj_full(X, Y, Xl, Yl, j=0, coef=1):

    if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
        raise ValueError
    u = (X - Y + Xl + Yl) // 2
    v = coef * (2 ** (X - Y) * fact_quo(X, Y-j) * fact_quo(u+j, j) * 
         4 ** j * (-1) ** j)
    w = 3 ** (u+j) * fact_quo(X-Y+j)
    den2 = fact_quo(X) * fact_quo(Xl) * fact_quo(Yl)
    z = (np.sqrt(fact_quo(X)) * np.sqrt(fact_quo(Y)) 
            * np.sqrt(fact_quo(Xl)) * np.sqrt(fact_quo(Yl)))
    return (v / (den2 * w)) * z

def Gj(X, Y, Xl, Yl, j=0, coef=1):

    if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
        raise ValueError
    kX, kY, kXl, kYl, kj = X % 2, Y % 2, Xl % 2, Yl % 2, 0

    g = coef * Gj_full(kX, kY, kXl, kYl, kj)
    while kX < X:
        u = (kX - kY + kXl + kYl) // 2
        v = 4 * (u + kj + 1)
        w = 3 * (kX + 2 - kY + kj) * (kX + 1 - kY + kj)
        g *= (v / w) * np.sqrt(kX + 2) * np.sqrt(kX + 1)
        kX += 2
    while kXl < Xl:
        u = (kX - kY + kXl + kYl) // 2
        v = u + kj + 1
        w = 3 * (kXl + 2) * (kXl + 1)
        g *= (v / w) * np.sqrt(kXl + 2) * np.sqrt(kXl + 1)
        kXl += 2
    while kYl < Yl:
        u = (kX - kY + kXl + kYl) // 2
        v = u + kj + 1
        w = 3 * (kYl + 2) * (kYl + 1)
        g *= (v / w) * np.sqrt(kYl + 2) * np.sqrt(kYl + 1)
        kYl += 2
    while kY < Y:
        u = (kX - kY + kXl + kYl) // 2
        v = 3 * (kX - kY + kj) * (kX - kY - 1 + kj) 
        w = 4 * (kY + 2 - kj) * (kY + 1 - kj) * (u + kj)
        g *= (v / w) * np.sqrt(kY + 2) * np.sqrt(kY + 1)
        kY += 2
    while kj < j:
        u = (kX - kY + kXl + kYl) // 2
        v = -4 * (kY - kj) * (u + kj + 1)
        w = 3 * (kX - kY + kj + 1) * (kj + 1)
        g *= (v / w)
        kj += 1
    return g

(4/3)** j和阶乘逐步增加求和项的绝对值。然而,总和应该小于1.事实上,对于X = Y和Xl = Yl = 0,总和等于(-1/3)** X.

1 个答案:

答案 0 :(得分:0)

如果不使用lib,浮点数的无限大数的精度是不可用的。因此,您应该查看decimal lib,您甚至可以设置精度。例如

import decimal
decimal.getcontext().prec = 100
def pi():
    pi = decimal.Decimal(0)
    for k in range(350):
        pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)

如果您设法强制所有数字为整数,you don't need to worry about it