Kronecker product between two tensors

2019-02-15 17:37发布

问题:

I have two tensor: x is 2-by-2-by-3, y is also 2-by-2-by-3. Define each frontal slice of tensor is x1 x2 x3,y1,y2,y3. xi or yi are 2-by-2 matrix. How can I do kronecker product between x and y in matlab? What I want to get is kron(x1,y1),kron(x2,y2),kron(x3,y3) in matlab simultaneously without any looping.

回答1:

This could be one approach -

%// Pre-processing part
[m,n,r] = size(x) %// Get size
N = m*n %// number of elements in one 3D slice

%// ------------- PART 1: Get indices for each 3D slice

%// Get the first mxm block of kron-corresponding indices and then add to
%// each such block for the indices corresponding to the kron multiplications
%// of each iteration
a1 = bsxfun(@plus,reshape([0:N-1]*N+1,m,m),permute([0:N-1],[1 3 2]))

%// Now, a1 is a 3D array, we need to make 2D array out of it.
%// So, concatenate along rows to make it a "slimish" 2D array
a2 = reshape(permute(a1,[1 3 2]),size(a1,1)*size(a1,3),[])

%// Cut after every N rows to make it a square 2D array.
%// These are the indices for each frontal tensor of kron muliplications
slice_idx = reshape(permute(reshape(a2,N,size(a2,1)/N,[]),[1 3 2]),N,N)

%// -------------  PART 2: Get kron equivalent output

%// Perform x:(Nx1) x y:(1xN) multiplications
vals = bsxfun(@times,reshape(x,m*n,1,r),reshape(y,1,m*n,r)) %//multiplications

%// Get indices for all 3D slices and then index into those multiplications
%// with these for the final kron equivalent output
all_idx=bsxfun(@plus,slice_idx,permute([0:r-1]*m*m*n*n,[1 3 2])) %//all indices
out = vals(all_idx) %// final output of kron equivalent multiplications


回答2:

This works for arbitrary sizes of x and y:

  1. Build a 5D array z. The first two dimensions contain the products of combinations of rows of x and y; the next two contain the products of combinations of columns of x and y; and the fifth is the original third dimension.
  2. That arrray is reshaped, collapsing dimensions first ant second on one hand, and third and fourth on the other hand, to produce the final result:

Code:

z = bsxfun(@times, permute(x, [4 1 5 2 3]), permute(y, [1 4 2 5 3]));  %// step 1
z = reshape(z, size(x,1)^2, size(x,2)^2, size(x,3));                   %//step 2