Double dot product of two tensors
Solution 1
The colon operator in MATLAB doesn't do what you expect, as it serves another functionality. In fact, there is no built-in implementation for a double inner product in MATLAB. You need to implement it by yourself, for instance:
idx = max(0, ndims(A) - 1); %// Index of first common dimension
B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
double_dot_prod = squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx));
where A
and B
are your tensors (i.e multi-dimensional matrices). Vectorizing this was a hard nut to crack, so I hope I got the math right!
If you want, you can put this code in a function for convenience. For the sake of good practice, also verify that both tensors are of second rank or higher. Here's a friendly copy-paste version for you:
function C = double_dot(A, B)
assert(~isvector(A) && ~isvector(B))
idx = max(0, ndims(A) - 1);
B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
C = squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx));
A word of advice: I suggest that you read online tutorials to get yourself familiar with the basics of the MATLAB language.
Solution 2
It's very unfortunate, but MATLAB has not implemented an inner product of tensors in their standard library to my knowledge. To produce a scalar version of the inner product, you need to either inefficiently iterate through each entry like:
function C = double_dot(A,B)
for i=1:1:3
for j=1:1:3
C = C + A(i,j)*B(i,j);
end
end
Or you can run a slight modification of Eitan's vectorized code (above). His code produces a vector. The inner product of two tensors should be a scalar. So you need to sum across the final array that his code produces.
function C = double_dot(A, B)
assert(~isvector(A) && ~isvector(B))
idx = max(0, ndims(A) - 1);
B_t = permute(B, circshift(1:ndims(A) + ndims(B), [0, idx - 1]));
C = sum(squeeze(sum(squeeze(sum(bsxfun(@times, A, B_t), idx)), idx)));
Eitan's code is an implementation of the dot
function in matlab (see https://www.mathworks.com/help/matlab/ref/dot.html). Note the section on the dot product of matricies. Instead you should more simply use:
function C = double_dot(A,B)
C = sum(dot(A,B));
ISara sky
Updated on June 04, 2022Comments
-
ISara sky about 2 years
I have two tensors:
A
is a second order tensor andB
is a fourth order tensor. I know that when computing the double dot product (:) of two tensors, the rank of the resulting tensor will be decreased by two, so in my example the result should be a second order tensor.However, when I write this code in MATLAB, it gives the following error:
Matrix dimensions must agree.
How can I solve this problem?