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


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

我可以使用for循环但这需要很长时间。我怎么能更快地做到这一点?


16
2018-02-04 19:45


起源


总是,在可能的情况下始终向量化MATLAB代码。 - Doresoom
应该搬到 math.stackexchange.com? - aaronsnoswell


答案:


给出的答案都是正确的。我只想详细说明 gnovice的 关于浮点测试的评论。

比较浮点数是否相等时,必须使用容差值。通常使用两种类型的公差比较:绝对公差和相对公差。 (资源

绝对容差比较 a 和 b 好像:

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

29
2018-02-04 21:46



怎么了? isequal? - Jacob
尝试: isequal(0.3,0.1*3) 这相当于 0.3 == 0.1*3。两者的答案都是假的! - Amro
我道歉 - 我想我对MATLAB的信任是错误的!我现在必须改变很多代码:( - Jacob
关于使用EPS的一点是:它也是一个 相对的 功能。不带参数调用EPS可以得到从1.0到下一个最大双精度数的距离。对于你的第二个匿名函数,你可能想要使用类似的东西 tol*eps(max(abs(x),abs(y))),它应该给你在值的范围内的浮点精度 x 和 y (乘以 tol)。 - gnovice
@gnovice:其实那不正确。如果你按照我引用的链接(MATLAB xUnit框架的文档的一部分),它解释了 tol_floor 价值作为绝对宽容时 a 和 b 非常接近0.我只是选择使用 eps。事实上,如果需要,可以省略它并将其定义为: abs(x-y) <= tol*max(abs(x),abs(y))用户为其选择值的位置 tol (一个很好的默认值是 1e-8) - Amro


如果你的两个矩阵 A 和 B 大小相同,那么你可以这样做:

index = A == B;

index 将是一个 逻辑数组 随处可见的元素 A 和 B 等于零,否则为零。

一句警告......

如果 A 和 B 包含整数,上面应该没问题。但是,如果它们包含浮点值,则可能会得到不希望的结果。上面的代码只有元素值为1 究竟 等于。即使是最小的差异也会导致元素被认为是不相等的。

你可以看看 这个问题的答案 有关处理“浮点运算的危险”的更多信息。一种解决方案是检查数组元素是否在给定的容差范围内,如下所示:

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

以上将为您提供一个逻辑数组 index 随处可见的元素 A 和 B 彼此在0.0001之内,否则为零。


12
2018-02-04 19:47



Matlab具有函数eps,被描述为浮点相对精度。您可以在gnovice的代码中使用它而不是容差变量。 index = abs(A-B)<= eps; - yuk
eps是可以表示的最小值,不是吗?在这方面,这不是很有用。 - David Alfonso


只需使用正常 == 运营商:

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

ans =

     1     0
     0     1

7
2018-02-04 19:49