Double dot product of two tensors

14,529

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));
Share:
14,529
ISara sky
Author by

ISara sky

Updated on June 04, 2022

Comments

  • ISara sky
    ISara sky about 2 years

    I have two tensors: A is a second order tensor and B 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?