2017-08-29 5 views
0

Je pense que cela devrait être une chose très simple mais je ne la trouve pas résolue. J'essaye de faire une double contraction de deux tenseurs d'ordre de senond. Tout fonctionne bien, mais le résultat de la double contraction est un type Eigen:Eigen :: Double contraction du tenseur à la valeur scalaire

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> > > 

mais je besoin d'un double. Je peux l'imprimer mais ce n'est pas possible pour moi de travailler avec.

Le code est le suivant

#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 

} 

je besoin d'une fonction ou d'appeler pour obtenir la valeur du résultat, l'espoir que quelqu'un pourrait me aider.

Vive Jonas

Répondre

1

je résolu le problème, mais pense que cela va vous aider aussi si vous travaillez avec le module Eigen :: Tensor.

Comme écrit here dans la section Opérations Tensor et C de la "auto":

Parce que les opérations Tensor créer des opérateurs de tenseur, le mot-cléautoC++ n'a pas son sens intuitif. Lorsque vous utilisezautovous ne recevez pas un Tensor comme résultat, mais plutôt une expression non-évaluée ...

Ainsi, le résultat d'une contraction du tenseur est un

Eigen::TensorContractionOp<...> 

et non un tenseur à partir de laquelle nous pouvons obtenir ses éléments. Nous avons donc besoin de connaître la taille du tenseur résultant. Le problème est que le résultat doit être un tenseur scalaire qui est fait avec vide Eigen::Sizes<>

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

Voici le code de fonctionnement. J'espère que cela aide quelqu'un ...

#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"; 
}