Search code examples
c++eigentensor

How to pass an Eigen tensor to a function correctly?


I am having some trouble passing a function inside another function with Eigen tensor. For example, calling the Function1 in the main.cpp code and it works fine, but calling inside of Function2 is causing an error.

void Function1(Eigen::Tensor<std::complex<double>, 3>& vark, Eigen::Tensor<double, 3> Kin, Eigen::Tensor<std::complex<double>, 3>& Out){
    
    Out = vark * Kin * 1i; 

}
void Function2(Eigen::Tensor<std::complex<double>, 3>& In, Eigen::Tensor<std::complex<double>, 3>& kin){
    
    Eigen::Tensor<std::complex<double>, 3> out(nx,ny,nz);  
    out.setZero();
    
    
    Function1(In, kin, Out); //error in Kin as it's passed from the function
}

The error I get:

 error: cannot convert ‘Eigen::TensorEvaluator<Eigen::Tensor<double, 3>, Eigen::DefaultDevice>::EvaluatorPointerType’ {aka ‘double*’} to ‘Eigen::TensorEvaluator<const Eigen::Tensor<std::complex<double>, 3>, Eigen::DefaultDevice>::EvaluatorPointerType’ {aka ‘const std::complex<double>*’}
  152 |     return m_rightImpl.evalSubExprsIfNeeded(m_leftImpl.data());
      |                                                              ^
      |                                                              |
      |                                                              Eigen::TensorEvaluator<Eigen::Tensor<double, 3>, Eigen::DefaultDevice>::EvaluatorPointerType {aka double*}

I am confused why is this happening.

EDIT: I added the header file for the two functions:

void Function1(Eigen::Tensor<std::complex<double>, 3>& vark, Eigen::Tensor<double, 3> Kin, Eigen::Tensor<std::complex<double>, 3>& Out);
void Function2(Eigen::Tensor<std::complex<double>, 3>& In, Eigen::Tensor<std::complex<double>, 3>& kin);

Solution

  • The Kin argument of Function1() is a tensor of double, not of complex<double>. Yet, in Function2() you pass in a complex<double>. So the compiler complains that it cannot convert a tensor of complex<double> to one of double. Fix: Change the Kin argument to Eigen::Tensor<std::complex<double>, 3>, and also add const& for performance reasons:

    void Function1(
        Eigen::Tensor<std::complex<double>, 3> const & vark,
        Eigen::Tensor<std::complex<double>, 3> const & Kin,
        Eigen::Tensor<std::complex<double>, 3> & Out)
    {
      Out = vark * Kin * 1i;
    }
    

    Note: You might also find the documentation about passing Eigen types to functions interesting.