这是我的代码:
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 一样。错误究竟在哪里:
以下是使用泰勒级数汇总 N 项来近似计算 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
我对结果很满意。由于它显示了 naiv 甚至浮点(分数)方式都很糟糕,所以错误一定是在总结消极和积极方面。即使 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)
关于python - 无法为 "high"x 计算 e^(-x),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64440876/