用Matlab代码逼近指数函数

用Matlab代码逼近指数函数,matlab,math,approximation,exp,Matlab,Math,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 谢谢你的帮助,干杯 编辑: 好的,问题如下: s=1 a=1; y=1; for k=1:40 a=a/k; y=y*x; s=

有人知道如何使下面的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
谢谢你的帮助,干杯

编辑:

好的,问题如下:

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。您的同事认为程序中存在一个愚蠢的错误,并请求您的帮助。仔细解释行为,并给出一个简单的解决方案,以产生更好的结果。[您必须建议对上述代码进行修改或使用。您还必须检查您的简单修复程序是否有效。]

因此,我多少能理解,当术语之间有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.72205303838800E-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

为什么你认为这是错误的答案?看看这个序列的最后一项,它的大小,告诉我为什么你期望你的答案接近0

我最初的回答是,舍入误差是问题所在。这将是这个基本方法的一个问题,但是为什么你认为40个术语对于适当的数学(相对于计算机浮点算术)答案来说是足够的呢

100^40/40!~=10^31


Woodchip有缩小射程的正确想法。这是人们用来快速实现这类功能的典型方法。一旦你把这些都弄清楚了,你就可以处理交替序列的舍入错误,方法是将循环中的相邻项求和,然后以k=1:2:40(例如)步进。在使用woodchips的想法之前,这在这里是不起作用的,因为对于x=-100,求和数会增长很长时间。您需要| x |<1来保证中间术语正在缩减,因此重写将起作用。

正如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),我想,你的意思是y=x^k?或者y=yx?正如代码所示,术语ay总是(忽略舍入错误)1.谢谢。是的,那是个打字错误,应该是y=y*x;嗯,四舍五入是一种看待它的方式,但实际上并非如此。相关短语是“大量减法消除”。序列中有非常大的负值和非常大的正值。理论上,如果你有大量的条款,这两个条款最终会被取消。实际上,这种情况不会发生,因为浮点运算的限制会导致精度下降。这就是为什么这个过程被称为大规模减法消除。正如你所评论的,我正在重写。好笑,是的,时机很好。我将在这里留下我的评论,只是因为大规模减法取消概念是一个重要的概念。@BillyRayValentine-为什么你认为范围缩小不简单?我展示的任何一种方案都只需几行额外代码即可完成。诚然,有一些聪明的变体可以在重要的时候添加几十条线以获得极端收敛,但我描述的简单范围缩减很难实现。试试看!这样做会让你学到很多东西,真正的意义在于这些身份。测试你的方案,找出各种数字,包括正数和负数。如果你有问题,再问一次。但实际上,只要使用这些身份就可以满足您的需要。感谢Woodchips,我不确定如何将其应用到算法中,特别是如果x=-100.exp(hpf(-100))ans=3.7200759760208359629596958038631833735889229237676196712061387666329047589581571818764228197E-44
12.8 = 2*6.4 = 2*2*3.2 = ... = 16*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