Bil*_*ine 4 math matlab approximation exp
在处理大和负实数时,有没有人知道如何使下面的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
Run Code Online (Sandbox Code Playgroud)
欢迎任何帮助,欢呼.
编辑:
好的,问题如下:
这段代码接近哪个数学函数?(我说指数函数.)当x = 1时它是否有效?(是的.)不幸的是,当x = -100时使用它会产生答案s = 8.7364e + 31.您的同事认为该程序中存在一个愚蠢的错误,并请求您的帮助.仔细解释行为并给出一个简单的修复,产生更好的结果.[您必须建议对上述代码进行修改,或者使用它.您还必须检查您的简单修复工作.]
所以我有点明白,当术语之间存在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
Run Code Online (Sandbox Code Playgroud)
不确定它是否完全正确但它会返回一些好的近似值.
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
Run Code Online (Sandbox Code Playgroud)
这使:
exp(-100)= 3.720075976020836e-044
s = 3.720075976020701e-044
小智 7
正如约翰在评论中指出的那样,你在循环中有一个错误.y = y*k线不能满足你的需要.仔细查看exp(x)系列中的术语.
无论如何,我认为这就是为什么你被赋予这个家庭作业的原因,要知道像这样的系列不能很好地收敛大值.相反,您应该考虑如何减少范围.
例如,您可以使用身份
exp(x+y) = exp(x)*exp(y)
Run Code Online (Sandbox Code Playgroud)
对你有利吗?假设你存储exp(1)= 2.7182818284590452353的值......
现在,如果我要求你计算exp(1.3)的值,你会如何使用上述信息?
exp(1.3) = exp(1)*exp(0.3)
Run Code Online (Sandbox Code Playgroud)
但我们已经知道exp(1)的价值了.实际上,只需稍加思考,就可以将指数范围缩小到需要系列仅在abs(x)<= 0.5时快速收敛的范围.
编辑:有第二种方法可以使用相同身份的变体进行范围缩减.
exp(x) = exp(x/2)*exp(x/2) = exp(x/2)^2
Run Code Online (Sandbox Code Playgroud)
因此,假设您希望计算大数的指数,可能是12.8.让这个快速收敛可以在简单的系列中使用很多术语,并且会发生大量的减法取消,所以无论如何你都不会获得良好的准确性.但是,如果我们认识到这一点
12.8 = 2*6.4 = 2*2*3.2 = ... = 16*0.8
Run Code Online (Sandbox Code Playgroud)
那么如果你能有效地计算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
Run Code Online (Sandbox Code Playgroud)
请注意,除非您使用这样的方法进行范围缩小,但由于需要额外的计算,您可能会遇到数值问题,但由于系列的收敛性大大提高,您通常会提前退出.
为什么你认为这是错误的答案?看看那个序列的最后一个项,它的大小,并告诉我为什么你应该有一个接近0的答案.
我的原始答案表明,舍入误差是问题所在.这将是这个基本方法的一个问题,但为什么你认为40是适当的数学(而不是计算机浮点算术)答案的足够的术语.
100 ^ 40/40!〜= 10 ^ 31.
Woodchip有一个正确的想法,减少范围.这是人们用来快速实现这些功能的典型方法.一旦你弄明白了,就可以处理交替序列的舍入误差,通过对循环内的相邻项求和,并以k = 1:2:40(例如)步进.直到你用木片的想法,因为X = -100,加数成长为这不在这里工作了很长的时间.你需要| x | <1保证中间项缩小,因此重写将起作用.