我如何将本特征求解器作为班级成员缓存

How do I cache an Eigen solver as a class member?

本文关键字:缓存 成员 特征      更新时间:2023-10-16

我有一些几何数据,通过求解某些昂贵的线性系统,我的顶点是我移动的。我想在函数调用之间重复使用该系统,因此我试图将其封装为可以将其提供给我正在使用的几何框架的课堂成员,但是我不知道如何命名求解器的类型。


我这样获得求解器:

#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;

这确实是编译的,但前提是我评论(更新的)构造函数。如果我将构造函数留在一个错误中,我会告诉我我正在尝试"使用已删除的函数",并且它被"隐式删除",因为默认定义将是错误的。我认为正在发生的事情是,必须发生一个隐性副本,其中包括对构造函数的调用,因此我添加了一个'&amp;对此:

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求解器作为类成员缓存的正确方法是什么?

这是我上面建议的第二种方法,是一个工作的独立示例:

#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);
}