如何将特征解算器缓存为类成员?

时间:2017-12-09 11:45:44

标签: c++ templates eigen eigen3

我有一些几何数据的顶点我通过解决一些昂贵的线性系统来移动。我想在函数调用之间重用该系统,所以我试图将它封装为类中的类成员,我可以将其提供给我正在使用的几何框架,但是我并没有这样做。知道如何命名解算器的类型。

我得到了这样的求解器:

#include "./eigen3/Eigen/Sparse"
#include "./eigen3/Eigen/SparseCore"
#include "./eigen3/Eigen/SparseCholesky"

Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> sparseSolver(mySPDMatrix);

所以我的第一个想法是写一个这样的类(一些成员省略):

class MatrixCachePerObjectData : public PerObjectData    /* 'PerObjectData' is required by the framework */
{
public:
    Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> cached_solver;
    MatrixCachePerObjectData(Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> cs) : cached_solver(cs) {}
};

不会编译。我已经意识到这是因为我命名了(缩写)构造函数而不是完整类型,因此我查看了文档并将成员类型更改为:

Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Lower, Eigen::AMDOrdering<int>> cached_solver;

这会编译,但前提是我注释掉了(更新的)构造函数。如果我离开构造函数,我会收到一个错误,告诉我我正在尝试使用已删除的函数&#34;并且它被隐式删除,因为默认定义将是格式错误的#34;。我认为发生的事情是必须发生一个隐含的副本,其中包括对构造函数的调用,所以我添加了一个&#39;&amp;&#39;它:

MatrixCachePerObjectData(Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Lower, Eigen::AMDOrdering<int>>& cs, Eigen::SparseMatrix<double> cm, bool cv) : cached_solver(cs), Q_T(cm), cache_valid(true) {}

但这给了我同样的错误,我不太清楚为什么。我最好(但仍然很糟糕)的猜测是,不是调用copy - 函数,而是调用等效的move - 函数,但事实上我可以告诉我这里真的很无能为力。所以我放弃了构造函数并尝试直接访问该成员:

auto mpc = new MatrixCachePerObjectData();
mpc->cached_solver = sparseSolver;

这可以预测再次失败并出现同样的错误。我尝试打印出类型,看看我是否在那里犯了错误并得到了:

N5Eigen14SimplicialLDLTINS_12SparseMatrixIdLi0EiEELi1ENS_11AMDOrderingIiEEEE   // typeid(sparseSolver).name()

这让我更加困惑。任何帮助表示赞赏。

将Eigen3求解器缓存为类成员的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

以下是我在上面建议的第二种方法之后的一个有用的自包含示例:

#include <Eigen/Sparse>
using namespace Eigen;

class Cache {
    typedef SimplicialLDLT<SparseMatrix<double> > Solver;
    Solver m_solver;
  public:
    Solver& solver() { return m_solver; }
};

int main()
{
  Cache cache;
  auto& solver = cache.solver();
  SparseMatrix<double> A = MatrixXd::Random(10,10).sparseView();
  A = A.transpose() * A;
  solver.compute(A);
}