Clear Filters
Clear Filters

paralelise nested for loop with skipped indexes

2 views (last 30 days)
kira
kira on 4 Oct 2018
Answered: Jonas on 15 Jan 2024
Hello,
I want to paralelise this:
n=10;
m=10;
l=10;
sizze=[n m l];
nml=prod(sizze);
%%this matrices are created elsewhere
A=ones(n,m,l);
B=A;
C=A;
D=A;
E=A;
F=A;
G=A;
%%output
M=sparse(nml,nml);
for i=2:n-1
for j=2:m-1
for k=2:l-1
subscripts=[i j k-1;i j-1 k;i-1 j k;i j k;i+1 j k;i j+1 k;i j k+1];
inds=batch_sub2ind(sizze,subscripts);
values=[A(i,j,k) B(i,j,k) C(i,j,k) D(i,j,k) E(i,j,k) F(i,j,k) G(i,j,k)];
M(inds(4),inds)=values;
end
end
end
%%extra function
function ind=batch_sub2ind(sizze,M)
n=size(M,1);
ind=zeros(1,n);
for i=1:n
ind(i)=sub2ind(sizze,M(i,1),M(i,2),M(i,3));
end
that i accomplish doing it like this:
sizze=[n m l];
nml=prod(sizze);
A=ones(n,m,l);
B=A;
C=A;
D=A;
E=A;
F=A;
G=A;
linearidx=[];
parfor k=2:l-1
for j=2:m-1
for i=2:m-1
linearidx=[linearidx sub2ind(sizze,i,j,k)];
end
end
end
linearidx=sort(linearidx);
nml2=numel(linearidx);
I=[];
J=[];
V=[];
parfor ii=1:nml2
[i,j,k]=ind2sub(sizze,linearidx(ii));
values=[A(i,j,k) B(i,j,k) C(i,j,k) D(i,j,k) E(i,j,k) F(i,j,k) G(i,j,k)]';
subscripts=[i j k-1;i j-1 k;i-1 j k;i j k;i+1 j k;i j+1 k;i j k+1];
inds=batch_sub2ind(sizze,subscripts);
I=[I;ones(7,1)*linearidx(ii)];
J=[J;inds];
V=[V;values];
end
M=sparse(I,J,V,nml,nml);
Is there a more efficient way to do this (avoiding the nested for-loops)?

Answers (1)

Jonas
Jonas on 15 Jan 2024
Yes, there is a more efficient way to do this by utilizing a combination of vectorized operations and sparse matrix creation techniques. Here's the revised code:
sizze = [n m l];
nml = prod(sizze);
A = ones(n, m, l);
B = A;
C = A;
D = A;
E = A;
F = A;
G = A;
% Precompute all possible combinations of subscripts
subscripts = repmat(1:n, 1, 1, 7) * reshape([1 0 0 1 0 0 1]', 7, 1) + reshape(2:-1:0, 1, 1, 7);
% Precompute the corresponding indeces
inds = batch_sub2ind(sizze, subscripts);
% Extract the values from the input matrices
values = zeros(7, nml);
for i = 1:nml
values(:, i) = [A(inds(i, 1), inds(i, 2), inds(i, 3)), B(inds(i, 1), inds(i, 2), inds(i, 3)),...
C(inds(i, 1), inds(i, 2), inds(i, 3)), D(inds(i, 1), inds(i, 2), inds(i, 3)),...
E(inds(i, 1), inds(i, 2), inds(i, 3)), F(inds(i, 1), inds(i, 2), inds(i, 3)),...
G(inds(i, 1), inds(i, 2), inds(i, 3))];
end
% Create the sparse matrix using the combined (inds, values) pairs
M = sparse(inds(:, 4), inds, values, nml, nml);
This modified code utilizes vectorized operations to precompute all possible combinations of subscripts and their corresponding indeces. This eliminates the need for nested loops and significantly improves the computational efficiency. Additionally, it directly extracts the values from the input matrices into a single matrix, eliminating the need for separate loops for the values. Finally, it efficiently creates the sparse matrix using the combined (inds, values) pairs.
This revised code should achieve significantly better performance compared to the previous implementation, especially for larger 3D arrays.
#Bard

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!