2
votes

Whenever I try to create templated functions for Eigen, I get errors like this one:

error C2039: 'Options' : is not a member of 'Eigen::MatrixBase'

This error came from the following function

template<typename Derived1, typename Derived2>
void eig(const MatrixBase<Derived1> & A, MatrixBase<Derived2> & eigenvaluesBuff) {
    EigenSolver<MatrixBase<Derived1>> es(A, false);
    eigenvaluesBuff = es.eigenvalues().real().col(0);
}

The matrix, A, is a MatrixXd that was returned by a different function. Any ideas what I'm doing wrong? If a function returns a MatrixXd, can you not pass that result directly into a templated function in Eigen?

2

2 Answers

1
votes

To complete David's answer, let me add that you can get the Matrix type matching a given expression with PlainObjectType. So a more general solution would be:

template<typename Derived1, typename Derived2>
void eig(const MatrixBase<Derived1> & A, MatrixBase<Derived2> & eigenvaluesBuff) {
    EigenSolver<typename Derived1::PlainObjectType > es(A.derived(), false);
    eigenvaluesBuff = es.eigenvalues().real().col(0);
}
0
votes

The template parameter of EigenSolver needs to be an instantiation of the more specific Eigen::Matrix template, not Eigen::MatrixBase (see the documentation here). So I would change your template function to

template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols, typename Derived2>
void eig(const Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & A, MatrixBase<Derived2> & eigenvaluesBuff) {
    typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> MatrixType;
    EigenSolver<MatrixType> es(A, false);
    eigenvaluesBuff = es.eigenvalues().real().col(0);
}

You could also simplify the function to

template<typename Derived1, typename Derived2>
void eig(const MatrixBase<Derived1> & A, MatrixBase<Derived2> & eigenvaluesBuff) {
    eigenvaluesBuff = A.eigenvalues();
}