Conditional array accumulation inside parfor

I have a situation were I am testing a condition inside a parfor loop, and if true append the results of a computation to an array. A simplified example is as follows
ary = [];
parfor n=1:N
for m = 1:M
if (f(m,n)>0) % do some test, this is not easily vectorizable
ary = [ary; n m];
end
end
end
I would like, however, to avoid growing arrays in the loop.
I could estimate an upperbound for the size of ary and try to do it this way,
ary = zeros(ubound,2);
ind = 0;
parfor n=1:N
for m = 1:M
if (f(m,n)>0) % do some test, this is not easily vectorizable
ind = ind + 1;
ary(ind,:) = [n m]; % such indexing will not work within parfor
end
end
end
but that wouldn't work as shown in the comment.
Another idea I had was using a logical array to keep track of the conditional result.
condary = false(N*M);
for k = 1:N*M % flatten the loop
% get n and m from k; k = (n-1)*M+m, therefore
m = mod(k,M); if m == 0, m = M; end
n = (k-m)/M+1;
if (f(m,n)>0)
condary(k) = true;
end
end
The desired array, ary, can then be back-constructed from the logical array in a second loop. In fact, ary, can be preallocated at this point. Or the operations meant to be performed using ary can be performed based on condary in a second loop. But this involves flattening the loop.
I was wondering if there are any better ways to do this.

 Respuesta aceptada

Matt J
Matt J el 19 de Mayo de 2024
Editada: Matt J el 19 de Mayo de 2024
map = false(N,M);
parfor k=1:M*N
[n,m]=ind2sub([N,M],k);
map(k) = ( f(m,n)>0 );
end
[I,J]=find(map);
ary=[I,J];

6 comentarios

Siva
Siva el 19 de Mayo de 2024
Editada: Siva el 19 de Mayo de 2024
Matt,
n and m are temporary variables, and can't be used to index arrays inside parfor. When I tried to run it in MATLAB, I got "Valid indices for map are restricted in parfor loops".
I had forgotten about ind2sub, that is better than what I had done.
Sorry. I fixed it.
map(k) = ( f(m,n)>0 );
Siva
Siva el 19 de Mayo de 2024
That is clever, to use the single absolute index!
In reference to my question, I am still wondering, might there be a way to build ary directly in the parfor loop, avoiding the logical array altogether?
I thiink the logical array is the best way, but here is a way to do direct accumulation:
ary=cell(N*M,1);
parfor k=1:M*N
[n,m]=ind2sub([N,M],k);
if (f(m,n)>0) % do some test, this is not easily vectorizable
ary{k}=[n,m];
end
end
ary=cell2mat(ary);
Siva
Siva el 19 de Mayo de 2024
Editada: Siva el 19 de Mayo de 2024
That is pretty cool too. Thank you!
Any implications in terms of the relative memory usage of the two approaches?
Matt J
Matt J el 19 de Mayo de 2024
The logical array approach stores memory contiguously, which is one reason I like it better.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Productos

Versión

R2023b

Preguntada:

el 19 de Mayo de 2024

Comentada:

el 19 de Mayo de 2024

Community Treasure Hunt

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

Start Hunting!

Translated by