MATLAB:非常小的数字除以非常小的数字

时间:2016-07-30 06:53:03

标签: matlab

我有一个非常小的数字除以非常小的数字,MATLAB给我Inf(当x太小时)或NaN(当x为零时)。但正确的限值应该是2.如何解决这个问题?要将j设为2,因为xx = 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

2 个答案:

答案 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方法。特别是:

  1. 在一系列接近极限点的几何间隔点处评估极限。
  2. 多项式用于拟合结果值序列。诀窍是找到步骤1中选择的点的平衡。它们越接近极限点,多项式拟合就越失真。
  3. 将多项式模型的常数项作为限制。
  4. 在您的特定情况下,该实用程序就像魅力一样,无需调整点序列。请注意,它期望您的函数被矢量化,即能够在输入点的矢量处评估结果,因此在定义它时使用元素操作符:

    >> 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)