无法计算 "high" x 的 e^(-x)
Can't calculate e^(-x) for "high" 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 基本相同。
具体错误在哪里:
这里是 table 计算 exp(-30) 的不同方法,用泰勒级数对 N 项求和:
天真的我只是把这些项计算为浮点数并将它们相加。
在分数列中,我做了同样的事情,但使用了 python 的分数而不是浮点除法。
然后我认为在division/muliplication和总结中区分错误会很好。所以我用分数计算了每个被加数,但在求和之前把它们变成了浮点数。
最后我计算了 exp(30) 的值,然后是 1/exp(30) 我称之为 1/e^30_trick.
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 甚至 float(fractions) 方式都很糟糕,所以错误一定是在总结负项和正项时。同样,即使 1/exp(30) 技巧和派系都收敛到 9.357623e-14 的“正确”值。前者比后者收敛快很多
Table代码:
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)
这是我的代码:
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 基本相同。
具体错误在哪里:
这里是 table 计算 exp(-30) 的不同方法,用泰勒级数对 N 项求和:
天真的我只是把这些项计算为浮点数并将它们相加。
在分数列中,我做了同样的事情,但使用了 python 的分数而不是浮点除法。
然后我认为在division/muliplication和总结中区分错误会很好。所以我用分数计算了每个被加数,但在求和之前把它们变成了浮点数。
最后我计算了 exp(30) 的值,然后是 1/exp(30) 我称之为 1/e^30_trick.
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 甚至 float(fractions) 方式都很糟糕,所以错误一定是在总结负项和正项时。同样,即使 1/exp(30) 技巧和派系都收敛到 9.357623e-14 的“正确”值。前者比后者收敛快很多
Table代码:
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)