the_toast
the_toast

Reputation: 185

Accessing Template values in Eigen using EIGEN_MATRIXBASE_PLUGIN

I am currently trying to adapt the Eigen API to support the following function:

matrix.similarity(similarityTransformationMatrix);

which simply does the following:

similarityTransformationMatrix * matrix * similarityTransformationMatrix.transpose();

My previous implementation only allows to take square matrices for both:

inline MatrixBase< Derived > similarity( const MatrixBase< Derived >& m) const {
  MatrixBase< Derived > t = m;
  t.transposeInPlace();
  return m*(*this)*t;
}

I need instead to be able to call this on a (square, but check for cols = rows not required) matrix, and a similarityTransformation of a different dimension. My problem is that the return matrix is not of the type of either of those, but it can be derived:

Matrix< double, similarityTransformation.rows(), similarityTransformation.rows()>

Could you give me pointers how to implement this? I didn't try implementing it as Eigen::Matrix but I'd rather stick to MatrixBase if possible, but MatrixBase didn't want to accept multiple arguments for the return type of the form

MatrixBase< OtherDerived::Scalar, OtherDerived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime>

Upvotes: 0

Views: 432

Answers (1)

ggael
ggael

Reputation: 29205

First of all, you should notice that you cannot create object of type MatrixBase<...>. MatrixBase is just an abstract base class. In your case, t and the return type of similarity should be a Matrix<...> object.

Second, the template parameters of Matrix<...> must be known at compile time. This means you cannot use similarityTransformation.rows() for that purpose but use TYPEOF_similarityTransformation::RowsAtCompileTime.

Third, your similarity() method must be templated to accept any other Eigen's expression.

Here is a proposal:

template<typename OtherDerived>
Matrix<Scalar, OtherDerived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime>
similarity(const MatrixBase<OtherDerived>& S) const
{
  return S * ( this->derived() * S.adjoint() );
}

This example could be further extended to support mixing reals with complexes... (only Scalar has to be changed to something more complicated for type promotion..)

Upvotes: 1

Related Questions