我有一个非常小的数字除以非常小的数字,MATLAB给我Inf(当x
太小时)或NaN(当x
为零时)。但正确的限值应该是2.如何解决这个问题?要将j
设为2,因为x
或x = 0
太小了?
x = 0.000001
>> x = 0.000001
x =
1.0000e-06
>> j = 2*x*(1+(-1)*exp(-x))^(-1)*exp(-x)
j =
2.0000
x = 0.01
>> x = 0.01
x =
0.0100
>> j = 2*x*(1+(-1)*exp(-x))^(-1)*exp(-x)
j =
1.9900
x = 1e-19
>> x = 1e-19
x =
1.0000e-19
>> j = 2*x*(1+(-1)*exp(-x))^(-1)*exp(-x)
j =
Inf
x = 0
>> x = 0
x =
0
>> j = 2*x*(1+(-1)*exp(-x))^(-1)*exp(-x)
j =
NaN
答案 0 :(得分:2)
NaN
获得x=0
的事实是正确的,因为您不能除以零。该限制仅在x->0
时有效,而不是x=0
。
它最多可以用于x~ = 10^-12
,问题在于,当指数接近1
时,由于浮点算术的具体细节,你很快就会失去精度:
f = @(x) 2*x*exp(-x)/(1-exp(-x));
pow = (-1)*(1:19);
X = 10.^pow; % 10^-1 to 10^-19
[pow', arrayfun(f, X)']
ans =
-1.0000 1.9017
-2.0000 1.9900
-3.0000 1.9990
-4.0000 1.9999
-5.0000 2.0000
-6.0000 2.0000
-7.0000 2.0000
-8.0000 2.0000
-9.0000 2.0000
-10.0000 2.0000
-11.0000 2.0000
-12.0000 2.0000
-13.0000 1.9994
-14.0000 2.0016
-15.0000 2.0016
-16.0000 1.8014
-17.0000 Inf
-18.0000 Inf
-19.0000 Inf
解决这个问题的一种方法是使用符号数学,如另一个答案所示。如果你想以数字方式进行,你必须找到在距离尚未达到极限的极限点太远的地方进行评估之间的权衡,并且评估太接近于数值误差超过结果的极限点。
在FEX上有一个很棒的Adaptive numerical limit (and residue) estimation提交,试图实现这一目标。 approach it takes有点类似于Richardson extrapolation方法。特别是:
在您的特定情况下,该实用程序就像魅力一样,无需调整点序列。请注意,它期望您的函数被矢量化,即能够在输入点的矢量处评估结果,因此在定义它时使用元素操作符:
>> f = @(x) 2.*x.*exp(-x)./(1-exp(-x));
[lim, err] = limest(f, 0)
lim =
2.0000
err =
5.5161e-12
答案 1 :(得分:1)
您可以使用符号数学工具箱:
syms x;
limit(2*x*(1+(-1)*exp(-x))^(-1)*exp(-x), 0)