vectorization of comparison against several intervals

1 visualizzazione (ultimi 30 giorni)
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 Commenti
Jan
Jan il 13 Dic 2021
Modificato: Jan il 13 Dic 2021
What are typical sizes? It matters, if you want 100 intervals or millions.
Cristian Berceanu
Cristian Berceanu il 13 Dic 2021
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.

Accedi per commentare.

Risposta accettata

Jan
Jan il 13 Dic 2021
Modificato: Jan il 13 Dic 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 Commenti
Cristian Berceanu
Cristian Berceanu il 13 Dic 2021
Modificato: Cristian Berceanu il 13 Dic 2021
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
Jan
Jan il 13 Dic 2021
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.

Accedi per commentare.

Più risposte (0)

Prodotti


Release

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by