Search code examples
c++c++11eigen

Error using Eigen: invalid use of incomplete type ‘const class Eigen


I have the following code that works:

Matrix <float, ny+1, nx> eXX;
eXX.setZero();

Eigen::Matrix< double, (ny+1), (ny)> u; 
    u.setZero(); 
    for(int i = 0; i< nx; i++){
        for(int j = 0; j< ny+1; j++){
            eXX(j + (ny+1)*i) = (i)*2*EIGEN_PI/nx; 
            u(j + (ny+1)*i) = cos(eXX(j + (ny+1)*i));
        }
    }

But when I write the following it doesn't work:

Matrix <float, ny+1, nx> eXX;
eXX.setZero();

Eigen::Matrix< double, (ny+1), (ny)> u; 
    u.setZero(); 
    for(int i = 0; i< nx; i++){
        for(int j = 0; j< ny+1; j++){
            eXX(j + (ny+1)*i) = (i)*2*EIGEN_PI/nx; 
        }
    }
u = eXX.matrix().cos();// -or- std::cos(eXX.array());
    std::cout << u << "\n"; //error

The full error message:

Test.cpp:418:23: error: invalid use of incomplete type ‘const class Eigen::MatrixFunctionReturnValue<Eigen::Matrix<float, 11, 10> >’
  418 |  u = eXX.matrix().cos();
      |                       ^
In file included from /mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/Core:163,
                 from /mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/Dense:1,
                 from Test.cpp:21:
/mnt/c/Users/eigen-3.4.0/eigen-3.4.0/Eigen/src/Core/util/ForwardDeclarations.h:305:34: note: declaration of ‘class Eigen::MatrixFunctionReturnValue<Eigen::Matrix<float, 11, 10> >’
  305 | template<typename Derived> class MatrixFunctionReturnValue;

I guess I could try rewriting eXX without the use of for loop and pass it but that also doesn't work. Also, I read someone recommending adding something like #include <MatrixFunctionReturnValue> which made things a lot worse actually. Thanks.

I am adding my includes as well here:

#define _USE_MATH_DEFINES 
#include <cmath>
#include<math.h>
#include<stdio.h>
#include "fftw3.h"
#include <cstring>
#include <sstream>
#include <string>
#include <sys/resource.h>
#include <iostream> 
#include <vector>
#include <fstream> 
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include <Eigen/SparseCore> 
#include <Eigen/Sparse>


Solution

  • The Matrix class is built for linear algebra. When you want to operate over the elements of a matrix you need to the use the Array class instead. See Eigen documentation on Array. The other way to do this is to use the unaryExpr to take each element of the matrix as an input.

    Here are both methods:

    #include <iostream>
    #include <Eigen/Dense>
    ....
    Eigen::Matrix<double, 3, 3> vals;
    vals.setZero();
    std::cout << vals << '\n';
    std::cout << "******\n";
    std::cout << vals.array().cos() << '\n';
    std::cout << vals << '\n';
    std::cout << "******\n";
    Eigen::Matrix<double, 3, 3> res = vals.unaryExpr([](double a) { return cos(a); });
    std::cout << res << '\n';
    std::cout << vals << '\n';
    

    Take note of how vals changes (and doesn't change) with the various operations.