Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take outer product of more than two matrices in one shot, in matlab?

I want to compute y = a⊗a⊗a, where a is a n-by-1 vector, and is the outer product operator. In this case y should be an n-by-n-by-n tensor.

If y = a⊗a, it is easy. I simply do:

y = a * a' 

But what to do in the first case? How do I compute this outer product efficiently in MATLAB if there are more than two vectors?

like image 285
Cem S. Avatar asked Jan 16 '13 10:01

Cem S.


People also ask

How do you find the outer product of two vectors in Matlab?

Description. C = cross( A,B ) returns the cross product of A and B . If A and B are vectors, then they must have a length of 3. If A and B are matrices or multidimensional arrays, then they must have the same size.

What is the outer product of two matrices?

In linear algebra, the outer product of two coordinate vectors is a matrix. If the two vectors have dimensions n and m, then their outer product is an n × m matrix. More generally, given two tensors (multidimensional arrays of numbers), their outer product is a tensor.

How do you do a tensor product in Matlab?

K = kron( A,B ) returns the Kronecker tensor product of matrices A and B . If A is an m -by- n matrix and B is a p -by- q matrix, then kron(A,B) is an m*p -by- n*q matrix formed by taking all possible products between the elements of A and the matrix B .


2 Answers

In a multi-dimensional (tensor) case of y = u⊗v, I believe that you need to shift the dimensions of the second operand like so:

v_t = permute(v, circshift(1:(ndims(u) + ndims(v)), [0, ndims(u)]));

and then multiply them with bsxfun:

y = bsxfun(@times, u, v_t);

The regular matrix multiplication is defined only for vector and 2-D matrices, so we couldn't use it in the general case.

Also note that this computation still fails if the second operand is a 1-D vector, because ndims returns 2 instead of 1 for vectors. For this purpose, lets define our own function that counts dimensions:

my_ndims = @(x)(isvector(x) + ~isvector(x) * ndims(x));

To complete the answer, you can define a new function (e.g. an anonymous function), like so:

outprod = @(u, v)bsxfun(@times, u, permute(v, circshift(1:(my_ndims(u) + my_ndims(v)), [0, my_ndims(u)])));

and then use it as many times as you want. For example, y = a×a×a would be computed like so:

y = outprod(outprod(a, a), a);

Of course, you can write a better function that takes a variable number of arguments to save you some typing. Something along these lines:

function y = outprod(u, varargin)
    my_ndims = @(x)(isvector(x) + ~isvector(x) * ndims(x));
    y = u;
    for k = 1:numel(varargin)
        v = varargin{k};
        v_t = permute(v, circshift(1:(my_ndims(y) + my_ndims(v)),[0, my_ndims(y)]));
        y = bsxfun(@times, y, v_t);
    end

I hope I got the math right!

like image 104
Eitan T Avatar answered Oct 15 '22 02:10

Eitan T


You can use as well the kron function:

kron(a * a', a)

or when four outer (kronecker tensor) products needed:

kron(kron(a * a', a), a)

and so on. The last one gives you a m x n matrix, where m = n * n * n.

If adding dimensions is desired as going on with the products, you may use the reshape function:

reshape(kron(a * a', a), [n, n, n])

or

reshape(kron(kron(a * a', a), a), [n, n, n, n])

and so on. The last one gives you a n x n x n x n tensor.

like image 32
hamid attar Avatar answered Oct 15 '22 03:10

hamid attar