我想用for_each
循环来处理矩阵向量乘法的序列。
所以我做了这样的代码。
template <typename EigenMat, typename EigenVec>
struct MatVecMult{
MatVecMult(const EigenMat& m){
mat = m;
}
void operator()(EigenVec& v)
{
v = mat*v;
}
EigenMat mat;
};
//this is main loop.
Eigen::Matrix2d mat;
vector<Eigen::Vector2d> v_array; //very huge vector, i.e 1000000.
MatVecMult<Eigen::Matrix2d, Eigen::Vector2d> functor(mat);
std::for_each(v_array.begin(), v_array.end(), functor);
现在问题是上面的代码要求我指定MatVecMul
仿函数的模板参数。
但不是这样,我想让代码看起来更像下面的内容。
Eigen::Matrix2d mat1;
vector<Eigen::Vector2d> v_array1;
Eigen::Matrix4d mat2;
vector<Eigen::Vector4d> v_array2;
std::for_each(v_array1.begin(), v_array1.end(), MatVecMult(mat1));
std::for_each(v_array2.begin(), v_array2.end(), MatVecMult(mat2));
此代码适用于任何类型的Eigen::Matrix
和Eigen::Vector
。
这可能吗?
答案 0 :(得分:0)
首先,您可以改进MatVecMulti
类,使operator()
成为模板方法:
template <typename EigenMat>
struct MatVecMult {
MatVecMult(const EigenMat& m){
mat = m;
}
template <typename T>
void operator()(T& v)
{
v = mat*v;
}
EigenMat mat;
};
// So now it can be used as
Eigen::Matrix2d mat;
vector<Eigen::Vector2d> v_array;
MatVecMult<Eigen::Matrix2d> functor(mat);
std::for_each(v_array.begin(), v_array.end(), functor);
可以删除MatVecMulti
的最后一个模板参数吗?这取决于。
由于乘数数据存储在MatVecMulti
中,因此在使用之前需要使用乘数类型。这就是你MatVecMult<Eigen::Matrix2d> functor(mat);
但不是这样,我想让代码看起来更像 以下。
Eigen::Matrix2d mat1;
vector<Eigen::Vector2d> v_array1;
Eigen::Matrix4d mat2;
vector<Eigen::Vector4d> v_array2;
std::for_each(v_array1.begin(), v_array1.end(), MatVecMult(mat1));
std::for_each(v_array2.begin(), v_array2.end(), MatVecMult(mat2));
如果Eigen::Matrix2d
和Eigen::Matrix4d
共享一个公共基类,例如Eigen::MyFakeBaseMatrix
,您可以通过多态存储/使用乘数,并将构造函数转换为模板方法:
struct MatVecMult {
template <typename prod_t>
MatVecMult(const prod_t& m){
mat = unique_ptr<MyFakeBaseMatrix>(new prod_t(m));
}
template <typename T>
void operator()(T& v)
{
v = (*mat)*v;
}
std::unique_ptr<MyFakeBaseMatrix> mat;
};
答案 1 :(得分:0)
您可以使用EigenMat
的模板参数来推导EigenVec
的矢量类型。以下用g ++编译,但不是VS2013。我没有针对运行时问题对其进行测试。
#include <iostream>
#include <algorithm>
#include <vector>
#include <Eigen/Core>
#include <Eigen/StdVector>
using std::vector;
template <typename EigenMat>
struct MatVecMult{
typedef typename EigenMat::Scalar Scalar;
typedef Eigen::Matrix<Scalar, EigenMat::ColsAtCompileTime, 1> EigenVec;
MatVecMult(const EigenMat& m){
mat = m;
}
void operator()(EigenVec& v)
{
v = mat*v;
}
EigenMat mat;
};
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector4d);
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Vector2d);
int main()
{
Eigen::Matrix2d mat1;
vector<Eigen::Vector2d> v_array1;
Eigen::Matrix4d mat2;
vector<Eigen::Vector4d> v_array2;
std::for_each(v_array1.begin(), v_array1.end(), MatVecMult<Eigen::Matrix2d>(mat1));
std::for_each(v_array2.begin(), v_array2.end(), MatVecMult<Eigen::Matrix4d>(mat2));
return 0;
}
请勿忘记使用std::vector
处理与Eigen静态大小类型的对齐问题。