Eigen::Tensor double contraction to scalar value

1k views Asked by At

I think this should be a really simple thing but I don't get it solved. I'm trying to do a double contraction of two senond order Eigen tensors. Everything works well, but the result of the double contraction is an Eigen type:

Eigen::TensorContractionOp<const std::array<Eigen::IndexPair<int>, 2ul>, const Eigen::TensorFixedSize<double, Eigen::Sizes<3l, 3l> >, const Eigen::TensorFixedSize<double, Eigen::Sizes<3l, 3l> > >

but I need a double. I can print it but its not possible for me to work with it.

The code is the following

#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>

int main()
{

    auto tensor1 = Eigen::TensorFixedSize<double, Eigen::Sizes<3,3>>();
    tensor1.setValues({ {1, 0, 0},
                        {0, 1, 0},
                        {0, 0, 1} });
    std::cout << "tensor1:\n" << tensor1 << "\n";

    auto tensor2 = Eigen::TensorFixedSize<double, Eigen::Sizes<3,3>>();
    tensor2.setValues({ {2, 0, 0},
                        {0, 2, 0},
                        {0, 0, 2} });
    std::cout << "tensor2:\n" << tensor2 << "\n";

    Eigen::array<Eigen::IndexPair<int>, 2> contraction_pair0011
        = { Eigen::IndexPair<int>(0, 0), Eigen::IndexPair<int>(1, 1)};

    auto tensor1_tensor2 = tensor1.contract(tensor2, contraction_pair0011);
    std::cout << "tensor1 : tensor2:\n" << tensor1_tensor2 << "\n";

    // double value = tensor1_tensor2; // won't compile

}

I need a function or call to get the value of the result, hope someone could help me.

Cheers Jonas

1

There are 1 answers

0
BeiHerta On BEST ANSWER

I solved the problem but think it will help you too if you are working with Eigen::Tensor module.

As written here in section Tensor Operations and C++ "auto":

Because Tensor operations create tensor operators, the C++ auto keyword does not have its intuitive meaning. When you use auto you do not get a Tensor as a result but instead a non-evaluated expression...

So the result of a tensor contraction is a

Eigen::TensorContractionOp<...>

and not a tensor from which we can get its elements. So we need to know the size of the resulting tensor. The Problem was that the result has to be a scalar tensor which is done with empty Eigen::Sizes<>

Eigen::TensorFixedSize<double, Eigen::Sizes<>>

Here the running code. I hope it helps somebody...

#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>

int main()
{
    auto tensor1 = Eigen::TensorFixedSize<double, Eigen::Sizes<3,3>>();
    tensor1.setValues({ {1, 0, 0},
                        {0, 1, 0},
                        {0, 0, 1} });
    std::cout << "tensor1:\n" << tensor1 << "\n";

    auto tensor2 = Eigen::TensorFixedSize<double, Eigen::Sizes<3,3>>();
    tensor2.setValues({ {2, 0, 0},
                        {0, 2, 0},
                        {0, 0, 2} });
    std::cout << "tensor2:\n" << tensor2 << "\n";


    Eigen::array<Eigen::IndexPair<int>, 2> contraction_pair0011
        = { Eigen::IndexPair<int>(0, 0), Eigen::IndexPair<int>(1, 1)};

    Eigen::TensorFixedSize<double, Eigen::Sizes<>> tensor1_tensor2 = tensor1.contract(tensor2, contraction_pair0011);
    std::cout << "tensor1 : tensor1:\n" << tensor1_tensor2 << "\n";

    double t1_t2 = tensor1_tensor2(0);
    std::cout << "result in double:\n" << t1_t2 << "\n";
}