# Multiplying a 2d matrix with each slice of 3d matrix

99 views (last 30 days)
Søren sønderby on 1 Aug 2014
Commented: Ray M on 13 Oct 2021
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
##### 2 CommentsShowHide 1 older comment
Matt J on 4 Aug 2014
@Shravankumar
MTIMESX has input flags that let you say whether you want the multiplication with F, F', or F.'

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),[]);
##### 2 CommentsShowHide 1 older comment
Ray M on 13 Oct 2021
Nevermind! I got it :)

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
C = 4×4×3 int16 array
C(:,:,1) = 256 4 9 169 25 121 100 64 81 49 36 144 16 196 225 1 C(:,:,2) = 256 4 9 169 25 121 100 64 81 49 36 144 16 196 225 1 C(:,:,3) = 256 4 9 169 25 121 100 64 81 49 36 144 16 196 225 1
mtimes isn't fully defined for integer arrays. If mtimes doesn't work pagemtimes probably shouldn't.
D = A*A % errors
Error using *
MTIMES (*) is not fully supported for integer classes. At least one argument must be scalar.

Edric Ellis on 4 Aug 2014
With Parallel Computing Toolbox, you can perform this on the GPU using PAGEFUN.
Nils Melchert on 19 May 2020
Is there the possibility to get a minimal example for exactly this use case? I am struggling with the same thing.

Matt J on 2 Aug 2014
Edited: Matt J on 2 Aug 2014
See MTIMESX.
Søren sønderby on 2 Aug 2014
It fails with the following output:
Non-PC auto build is not currently supported. You will have to
manually compile the mex routine. E.g., as follows:
>> blas_lib = 'the_actual_path_and_name_of_your_systems_BLAS_library'
>> mex('-DDEFINEUNIX','mtimesx.c',blas_lib)
or
>> mex('-DDEFINEUNIX','-largeArrayDims','mtimesx.c',blas_lib)
I tried to google the blas library path on osx 10.7.5 with no luck so far.

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".