vectorization of comparison against several intervals

Hello,
I currently have the code below, which essentially checks if each element of the MainArray is within any of the intervals described in each row of CompArray; if yes, the corresponding position in ResultsArray is set to 0. In practice, I need to run this on mich bigger matrices and iteratively, so speed of execution becomes a problem. Is there a possibility to vectorize it? Note that CompArray can have a variable number of rows (comparison intervals), but always only two columns.
clc
clearvars
ResultsArray = ones(10,10);
MainArray = magic(10);
CompArray = [ 20 30;...
40 50;...
60 70];
for Row = 1:10
for Col = 1:10
if(any((MainArray(Row,Col) >= CompArray(:,1)) & (MainArray(Row,Col) <= CompArray(:,2))))
ResultsArray(Row,Col) = 0;
end
end
end
Best regards,
Cristian

2 Comments

Jan
Jan on 13 Dec 2021
Edited: Jan on 13 Dec 2021
What are typical sizes? It matters, if you want 100 intervals or millions.
Typical sizes for MainArray and ResultsArray would be 1000 x 1000 to 10.000 x 10.000.
CompArray could have anything between 20 and 200 rows.

Sign in to comment.

 Accepted Answer

Jan
Jan on 13 Dec 2021
Edited: Jan on 13 Dec 2021
Easier to run in the forum and maybe faster already:
N = 1000;
M = randi([1, 1000], N, N);
C = sort(randi([1, 1000], 100, 2), 2);
C1 = C(:, 1);
C2 = C(:, 2);
tic
R1 = ones(size(M));
for Row = 1:size(M, 1)
for Col = 1:size(M, 2)
if(any((M(Row,Col) >= C(:,1)) & (M(Row,Col) <= C(:,2))))
R1(Row,Col) = 0;
end
end
end
toc
tic
R2 = ones(size(M));
for k = 1:numel(M)
if any((M(k) >= C1) & (M(k) <= C2))
R2(k) = 0;
end
end
toc
% Alternatively:
tic
R3 = ones(size(M));
for k = 1:numel(M)
R3(k) = all((M(k) < C1) | (M(k) > C2));
end
toc
tic
R4 = true(size(M));
for k = 1:size(C1, 1)
R4(R4 & (M >= C1(k)) & (M <= C2(k))) = false;
end
toc
tic
R5 = true(size(M));
for k = 1:size(C1, 1)
R5 = R5 & (M < C1(k) | M > C2(k));
end
toc
isequal(R1, R2, R3, R4, R5)
% R2018b, Win10, i5 mobil:
% Elapsed time is 0.429244 seconds. original
% Elapsed time is 0.335571 seconds. simplilied
% Elapsed time is 0.351330 seconds. no IF
% Elapsed time is 0.247861 seconds. loop over intervals
% Elapsed time is 0.148806 seconds. loop over intervals 2

2 Comments

Super, thanks!
I am not sure if this really counts as "vectorization" (since you still have to keep the "for" loop), but it most certainly gives much faster results!
Regards,
Cristian
The vectorized version are much slower, therefore I did not copy them. Vectorisation is not efficient, if large intermediate arrays are required, which do not match into the CPU cache.

Sign in to comment.

More Answers (0)

Categories

Find more on Graphics Performance in Help Center and File Exchange

Products

Release

R2021b

Asked:

on 13 Dec 2021

Commented:

Jan
on 13 Dec 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!