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?
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.
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.
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 .
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With