112 views (last 30 days)

Show older comments

What is the fastest way multiply a 2d matrix with each slice of a 3d matrix?

x = rand(1000,200);

F = rand(100,1000,10);

b = zeros(100,200,10);

for i = 1:10

b(:,:,i) = F(:,:,i)*x;

end

Andrei Bobrov
on 2 Aug 2014

f1 = size(F);

x1 = size(x);

b = reshape(sum(bsxfun(@times,reshape(F,[f1(1),1,f1(2:3)]),...

reshape(x',1,x1(2),[])),3),f1(1),x1(2),[]);

Steven Lord
on 11 Oct 2021

In release R2020b we introduced the pagemtimes function for this purpose.

Steven Lord
on 12 Oct 2021

@Image Analyst Your bsxfun call is calling times not mtimes. times can work with implicit expansion.

A = int16(magic(4));

B = repmat(A, 1, 1, 3);

C = A.*B

mtimes isn't fully defined for integer arrays. If mtimes doesn't work pagemtimes probably shouldn't.

D = A*A % errors

Edric Ellis
on 4 Aug 2014

Nils Melchert
on 19 May 2020

Image Analyst
on 2 Aug 2014

You can do it easily if the number of rows and columns in your 3D and 2D match, which they don't in your example:

rows = 1000;

columns = 200;

slices = 10;

x = rand(rows, columns);

F = rand(rows, columns, slices);

b = zeros(rows, columns, slices);

for slice = 1 : slices

b(:,:, slice) = F(:,:, slice) .* x; % Use dot star, not just star.

end

If the number of rows and columns are different you need to make some decisions about exactly where you want to multiply, if one is smaller than the other, or one extends out past the other.

Image Analyst
on 2 Aug 2014

Alternate way. Not sure which is faster:

% Mask the 3D image called "image3D" with 2D image called "mask".

masked3DImage = bsxfun(@times, image3D, cast(mask, class(image3D)));

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

Start Hunting!