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

조회 수: 58 (최근 30일)
Søren sønderby
Søren sønderby 2014년 8월 1일
댓글: Ray M 2021년 10월 13일
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
Shravankumar P
Shravankumar P 2014년 8월 2일
I would like to have the transposed F. i.e., F=F'; is it possible.
Matt J
Matt J 2014년 8월 4일
@Shravankumar
MTIMESX has input flags that let you say whether you want the multiplication with F, F', or F.'

댓글을 달려면 로그인하십시오.

채택된 답변

Andrei Bobrov
Andrei Bobrov 2014년 8월 2일
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
Ray M
Ray M 2021년 10월 11일
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 2021년 10월 13일
Nevermind! I got it :)

댓글을 달려면 로그인하십시오.

추가 답변 (4개)

Steven Lord
Steven Lord 2021년 10월 11일
In release R2020b we introduced the pagemtimes function for this purpose.
  댓글 수: 3
Ray M
Ray M 2021년 10월 11일
편집: Ray M 2021년 10월 11일
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
Steven Lord
Steven Lord 2021년 10월 12일
@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
Edric Ellis 2014년 8월 4일
With Parallel Computing Toolbox, you can perform this on the GPU using PAGEFUN.
  댓글 수: 1
Nils Melchert
Nils Melchert 2020년 5월 19일
편집: Nils Melchert 2020년 5월 19일
Is there the possibility to get a minimal example for exactly this use case? I am struggling with the same thing.

댓글을 달려면 로그인하십시오.


Matt J
Matt J 2014년 8월 2일
편집: Matt J 2014년 8월 2일
See MTIMESX.
  댓글 수: 9
Matt J
Matt J 2014년 8월 2일
편집: Matt J 2014년 8월 2일
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?
Søren sønderby
Søren sønderby 2014년 8월 2일
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
Image Analyst 2014년 8월 2일
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
Image Analyst
Image Analyst 2014년 8월 2일
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)));

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 GPU Computing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by