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

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 Kommentare

I would like to have the transposed F. i.e., F=F'; is it possible.
@Shravankumar
MTIMESX has input flags that let you say whether you want the multiplication with F, F', or F.'

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Andrei Bobrov
Andrei Bobrov am 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 Kommentare

Ray M
Ray M am 11 Okt. 2021
Great Solution, the solution you have provided is equivalent to:
for i = 1:whatever
b(:,:,i) = F(:,:,i) * x;
end
How would you produce the trasnpose multiplication effect (assuming correct sizes)?
for i = 1:whatever
b(:,:,i) = x * F(:,:,i);
end
Ray M
Ray M am 13 Okt. 2021
Nevermind! I got it :)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (4)

Steven Lord
Steven Lord am 11 Okt. 2021

2 Stimmen

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

3 Kommentare

Too bad it doesn't work with uint8 images (yet)
% Works
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, 'like', rgbImage));
% Doesn't work
maskedRgbImage = pagemtimes(rgbImage, cast(mask, 'like', rgbImage)); % R2020b and later.
Error using pagemtimes
Invalid data types. Input arrays must be double or single.
Error in test (line 10)
maskedRgbImage = pagemtimes(rgbImage, cast(mask, 'like', rgbImage)); % R2020b and later.
It would be great for using a logical 2-D mask image and a 2-D gray scale, or 3-D color, or N-d volumetric image. Can you put in that suggestion?
Ray M
Ray M am 11 Okt. 2021
Bearbeitet: Ray M am 11 Okt. 2021
I am not sure if this meant to be a reply to my question under Andrei Bobrov solution, but it does not appear so. I am simply interested in performing a single matrix multiplication by slices of a 3D matrix with the use of bsxfun as follows:
mat_mxn * 3Dmat_nxkxl
and
3Dmat_mxnxk * mat_nxh
1) We note that A * B ~= B * A. Note that Andrei Bobrov solution just does 3Dmat_mxnxk * mat_mxh.
2) @times in bsxfun perform .* not * and that is why Andrei Bobrov does a sum as well.
Thanks
@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.

Melden Sie sich an, um zu kommentieren.

Edric Ellis
Edric Ellis am 4 Aug. 2014

1 Stimme

With Parallel Computing Toolbox, you can perform this on the GPU using PAGEFUN.

1 Kommentar

Nils Melchert
Nils Melchert am 19 Mai 2020
Bearbeitet: Nils Melchert am 19 Mai 2020
Is there the possibility to get a minimal example for exactly this use case? I am struggling with the same thing.

Melden Sie sich an, um zu kommentieren.

Matt J
Matt J am 2 Aug. 2014
Bearbeitet: Matt J am 2 Aug. 2014

0 Stimmen

See MTIMESX.

9 Kommentare

Søren sønderby Commented:
I briefly looked at MTIMESX but I didn't find any installation instructions for OSX.
How would you do it using GPU?
Matt J
Matt J am 2 Aug. 2014
Bearbeitet: Matt J am 2 Aug. 2014
How would you do it using GPU?
You could make a GPU implementation of the for-loop in your original post. Simply pre-convert F, x, and b to gpuArray objects.
To use GPU computing you also need the Parallel Computing Toolbox. Have you purchased that?
Matt J
Matt J am 2 Aug. 2014
Bearbeitet: Matt J am 2 Aug. 2014
Also, for small array dimensions like what you've shown, a GPU-driven version might not be faster than on the CPU. Matrix multiplications in MATLAB are already very well-multithreaded on the CPU.
I have the GPU toolbox (academic license). Do you have any experience installing MTIMESX on os x?
The Mathworks does not make any toolbox by the name "GPU Toolbox". If you have one, it must have been written by some third party company.
I meant i have the Parallel Computing Toolbox
Matt J
Matt J am 2 Aug. 2014
Bearbeitet: Matt J am 2 Aug. 2014
Do you have any experience installing MTIMESX on os x
Don't see why it would be different than Windows, except I'm not sure that SPEEDOMP would be supported. What happens when you try to compile with mtimesx_build?
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.

Melden Sie sich an, um zu kommentieren.

Image Analyst
Image Analyst am 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.

1 Kommentar

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)));

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Sparse Matrices finden Sie in Hilfe-Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by