如何比较两个数组的所有元素?

16

我有两个大数组,大约有1000行和1000列。我需要比较这些数组的每个元素,并在另一个数组中存储1,如果对应的元素相等。

我可以使用for循环来实现,但是这需要很长时间。我该如何更快地完成这个任务?


2
尽可能地向量化MATLAB代码,总是要做的事情。 - Doresoom
应该移动到http://math.stackexchange.com/? - aaronsnoswell
3个回答

29
答案:所有答案都是正确的。我只是想详细说明gnovice在浮点数测试方面的评论。
在比较浮点数是否相等时,需要使用一个容差值。通常使用两种类型的容差比较:绝对容差和相对容差。(来源
对于 ab 的绝对容差比较如下:
|a-b| < tol

相对容差比较如下:

|a-b| < tol*max(|a|,|b|) + tol_floor

你可以将上述两个函数实现为匿名函数:

%# absolute tolerance equality
isequalAbs = @(x,y,tol) ( abs(x-y) <= tol );

%# relative tolerance equality
isequalRel = @(x,y,tol) ( abs(x-y) <= ( tol*max(abs(x),abs(y)) + eps) );

然后你可以这样使用它们:

%# let x and y be scalars/vectors/matrices of same size
x == y
isequalAbs(x, y, 1e-6)
isequalRel(x, y, 1e-6)

4
尝试运行:isequal(0.3,0.1*3),它等同于 0.3 == 0.1*3。两者的答案都是错误的! - Amro
1
非常抱歉 - 我想我对MATLAB的信任是错误的!现在我必须改变很多代码 :( - Jacob
2
有关使用EPS的一点说明:它也是一个相对函数。调用没有参数的EPS会给出从1.0到下一个最大双精度数之间的距离。对于您的第二个匿名函数,您可能想要使用类似于 tol * eps(max(abs(x),abs(y))) 的东西,这应该会在xy值范围内给您浮点精度(乘以tol)。 - gnovice
2
@gnovice:实际上那是不正确的。如果你跟随我引用的链接(MATLAB xUnit框架文档的一部分),它解释了tol_floor值在ab非常接近0时作为绝对公差的作用。我只是选择使用eps。事实上,如果你想的话可以省略它并定义为:abs(x-y) <= tol*max(abs(x),abs(y)),其中用户选择tol的值(一个很好的默认值是1e-8)。 - Amro
@gnovice 在这个点上,公差不应该取决于 eps 吗:abs(x-y) < max( abs( eps(x), eps(y) ) ) - user2469775
显示剩余2条评论

12
如果你的两个矩阵 AB 大小相同,那么你可以这样做:
index = A == B;

而且index将是一个逻辑数组,在AB的元素相等时处处为1,否则为0。

警告...

如果AB包含整数,则上述内容应该是可以接受的。然而,如果它们包含浮点值,则可能会得到不想要的结果。上面的代码仅在元素完全相等时才有值为1。即使最小的差异也会导致元素被认为是不相等的。

您可以查看这个问题的答案,以获取有关“浮点操作危险”的更多信息。一种解决方法是检查数组元素是否彼此之间在给定的容差范围内,如下所示:

tolerance = 0.0001;
index = abs(A-B) <= tolerance;

以上代码将为您提供一个逻辑数组 index,其中每个与AB元素的差值在0.0001以内的位置都标记为1,否则标记为0。


Matlab有一个名为eps的函数,描述了浮点相对精度。您可以在gnovice的代码中使用它来代替公差变量。索引= abs(A-B)<= eps; - yuk
eps是可以表示的最小值,不是吗?但在这种情况下并不是很有用。 - David

7

只需使用常规的==运算符:

>> [1 2; 3 4] == [1 5; 6 4]      

ans =

     1     0
     0     1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接