Reputation: 3
I need a function that is capable of accepting both an Eigen::Map or Eigen::Matrix as input and output an Eigen::Matrix of the same type.
Using Eigen 3.4.0
My current implementation is as follows:
template<typename T, typename E>
Matrix<T, Dynamic, Dynamic> foo(E& data_in)
{
// typename T: scalar type (int, double, complex<float>, etc.). used to initialize data_out
// typename E: Eigen class (Matrix, Map, etc.). used to accept any eigen type
// Usage: Matrix<T,-,-> data_out = foo<T>(data_in)
// e.g. Matrix<double, Dynamic, Dynamic> eg = foo<double>(data_in) // data in is Map<Matrix<double, Dynamic, Dynamic>>
It works but seems like bad practice. I have to define it in the header file to compile and I would think there's a better way to do this.
Upvotes: 0
Views: 266
Reputation: 13310
Eigen classes contain a type definition PlainObject
that is the simple Matrix or Array type for a particular expression. The documentation has a section on how to write functions that accept Eigen objects
In summary, this should work for you:
template<class Derived>
typename Eigen::MatrixBase<Derived>::PlainObject
foo(const Eigen::MatrixBase<Derived>& data_in)
{
using matrix_type =
typename Eigen::MatrixBase<Derived>::PlainObject;
matrix_type out = …;
return out;
}
Other typedefs such as Scalar
are also available.
My apologies, I misread your problem. While the above is a better way to write your template, it seems like you want to get away from writing templates.
Well, you cannot avoid writing templates if you need multiple scalar types, but you can coalesce for different matrix sub-types (block expressions, Map, etc.) using Eigen::Ref
Header:
// overload for floats
Eigen::MatrixXf foo(const Eigen::Ref<const Eigen::MatrixXf>& in_data);
// overload for doubles
Eigen::MatrixXd foo(const Eigen::Ref<const Eigen::MatrixXd>& in_data);
Source file:
namespace {
// common implementation
template<class Derived>
typename Eigen::MatrixBase<Derived>::PlainObject
implement_foo(const Eigen::MatrixBase<Derived>& data_in)
{
using matrix_type =
typename Eigen::MatrixBase<Derived>::PlainObject;
matrix_type out = …;
return out;
}
} /* namespace anonymous */
Eigen::MatrixXf foo(const Eigen::Ref<const Eigen::MatrixXf>& in_data)
{ return implement_foo(in_data); }
Eigen::MatrixXd foo(const Eigen::Ref<const Eigen::MatrixXd>& in_data)
{ return implement_foo(in_data); }
The usage of Eigen::Ref
is explained in the same Eigen documentation page I linked above.
Upvotes: 1