“矩阵是不是包含值 X?”的函数
Posted
技术标签:
【中文标题】“矩阵是不是包含值 X?”的函数【英文标题】:Function for 'does matrix contain value X?'“矩阵是否包含值 X?”的函数 【发布时间】:2010-12-27 04:28:45 【问题描述】:是否有内置的 MATLAB 函数来确定矩阵是否包含某个值?
(ala php 的in_array()
)
【问题讨论】:
对于可能需要容差的浮点数据,请注意,R2015a 版本添加了新功能,可通过单个内置函数来处理此问题。整数值数据的公认解决方案很棒,但对于浮点数,请跳转到this answer。很抱歉自我推销,但经过多年的询问,这是对 MATLAB 的一个重要补充。 【参考方案1】:有很多方法可以做到这一点。 ismember 是第一个想到的,因为它是您希望采取的一组成员操作。因此
X = primes(20);
ismember([15 17],X)
ans =
0 1
因为 15 不是素数,但 17 是素数,所以 ismember 在这里做得很好。
当然,find(或任何)也可以。但是这些并没有像 ismember 那样矢量化。我们可以测试一下 15 是否在 X 表示的集合中,但是测试这两个数字需要循环或连续测试。
~isempty(find(X == 15))
~isempty(find(X == 17))
或者,
any(X == 15)
any(X == 17)
最后,我要指出,如果数字可能是真正的浮点数,那么对精确值的测试是危险的。正如我所展示的,对整数值进行测试很容易。但是针对浮点数的测试通常应该使用容差。
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
【讨论】:
这三个中最快的似乎是any
。但您可能想自己测量(使用tic
和toc
)。
对于浮点值,如果您至少使用 R2015a,请使用 ismembertol
。【参考方案2】:
你可以这样做:
A = randi(10, [3 4]); %# a random matrix
any( A(:)==5 ) %# does A contain 5?
要以 矢量化 方式执行上述操作,请使用:
any( bsxfun(@eq, A(:), [5 7 11] )
或如@woodchips 建议的那样:
ismember([5 7 11], A)
【讨论】:
为什么你在 ismember 中使用 [5 7 11] 作为参数 @Jordan:返回的答案是一个与参数大小相同的逻辑数组(真/假),表示矩阵A
是否包含这些值中的每一个(例如[true, true, false]
表示@ 987654328@ 包含值 5
和 7
但不包含 11
)。
@AnderBiguri:这里有一些你可以运行比较的测试:gist.github.com/amroamroamro/e66ac6a88b0692d995fd【参考方案3】:
如果您需要检查一个向量的元素是否在另一个向量中,最好的解决方案是ismember
,如其他答案中所述。
ismember([15 17],primes(20))
但是,当您处理浮点数时,或者只想进行紧密匹配(+- 1000 也是可能的)时,我发现的最佳解决方案是相当有效的File Exchange Submission: ismemberf
举了一个很实用的例子:
[tf, loc]=ismember(0.3, 0:0.1:1) % returns false
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true
虽然默认容差通常应该足够了,但它为您提供了更大的灵活性
ismemberf(9.99, 0:10:100) % returns false
ismemberf(9.99, 0:10:100,'tol',0.05) % returns true
【讨论】:
【参考方案4】:对于浮点数据,您可以使用新的ismembertol
function,它计算集合成员具有指定的容差。这类似于 File Exchange 中的 ismemberf
函数,只是它现在内置于 MATLAB。示例:
>> pi_estimate = 3.14159;
>> abs(pi_estimate - pi)
ans =
5.3590e-08
>> tol = 1e-7;
>> ismembertol(pi,pi_estimate,tol)
ans =
1
【讨论】:
以上是关于“矩阵是不是包含值 X?”的函数的主要内容,如果未能解决你的问题,请参考以下文章