无法为“高” x计算e ^-x

问题描述

这是我的代码:

def fact(y):
    if y == 0:
        fact=1
        return fact
    else:
        fact=1
        for k in range (1,y+1):
            fact = fact * k
        return fact

def e_negative_x(x):
    n=0
    numerical_precesion=1
    numerical_precesion_ideal= 10**(-8)
    while numerical_precesion > numerical_precesion_ideal:
        sum=0
        for i in range (0,n+1):
            ind=((-x)**i)/fact(i)
            if i> 0 & n-i == 0:
                ind_2=((-x)**(i-1))/fact(i-1)
                numerical_precesion_1 = ind_2 - ind
                numerical_precesion = abs(numerical_precesion_1)
            sum = sum + ind
        if   numerical_precesion > numerical_precesion_ideal:
            n += 1
        elif sum < 0:
            n += 1
    return sum

我尝试将其用于x=0.1;1;10;15作为练习,但我的精度得到了“正确”,但是当我尝试x=30时,它卡在了-8e-5上(错误答案)。我试图增加我的条款,但是它仍然停留在-8e-5上,小数点后一位不同,而且条款的大幅度增加之后根本没有改变。

编辑:这是-8e-5,这是错误的,因为在无穷大时该级数趋向于0。我进行了无限循环(对于无限项),并打印出它具有多少项以及该项的总和。我在关闭之前有600 +个字词。在89任期,我陷于-8e5,在 117之后,我陷于-8.553016433669241e-05,直到600 + 任期。

解决方法

如何做得更好:

我想说,将可比较大小的正负项相加是容易出错的,因为这会导致将大数和小数相加,这被认为是有问题的。但自exp(-30)=1/exp(30).

起,您就可以避免使用它
1/math.fsum(((30)**n/math.factorial(n) for n in range(0,100+1)))

9.357622968840174e-14

即正像你期望的那样小。还有

1/math.fsum(((30)**n/math.factorial(n) for n in range(0,100+1)))-np.exp(-30)

给予

-1.262177448353619e-29

所以我们基本上和numpy一样。

错误在哪里:

这里是一张表格,其中以taylor级数总计N个项的方式近似计算exp(-30):

  • 天真的想法,我只是将术语计算为浮点数并将其汇总。

  • 在分数列中,我做了同样的事情,但使用的是python的分数,而不是浮点除法。

  • 然后,我认为最好区分除/乘法和总结中的错误。因此,我用分数计算了每个被求和数,但在求和之前将它们转换为浮点数。

  • 最后,我很自然地计算了exp(30)的值,然后又计算了我称为 1 / e ^ 30_trick 的1 / exp(30)的值。

            native     fractions  float(fraction)  1/e^30_trick
0    1.000000e+00  1.000000e+00     1.000000e+00  1.000000e+00
10   1.212548e+08  1.212548e+08     1.212548e+08  4.187085e-09
20   8.529171e+10  8.529171e+10     8.529171e+10  2.652040e-12
30   3.848426e+11  3.848426e+11     3.848426e+11  1.706501e-13
40   6.333654e+10  6.333654e+10     6.333654e+10  9.670058e-14
50   8.782292e+08  8.782292e+08     8.782292e+08  9.360412e-14
60   1.685584e+06  1.685584e+06     1.685584e+06  9.357627e-14
70   6.225246e+02  6.225247e+02     6.225246e+02  9.357623e-14
80   5.588481e-02  5.595324e-02     5.588481e-02  9.357623e-14
90  -6.697346e-05  1.459487e-06    -6.697346e-05  9.357623e-14
100 -6.843293e-05  1.276217e-11    -6.843293e-05  9.357623e-14
110 -6.843294e-05  9.361706e-14    -6.843294e-05  9.357623e-14
120 -6.843294e-05  9.357623e-14    -6.843294e-05  9.357623e-14

我对结果很满意。由于它显示了朴素的方法,甚至是float(fractions)方法都非常糟糕,因此错误必须归纳为负和正项。同样,即使1 / exp(30)技巧和派系的确收敛到9.357623e-14的“正确”值。前者的收敛速度快于后者。

表格代码:

series = pd.Series(np.arange(0,151,10))

@np.vectorize
def naiv(N):
    return math.fsum(((-30)**n/math.factorial(n) for n in range(0,N+1)))

@np.vectorize
def fractions(N):
    return float(sum(Fraction((-30)**n,math.factorial(n)) for n in range(0,N+1)))

@np.vectorize
def float_fractions(N):
    return math.fsum(float(Fraction((-30)**n,math.factorial(n))) for n in range(0,N+1))

@np.vectorize
def one_over_30_trick(N):
    return 1/math.fsum(((30)**n/math.factorial(n) for n in range(0,N+1)))

pd.DataFrame({"native":naiv(series),"fractions":fractions(series),"float(fraction)":float_fractions(series),"1/e^30_trick":one_over_30_trick(series)},index=series)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...