假设我写了以下内容:
func(Eigen::SparseMatrixBase<double> & A){
for(int i = 0; i < A.outerSize(); i++)
for(Eigen::SparseMatrixBase<double>::InnerIterator it(A,i);it;++it)
// do something
}
此函数不起作用,因为SparseMatrixBase
无法初始化内部迭代器。
所以,我为RowMajor
和ColMajor
定义了函数,然后我尝试模拟这些函数:
template<class Mat, class MatI>
func(Mat & A){
for(int i = 0; i < A.outerSize(); i++)
for(MatI it(A,i);it;++it)
//do something
func<Eigen::SparseMatrix<double,Eigen::RowMajor>,ditto::InnerIterator>(Arowmajor);
func<...,...>(Acolmajor);
当我编译时:
error: cannot convert Eigen::SparseMatrix<double,RowMajor> &
to Eigen::SparseMatrix<double,0,int> &
然后,我改变了类型:
func<Eigen::SparseMatrix<double,0,int>,ditto::InnerIterator>(Arowmajor)
错误?与前一个相反:
error: cannot convert Eigen::SparseMatrix<double,0,int> &
to Eigen::SparseMatrix<double,RowMajor> &
使用Eigen类处理迭代和模板的正确方法是什么?
答案 0 :(得分:2)
您可以使用一个模板参数代表SparseMatrix
类型,而不是显式使用两个模板参数,并使用其InnerIterator
:
#include <Eigen/SparseCore>
#include <iostream>
using namespace Eigen;
template<class Mat>
void func(Mat & A, double d)
{
for (int i = 0; i < A.outerSize(); i++)
for (typename Mat::InnerIterator it(A, i); it; ++it)
it.valueRef() = d;
}
int main()
{
SparseMatrix<double> sm(3, 3);
sm.setIdentity();
std::cout << sm << "\n\n";
func(sm, 3.2);
std::cout << sm << "\n\n";
return 0;
}
请注意,这不会为表达式编译,例如func(sm * 2.0, 3.2);
,因为它是表达式模板,并且没有InnerIterator
。有一些方法可以编写接受表达式的模板化函数,但这些函数更复杂,往往需要更多关于Eigen内部运算的知识(参见例如here)。