each columun of a 2D matrix multiply with a 3D array
1 view (last 30 days)
Show older comments
Hi,
I have a 2D matrix and a 3D array, I want to perform the following calculations:
A=rand(200,300);
B=rand(60,60,200);
c=0;
for j=1:300
d=0;
for k=1:200
d=d+A(k,j)*B(:,:,k);
end
c=c+d;
end
The a two for loops, the calculations are very slowly. Are there some good methods to aviod the loops?
0 Comments
Accepted Answer
DGM
on 23 Oct 2021
Edited: DGM
on 23 Oct 2021
This is something, but I bet there are other ways too. This is about 10x faster on my hardware/version, but only about 2-3x faster on the web version.
% array size parameters
pagesz = [10 10];
npages = 10;
wa = 10;
% build test arrays
A = rand(npages,wa);
B = rand(pagesz(1),pagesz(2),npages);
% METHOD 1
tic
c = 0;
for j = 1:wa
d = 0;
for k = 1:npages
d = d+A(k,j)*B(:,:,k);
end
c = c+d;
end
toc
% METHOD 2
tic
c2 = sum(B.*permute(sum(A,2),[3 2 1]),3);
toc
% error metric (should be approximately zero)
immse(c,c2)
% METHOD 3 (Chunru's proposal)
tic
c3 = 0;
for j = 1:wa
c3 = c3 + sum(reshape(A(:, j), 1, 1, []).*B, 3);
end
toc
% error metric (should be approximately zero)
immse(c,c3)
While Chunru's proposal might not be generally as fast as what I proposed, it preserves the order of operations, and so the accumulated error will be smaller.
More Answers (1)
Chunru
on 23 Oct 2021
A=rand(20,30);
B=rand(6,6,20);
c=0;
for j=1:30
d=0;
for k=1:20
d=d+A(k,j)*B(:,:,k);
end
c=c+d;
end
whos
c
c=0;
for j=1:30
c = c + sum(reshape(A(:, j), 1, 1, []).*B, 3);
end
c
See Also
Categories
Find more on Function Creation 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!