matlab:向量化单个循环,即ORing N二进制矩阵

时间:2015-03-21 01:17:46

标签: matlab loops matrix vectorization

以下代码对data矩阵进行一些计算,数据为 -

data = [ ...
        1 2 3 4 5 6; ...
        1 2 3 4 5 6; ...
        1 2 3 4 5 6;] 

我正在运行的代码是这样的 -

[~,col] = size(data) ;
flag1 = bsxfun(@lt, data(:,1), data(:,1).'); 
flag2 = bsxfun(@gt, data(:,1), data(:,1).'); 

for cindex = 2:col % can we get rid of this loop ?
    flag1 = flag1 | bsxfun(@lt, data(:,cindex), data(:,cindex).');
    flag2 = flag2 | bsxfun(@gt, data(:,cindex), data(:,cindex).');
end

此代码正在做的是比较列主要顺序中的每一行,并创建两个二进制值flag1flag2的矩阵。

有没有摆脱这个for cindex = 2:col循环?

2 个答案:

答案 0 :(得分:2)

您需要一些permuting(rearrange dimensions)来创建singleton dimensions,以便稍后使用bsxfun时会发生扩展,这实际上会取代原始发布代码中使用的循环。所以,实现看起来像这样 -

flag1 = any(bsxfun(@lt,permute(data,[1 3 2]),permute(data,[3 1 2])),3);
flag2 = any(bsxfun(@gt,permute(data,[1 3 2]),permute(data,[3 1 2])),3);

答案 1 :(得分:1)

我很好奇,我实际获得了多少收获,实际上是双倍的加速!这是一个基准 -

clear all 

data = rand(500,500);
[~,col] = size(data);
maxrun = 20 ;

%warm up
for k = 1:50000
    tic(); elapsed = toc();
end

toctime = 0 ;
for i = 1:maxrun
    flag1 = bsxfun(@lt, data(:,1), data(:,1).'); 
    flag2 = bsxfun(@gt, data(:,1), data(:,1).'); 
    tic
    for cindex = 2:col % can we get rid of this loop ?
        flag1 = flag1 | bsxfun(@lt, data(:,cindex), data(:,cindex).');
        flag2 = flag2 | bsxfun(@gt, data(:,cindex), data(:,cindex).');
    end
    toctime = toctime + toc ;
end
fprintf('time elapsed: %0.4f sec\n', toctime/maxrun);

toctime = 0 ;
for i = 1:maxrun
    flag1 = bsxfun(@lt, data(:,1), data(:,1).'); 
    flag2 = bsxfun(@gt, data(:,1), data(:,1).'); 
    tic
    for cindex = 2:col % can we get rid of this loop ?
        flag1 = bsxfun(@or, flag1, bsxfun(@lt, data(:,cindex), data(:,cindex).'));
        flag2 = bsxfun(@or, flag2, bsxfun(@gt, data(:,cindex), data(:,cindex).'));
    end
    toctime = toctime + toc ;
end
fprintf('time elapsed: %0.4f sec\n', toctime/maxrun);

toctime = 0 ;
for i = 1:maxrun
    tic
    flag1 = any(bsxfun(@lt,permute(data,[1 3 2]),permute(data,[3 1 2])),3);
    flag2 = any(bsxfun(@gt,permute(data,[1 3 2]),permute(data,[3 1 2])),3);
    toctime = toctime + toc ;
end
fprintf('time elapsed: %0.4f sec\n', toctime/maxrun);

fprintf('done.\n');

要注意在两个矩阵上执行|并执行bsxfun(@or...几乎相同的一件有趣的事情 -

>> vectest
time elapsed: 0.8609 sec
time elapsed: 0.7914 sec
time elapsed: 0.3285 sec
done.