Matlab R2012a奇怪'找到'数组元素错误

时间:2014-05-01 18:41:37

标签: matlab find

我在Matlab中使用find函数得到了一个非常奇怪的错误。看看这个!

A = 0:0.1:10;

现在,如果我执行以下操作,我会得到预期的行为:

find(A==5.6)
ans = 57

但如果我这样做:

find(A==5.9)
ans =
Empty matrix: 1-by-0

任何人都知道为什么?这很奇怪。

提前致谢!

2 个答案:

答案 0 :(得分:1)

以下是大多数程序员的常识:

a = 0.3;
b = 3 * 0.1;
a == b
ans =
     0

这是因为0.1无法准确表示为二进制数,因此3*0.1 几乎等于0.3,但是四舍五入错误。

然而,您显然可以执行以下操作:

a = 0.3;
a == 0.3
ans =
     1   

然而,你的问题比这更复杂......你做了:

A = 0:0.1:10;

尽管您可能会想到,但MATLAB不会创建值[0 0.1 0.2 ...],而是创建[0 0+0.1 0+0.1+0.1 0+0.1+0.1+0.1 ...]的内容(但不是真的,请参阅底部的更新 )。

为了说明这一点,您可以查看以下示例:

A = 0:0.1:0.4;
find(A == 0.3)
ans =
   Empty matrix: 1-by-0

find(A == 0.1+0.1+0.1)
ans =
     4

然而,这并没有涵盖所有方面:

A = 5.8:0.1:6
A =
    5.8000    5.9000    6.0000

find(A == 5.9)
ans =
     2
%% Found it!

A = 5.8:0.1:6.1
A =
    5.8000    5.9000    6.0000    6.1000

find(A == 5.9)
ans =
   Empty matrix: 1-by-0
%% Didn't find it!

find(A == 5.8+0.1)
ans =
     2
%% Found it again!

对于记录,linspace会产生相同的结果。

A = linspace(5.8, 6.0, 3)
A =
    5.8000    5.9000    6.0000

find(A == 5.9)
ans =
     2

A = linspace(5.8, 6.1, 4)
A =
    5.8000    5.9000    6.0000    6.1000

find(A == 5.9)
ans =
   Empty matrix: 1-by-0

find(A == 5.8+0.1)
ans =
     2

那么,发生了什么?以下两个实际上是否相同:x = [a:b:c]y = linspace(a,c,(c-a)/b+1)

A = 5.8:0.1:6.1
A =
    5.8000    5.9000    6.0000    6.1000

B = linspace(5.8,6.1,4)
B =
    5.8000    5.9000    6.0000    6.1000

A == B
ans =
     1     1     1     1

可能看起来那样......但答案是否定的,它们不一样!

x = -0.1:0.1:0.3
x =
   -0.1000         0    0.1000    0.2000    0.3000

y = linspace(-0.1,0.3,5)
y =
   -0.1000         0    0.1000    0.2000    0.3000

x == y
ans =
     1     1     0     0     1

那么,当你A = 5.8:0.1:6时会发生什么?数字是如何创建的?如何解释以下内容?

A = 5.8:0.1:6;
B = 5.8:0.1:6.1;

A(2)-B(2)
ans =
  8.8818e-016

eps(5.9)
ans =
  8.8818e-016

更新

抵消执行[0 0+0.1 0+2*0.1 ... 0+k*0.1]

的累积错误

“为了抵消这种错误累积,COLON算子的算法决定:

  

通过添加整数来计算输出向量的前半部分   步数的倍数到左手端点。下半场是   通过从右手减去步数的倍数来计算   端点。

(See here)

还要看here

当然,课程不是使用x == y来比较浮点数,而是(x - y) < tolerance

答案 1 :(得分:0)

正如评论中已经指出的那样,这是一个浮点问题。

如果您确实希望以这种方式使用find,请尝试使用linspace代替:来创建数组:

<强>之前:

>> A = 0:0.1:10;
>> find(A==5.6)

ans =

    57

>> find(A==5.9)

ans =

   Empty matrix: 1-by-0

<强>后:

>> A = linspace(0, 10, 101);
>> find(A==5.6)

ans =

    57

>> find(A==5.9)

ans =

    60