【问题标题】:How do I compare all elements of two arrays?如何比较两个数组的所有元素?
【发布时间】:2011-01-13 05:51:17
【问题描述】:

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

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

【问题讨论】:

标签: matlab comparison matrix vectorization


【解决方案1】:

如果您的两个矩阵 AB 大小相同,那么您可以这样做:

index = A == B;

index 将是一个logical array,其中AB 的元素处处相等,否则为零。

一句警告……

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

您可以查看this question's answers,了解有关处理“浮点运算的危险”的更多信息。一种解决方案是检查数组元素是否在彼此的给定容差范围内,如下所示:

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

上面将为您提供一个逻辑数组index,其中AB 的元素在0.0001 范围内,否则为零。

【讨论】:

  • Matlab 有函数 eps,描述为浮点相对精度。您可以在 gnovice 的代码中使用它代替容差变量。指数 = abs(A-B)
  • eps 是可以表示的最小值,不是吗?这在这种情况下不是很有用。
【解决方案2】:

只需使用普通的== 运算符:

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

ans =

     1     0
     0     1

【讨论】:

    【解决方案3】:

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

    在比较浮点数是否相等时,需要使用容差值。通常使用两种类型的公差比较:绝对公差和相对公差。 (source)

    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)
    

    【讨论】:

    • 尝试:isequal(0.3,0.1*3),相当于0.3 == 0.1*3。两者的答案都是错误的!
    • 我很抱歉 - 我想我对 MATLAB 的信任是错误的!我现在将不得不更改很多代码:(
    • 关于使用EPS的一点:它也是一个relative函数。不带参数调用 EPS 为您提供从 1.0 到下一个最大双精度数的距离。对于您的第二个匿名函数,您可能希望使用 tol*eps(max(abs(x),abs(y))) 之类的东西,它应该为您提供在 xy 的值范围内的浮点精度(乘以 tol)。跨度>
    • isequal 返回一个布尔值; OP 想要一个二元函数,它采用 2 个相同大小的矩阵并生成一个该大小的布尔矩阵。
    • @gnovice:其实那是不正确的。如果您按照我引用的链接(MATLAB xUnit 框架的文档的一部分),它解释了 tol_floor 值在 ab 非常接近 0 时充当绝对容差。我只是选择使用eps。事实上,您可以根据需要省略它并将其定义为:abs(x-y) &lt;= tol*max(abs(x),abs(y)),其中用户为tol 选择一个值(一个好的默认值是1e-8
    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 2012-05-08
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 2021-05-06
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多