对 Matrix<> 或 Block<> 进行数组运算的特征函数
Eigen function that does array operations on Matrix<> or Block<>
我想制作一个可以接受 Matrix<> 或 Block<> 对象的函数。
示例:
#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;
}
以下 不 工作,因为 DenseBase 没有 'array' 方法:
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;
}
我该怎么做?
如果两种对象都支持您希望执行的操作,则:
template <typename T>
double example_function(const T& input){
double d1 = input.array().pow(2).sum();
double d2 = input.rowwise().norm().sum();
return d1 + d2;
}
首先,您的原始代码(const MatrixXd&
)确实有效,但它会生成不必要的副本。要通过模板函数同时接受 Matrix<...>
和 Block<Matrix<...> >
对象,请使用 MatrixBase
而不是 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;
}
但是,在您的示例代码中 m1.block(1,0)
无效,因为您需要指定大小以及 start-index,例如,这些工作:
m1.block<1,2>(1,0);
m1.block(1,0, 1,2);
和m1.Random()
应该是m1.setRandom()
.
我想制作一个可以接受 Matrix<> 或 Block<> 对象的函数。
示例:
#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;
}
以下 不 工作,因为 DenseBase 没有 'array' 方法:
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;
}
我该怎么做?
如果两种对象都支持您希望执行的操作,则:
template <typename T>
double example_function(const T& input){
double d1 = input.array().pow(2).sum();
double d2 = input.rowwise().norm().sum();
return d1 + d2;
}
首先,您的原始代码(const MatrixXd&
)确实有效,但它会生成不必要的副本。要通过模板函数同时接受 Matrix<...>
和 Block<Matrix<...> >
对象,请使用 MatrixBase
而不是 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;
}
但是,在您的示例代码中 m1.block(1,0)
无效,因为您需要指定大小以及 start-index,例如,这些工作:
m1.block<1,2>(1,0);
m1.block(1,0, 1,2);
和m1.Random()
应该是m1.setRandom()
.