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.

 채택된 답변

Matt J
Matt J 2024년 5월 19일
편집: Matt J 2024년 5월 19일

2 개 추천

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

Siva
Siva 2024년 5월 19일
편집: Siva 2024년 5월 19일
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 2024년 5월 19일
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 2024년 5월 19일
편집: Siva 2024년 5월 19일
That is pretty cool too. Thank you!
Any implications in terms of the relative memory usage of the two approaches?
Matt J
Matt J 2024년 5월 19일
The logical array approach stores memory contiguously, which is one reason I like it better.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

릴리스

R2023b

질문:

2024년 5월 19일

댓글:

2024년 5월 19일

Community Treasure Hunt

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

Start Hunting!

Translated by