在处理大实数和负实数时,有人知道如何使下面的Matlab代码更准确地逼近指数函数吗?
例如,当x=1时,代码运行良好,当x= -100时,当它接近3.7201e-44时,返回8.7364e+31的答案。
守则如下:
s=1
a=1;
y=1;
for k=1:40
a=a/k;
y=y*x;
s=s+a*y;
end
s
任何帮助都是非常感谢的,干杯。
编辑:
好的,问题如下:
这段代码近似哪个数学函数?(我说指数函数。)当x= 1?(是。)时,会工作吗?不幸的是,当x= -100产生答案s= 8.7364e+31时,使用这个函数。您的同事认为程序中有一个愚蠢的bug,并请求您的帮助。仔细解释行为,并给出一个简单的解决办法,从而产生更好的效果。[您必须建议对上述代码进行修改,否则就会使用它。您还必须检查您的简单修复工作。
因此,我有点理解,当术语之间有16个(或更多)数量级时,这个问题围绕着大量的数字,精度就失去了,但是这个解决方案没有得到解决。
谢谢
编辑:
所以最后我说了这个:
s = 1;
x = -100;
a = 1;
y = 1;
x1 = 1;
for k=1:40
x1 = x/10;
a = a/k;
y = y*x1;
s = s + a*y;
end
s = s^10;
s
不确定它是否完全正确,但它返回一些很好的近似。
exp(-100) = 3.720075976020836e-044
S= 3.722053303838800e-044
经过进一步的分析(不幸的是提交了赋值),我意识到增加了迭代次数,从而增加了术语,进一步提高了效率。事实上,以下方面的效率甚至更高:
s = 1;
x = -100;
a = 1;
y = 1;
x1 = 1;
for k=1:200
x1 = x/200;
a = a/k;
y = y*x1;
s = s + a*y;
end
s = s^200;
s
这意味着:
exp(-100) = 3.720075976020836e-044
S= 3.720075976020701e-044
发布于 2012-04-23 13:33:41
正如John在评论中指出的那样,循环中有一个错误。Y= y*k线不能满足您的需要。请更仔细地查看系列中exp(x)中的术语。
不管怎么说,我想这就是为什么你被分配了这个家庭作业,来学习像这样的系列并不能很好地收敛到很大的值。相反,您应该考虑如何减少范围。
例如,您可以使用标识吗?
exp(x+y) = exp(x)*exp(y)
对你有利?假设您存储exp(1) =2.7182818284590452353的值..。
现在,如果我要求您计算exp(1.3)的值,您将如何使用上述信息?
exp(1.3) = exp(1)*exp(0.3)
但是我们已经知道exp(1)的值了。实际上,只要稍微考虑一下,就可以将范围缩小到只对abs(x) <= 0.5快速收敛的级数。
编辑:还有第二种方法可以使用相同身份的变化来缩小范围。
exp(x) = exp(x/2)*exp(x/2) = exp(x/2)^2
因此,假设您希望计算大数的指数,也许是12.8。要使它以可接受的速度收敛,在这个简单的系列中需要很多术语,并且会发生大量的减法取消,所以无论如何你都不会得到很好的精度。但是,如果我们认识到
12.8 = 2*6.4 = 2*2*3.2 = ... = 16*0.8
然后,如果你能有效地计算出0.8的指数,那么所期望的值就很容易恢复,也许是通过重复的平方。
exp(12.8)
ans =
362217.449611248
a = exp(0.8)
a =
2.22554092849247
a = a*a;
a = a*a;
a = a*a;
a = a*a
362217.449611249
exp(0.8)^16
ans =
362217.449611249
请注意,每当您使用这样的方法进行范围缩减时,虽然您可能会因所需的额外计算而引起数值问题,但是由于您的系列的收敛性大大增强,您通常会走在前面。
发布于 2012-04-23 13:18:51
你为什么认为这是错误的答案?看看这个序列的最后一个项,它的大小,告诉我为什么你期望得到一个接近0的答案。
我最初的回答是,舍入错误是问题所在。这将是这个基本方法的一个问题,但为什么你认为40是足够的适当的数学术语(相对于计算机浮点算术)答案。
40/ 40!~= 10^31。
木片有正确的想法与范围缩小。这是人们用来快速实现这类功能的典型方法。一旦弄清楚了这一点,就可以处理交替序列的舍入错误,方法是在循环中求和相邻的项,并以k=1:2: 40 (例如)为步长。这在这里是行不通的,直到你使用木片的想法,因为对于x= -100,总和增长了很长一段时间。为了保证中间项正在缩小,您需要使用x<1,这样重写就可以了。
https://stackoverflow.com/questions/10281150
复制相似问题