交叉指数按行

时间:2013-01-24 06:26:14

标签: matlab matrix indexing intersection vectorization

鉴于这两个矩阵:

m1 = [ 1 1;
       2 2;
       3 3;
       4 4;
       5 5 ];

m2 = [ 4 2;
       1 1;
       4 4;
       7 5 ];

我正在寻找一个功能,例如:

indices = GetIntersectionIndecies (m1,m2);

其输出将是

indices = 
          1
          0
          0
          1
          0

如何在不使用循环的情况下找到这两个矩阵之间的行的交叉索引?

2 个答案:

答案 0 :(得分:6)

一种可能的解决方案:

function [Index] = GetIntersectionIndicies(m1, m2)
[~, I1] = intersect(m1, m2, 'rows');
Index = zeros(size(m1, 1), 1);
Index(I1) = 1;

顺便说一句,我喜欢@Shai的创造性解决方案,如果你的矩阵很小,它比我的解决方案快得多。但如果你的矩阵很大,那么我的解决方案将占主导地位。这是因为如果我们设置T = size(m1, 1),那么@Shai答案中的tmp变量将是T * T,即如果T很大则为非常大的矩阵。以下是快速测试的一些代码:

%# Set parameters
T = 1000;
M = 10;

%# Build test matrices
m1 = randi(5, T, 2);
m2 = randi(5, T, 2);

%# My solution
tic
for m = 1:M
[~, I1] = intersect(m1, m2, 'rows');
Index = zeros(size(m1, 1), 1);
Index(I1) = 1;
end
toc

%# @Shai solution
tic
for m = 1:M
tmp = bsxfun( @eq, permute( m1, [ 1 3 2 ] ), permute( m2, [ 3 1 2 ] ) );
tmp = all( tmp, 3 ); % tmp(i,j) is true iff m1(i,:) == m2(j,:)
imdices = any( tmp, 2 );
end
toc

设置T = 10M = 1000,我们得到:

Elapsed time is 0.404726 seconds. %# My solution
Elapsed time is 0.017669 seconds. %# @Shai solution

但设置T = 1000M = 100,我们得到:

Elapsed time is 0.068831 seconds. %# My solution
Elapsed time is 0.508370 seconds. %# @Shai solution

答案 1 :(得分:3)

如何使用bsxfun

function indices = GetIntersectionIndecies( m1, m2 )
    tmp = bsxfun( @eq, permute( m1, [ 1 3 2 ] ), permute( m2, [ 3 1 2 ] ) );
    tmp = all( tmp, 3 ); % tmp(i,j) is true iff m1(i,:) == m2(j,:)
    indices = any( tmp, 2 );
end

干杯!