Reputation: 2164
The below code do some computation on a data
matrix, the data is laid as --
data = [ ...
1 2 3 4 5 6; ...
1 2 3 4 5 6; ...
1 2 3 4 5 6;]
and the code that I am running is like this --
[~,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
what this code is doing is comparing each row in column major order and creating two matrices of binary values flag1
and flag2
.
Is there anyway to get rid of this for cindex = 2:col
loop ?
Upvotes: 2
Views: 70
Reputation: 2164
I was curious to see, how much gain I am actually getting, it's actually a double speedup! here is a benchmark --
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');
one interesting thing to note doing |
over two matrices and doing bsxfun(@or...
are almost same --
>> vectest
time elapsed: 0.8609 sec
time elapsed: 0.7914 sec
time elapsed: 0.3285 sec
done.
Upvotes: 1
Reputation: 221574
You need some permuting(rearrange dimensions)
to create singleton dimensions
so that expansions would take place when using bsxfun
later on, which would essentially replace the looping as used in the original posted code. So, the implementation would look something like this -
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);
Upvotes: 2