如何将 Eigen 求解器缓存为 class 成员?
How do I cache an Eigen solver as a class member?
我有一些几何数据,我通过求解一些昂贵的线性系统来移动其顶点。我想在函数调用之间重新使用该系统,所以我试图将它封装为 class 中的 class 成员,我可以将其提供给我正在使用的几何框架,但我不知道如何命名求解器的类型。
我这样得到求解器:
#include "./eigen3/Eigen/Sparse"
#include "./eigen3/Eigen/SparseCore"
#include "./eigen3/Eigen/SparseCholesky"
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> sparseSolver(mySPDMatrix);
所以我的第一个想法是这样写一个class(部分成员省略):
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;
这确实可以编译,但前提是我注释掉(更新的)构造函数。如果我将构造函数留在其中,我会收到一条错误消息,告诉我我正在尝试 "use of deleted function" 而它是 "implicitly deleted because the default definition would be ill-formed"。我认为正在发生的事情是必须发生隐式复制,其中包括对构造函数的调用,因此我向其添加了“&”:
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 求解器缓存为 class 成员的正确方法是什么?
这是一个独立的工作示例,它遵循我上面建议的第二种方法:
#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);
}
我有一些几何数据,我通过求解一些昂贵的线性系统来移动其顶点。我想在函数调用之间重新使用该系统,所以我试图将它封装为 class 中的 class 成员,我可以将其提供给我正在使用的几何框架,但我不知道如何命名求解器的类型。
我这样得到求解器:
#include "./eigen3/Eigen/Sparse"
#include "./eigen3/Eigen/SparseCore"
#include "./eigen3/Eigen/SparseCholesky"
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> sparseSolver(mySPDMatrix);
所以我的第一个想法是这样写一个class(部分成员省略):
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;
这确实可以编译,但前提是我注释掉(更新的)构造函数。如果我将构造函数留在其中,我会收到一条错误消息,告诉我我正在尝试 "use of deleted function" 而它是 "implicitly deleted because the default definition would be ill-formed"。我认为正在发生的事情是必须发生隐式复制,其中包括对构造函数的调用,因此我向其添加了“&”:
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 求解器缓存为 class 成员的正确方法是什么?
这是一个独立的工作示例,它遵循我上面建议的第二种方法:
#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);
}