Matlab代码近似指数函数

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)

请注意,除非您使用这样的方法进行范围缩小,但由于需要额外的计算,您可能会遇到数值问题,但由于系列的收敛性大大提高,您通常会提前退出.


Joh*_*ohn 5

为什么你认为这是错误的答案?看看那个序列的最后一个项,它的大小,并告诉我为什么你应该有一个接近0的答案.

我的原始答案表明,舍入误差是问题所在.这是这个基本方法的一个问题,但为什么你认为40是适当的数学(而不是计算机浮点算术)答案的足够的术语.

100 ^ 40/40!〜= 10 ^ 31.

Woodchip有一个正确的想法,减少范围.这是人们用来快速实现这些功能的典型方法.一旦你弄明白了,就可以处理交替序列的舍入误差,通过对循环内的相邻项求和,并以k = 1:2:40(例如)步进.直到你用木片的想法,因为X = -100,加数成长为这不在这里工作了长的时间.你需要| x | <1保证中间项缩小,因此重写将起作用.