I'd like to make a function that can take both a Matrix<> or a Block<> object.
Example:
#include <iostream>
#include <Eigen/Dense>
//A simplified example of the function I'm making
double example_function(const Eigen::MatrixXd & input){
double d1 = input.array().pow(2).sum();
double d2 = input.rowwise().norm().sum();
return d1 + d2;
}
int main(){
Eigen::MatrixXd m1(3,2);
m1.setRandom();
// This works
example_function(m1);
// I'd like to make this work
example_function(m1.block(1,0,2,2));
return 0;
}
The following does not work, because DenseBase does not have the 'array' method:
template<typename Derived>
double example_function(const Eigen::DenseBase<Derived> & input){
double d1 = input.array().pow(2).sum(); // array() method invalid
double d2 = input.rowwise().norm().sum();
return d1 + d2;
}
How would I go about this?
First of all, your original code (with const MatrixXd&
) does work, but it can generate an unnecessary copy. To accept both Matrix<...>
and Block<Matrix<...> >
objects via a templated function, use MatrixBase
instead of DenseBase
:
template<class Derived>
double example_function(const Eigen::MatrixBase<Derived> & input){
double d1 = input.array().abs2().sum(); // abs2() is simpler/more efficient than pow(2)
double d2 = input.rowwise().norm().sum();
return d1 + d2;
}
However, in your example code m1.block(1,0)
is invalid, as you need to specify the size as well as the start-index, e.g., these work:
m1.block<1,2>(1,0);
m1.block(1,0, 1,2);
and m1.Random()
should be m1.setRandom()
.