Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiply a 3D matrix with a 2D matrix

Suppose I have an AxBxC matrix X and a BxD matrix Y.

Is there a non-loop method by which I can multiply each of the C AxB matrices with Y?

like image 999
Jacob Avatar asked Nov 16 '09 22:11

Jacob


People also ask

Can you multiply a 2D matrix by a 3D matrix?

It is easy to use. Multiply n-dimensional matrices (actually it can multiply arrays of 2-D matrices) It performs other matrix operations (transpose, Quadratic Multiply, Chol decomposition and more) It uses C compiler and multi-thread computation for speed up.

Can you multiply 3D matrices?

A 3D matrix is nothing but a collection (or a stack) of many 2D matrices, just like how a 2D matrix is a collection/stack of many 1D vectors. So, matrix multiplication of 3D matrices involves multiple multiplications of 2D matrices, which eventually boils down to a dot product between their row/column vectors.

Can you multiply two matrices with different dimensions?

You can only multiply two matrices if their dimensions are compatible , which means the number of columns in the first matrix is the same as the number of rows in the second matrix. If A=[aij] is an m×n matrix and B=[bij] is an n×p matrix, the product AB is an m×p matrix.


2 Answers

As a personal preference, I like my code to be as succinct and readable as possible.

Here's what I would have done, though it doesn't meet your 'no-loops' requirement:

for m = 1:C      Z(:,:,m) = X(:,:,m)*Y;  end 

This results in an A x D x C matrix Z.

And of course, you can always pre-allocate Z to speed things up by using Z = zeros(A,D,C);.

like image 71
Zaid Avatar answered Sep 20 '22 18:09

Zaid


You can do this in one line using the functions NUM2CELL to break the matrix X into a cell array and CELLFUN to operate across the cells:

Z = cellfun(@(x) x*Y,num2cell(X,[1 2]),'UniformOutput',false); 

The result Z is a 1-by-C cell array where each cell contains an A-by-D matrix. If you want Z to be an A-by-D-by-C matrix, you can use the CAT function:

Z = cat(3,Z{:}); 



NOTE: My old solution used MAT2CELL instead of NUM2CELL, which wasn't as succinct:

[A,B,C] = size(X); Z = cellfun(@(x) x*Y,mat2cell(X,A,B,ones(1,C)),'UniformOutput',false); 
like image 38
gnovice Avatar answered Sep 18 '22 18:09

gnovice