在一行与1和0的矩阵之间采用xor的速度更快?

时间:2014-01-14 16:54:15

标签: arrays matlab

我有一行数据,比如A = [0 1 1 1 0 0]

Matrix B包含许多行。对于一个虚拟的例子,我们说它只是B = [1 1 1 0 1 0; 1 0 0 1 0 1]

我想找到A和B行不同的列数,并使用该差异向量来查找哪一行B与A最相似。所以对于上面的示例,A与{{第1列,第4列,第5列中的1}} = 3总差异。 A与第2列,第2列,第3列,第6列= 4总差异中的B(2,:)不同,因此我希望返回索引1以指示A与B(1,:)最相似。

实际上B有 ~50,000行,而A和B都有 800列。我目前找到最相似行的代码如下:

B(1,:)

有效,但速度很慢。任何关于哪个功能花了这么长时间的见解以及改进它的方法?

5 个答案:

答案 0 :(得分:3)

bsxfun有6种或多或少类似的方法,很难说哪种方法最快。

%example data
A = [0 1 1 1 0 0];
B = perms(A);     %720x6 matrix

计算相似之处:

Z = sum(  bsxfun(@eq,  A,B) , 2);
Z = sum( ~bsxfun(@ne,  A,B) , 2);
Z = sum( ~bsxfun(@xor, A,B) , 2);

计算差异:

Z = sum( ~bsxfun(@eq,  A,B) , 2);
Z = sum(  bsxfun(@ne,  A,B) , 2);
Z = sum(  bsxfun(@xor, A,B) , 2);

Z是一个向量,包含A每行B的相等/不等元素数。

每项100项试验的基准(与上述相同的顺序):

t100 =

    0.0081
    0.0098
    0.0123
    0.0102
    0.0087
    0.0111

答案 1 :(得分:3)

pdist2'hamming'距离

一起使用
[D I] = pdist2( A, B, 'hamming', 'Smallest', 1 );

答案 2 :(得分:2)

所有解决方案的基准

(基准代码Thanks to Amro

function [t] = bench()
    A = [0 1 1 1 0 0];
    B = perms(A);

    % functions to compare
    fcns = {
        @() compare1(A,B);
        @() compare2(A,B);
        @() compare3(A,B);
        @() compare4(A,B);
    };

    % timeit
    t = zeros(4,1);
    for ii = 1:100;
        t = t + cellfun(@timeit, fcns);
    end
end

function Z = compare1(A,B)  %thewaywewalk
    Z = sum(  bsxfun(@eq,  A,B) , 2);
end
function Z = compare2(A,B)  %Matt J
    Z = sum(bsxfun(@xor, A, B),2);
end
function Z = compare3(A,B)  %Luis Mendo
    A = logical(A);
    Z = sum(B(:,~A),2) + sum(~B(:,A),2);
end
function Z = compare4(A,B)  %Shai
     Z = pdist2( A, B, 'hamming', 'Smallest', 1 );
end

100个试验的结果和720x6的{​​{1}}矩阵:

B

100个试验的结果和0.0068s %thewaywewalk 0.0092s %Matt J 0.0077s %Luis Mendo 0.0399s %Shai 的{​​{1}}矩阵:

40320x8

B方法似乎是最快的,并且使用匿名函数0.0889s %thewaywewalk 0.1512s %Matt J 0.4571s %Luis Mendo 0.4578s %Shai

答案 3 :(得分:1)

听起来像你需要的bsxfun命令

min(sum(bsxfun(@xor, A, B),2))

答案 4 :(得分:1)

另一种可能性,它通过索引取代xor(不确定它是否比以前的答案更快):

A = logical(A);
min(sum(B(:,~A),2) + sum(~B(:,A),2))

或者,为了避免~上的B

A = logical(A);
min(sum(B(:,~A),2) - sum(B(:,A),2)) + nnz(A)