重用 Eigen::SimplicialLLT 的符号分解

2024-04-11

我在 Eigen 库的 API 上遇到了一些困难,即用于稀疏矩阵 Cholesky 分解的 SimplcialLLT 类。 我需要分解三个矩阵,然后用它们来求解许多方程组(仅更改右侧) - 因此我只想将这些矩阵分解一次,然后重新使用它们。此外,它们都具有相同的稀疏模式,因此我只想进行一次符号分解,然后将其用于所有三个矩阵的数值分解。根据文档,这正是SimplicialLLT::analyzePattern and SimplicialLLT::factor方法是为了。然而,我似乎无法找到一种方法来将所有三个因素都保留在记忆中。这是我的代码:

我的类中有这些成员变量,我想填充以下因素:

Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> choleskyA;
Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> choleskyB;
Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> choleskyC;

然后我创建三个稀疏矩阵 A、B 和 C 并希望对它们进行因式分解:

choleskyA.analyzePattern(A);
choleskyA.factorize(A);
choleskyB.analyzePattern(B); // this has already been done!
choleskyB.factorize(B);
choleskyC.analyzePattern(C); // this has already been done!
choleskyC.factorize(C);

之后我可以一遍又一遍地使用它们来解决问题,只需更改右侧的 b 向量:

xA = choleskyA.solve(bA);
xB = choleskyB.solve(bB);
xC = choleskyC.solve(bC);

这是可行的(我认为),但是对analyzePattern的第二次和第三次调用是多余的。我想做的是这样的:

choleskyA.analyzePattern(A);
choleskyA.factorize(A);
choleskyB = choleskyA.factorize(B);
choleskyC = choleskyA.factorize(C);

但这不是当前 API 的一个选项(我们使用 Eigen 3.2.3,但如果我没看错的话,3.3.2 在这方面没有任何变化)。这里的问题是,对 SimplcialLLT 的同一实例进行因式分解的后续调用将覆盖之前计算的因式,同时,我无法找到一种方法来复制它以保留。我查看了源代码,但我必须承认这没有多大帮助,因为我看不到任何复制底层数据结构的简单方法。在我看来,这是一个相当常见的用法,所以我觉得我遗漏了一些明显的东西,请帮助。

我尝试过的:

我尝试简单地使用choleskyB = choleskyA希望默认的复制构造函数能够完成任务,但我发现基类被设计为不可复制的。

我可以从以下位置获取 L 和 U 矩阵(它们有一个 getter)choleskyA,复制它们并仅存储它们,然后基本上复制粘贴 SimplicialCholeskyBase::_solve_impl() 的内容(复制粘贴在下面),以直接使用先前存储的 L 和 U 编写求解自己的方法。

template<typename Rhs,typename Dest>
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
{
  eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
  eigen_assert(m_matrix.rows()==b.rows());

  if(m_info!=Success)
    return;

  if(m_P.size()>0)
    dest = m_P * b;
  else
    dest = b;

  if(m_matrix.nonZeros()>0) // otherwise L==I
    derived().matrixL().solveInPlace(dest);

  if(m_diag.size()>0)
    dest = m_diag.asDiagonal().inverse() * dest;

  if (m_matrix.nonZeros()>0) // otherwise U==I
    derived().matrixU().solveInPlace(dest);

  if(m_P.size()>0)
    dest = m_Pinv * dest;
}

...但这是一个相当丑陋的解决方案,而且我可能会把它搞砸,因为我对这个过程没有很好的理解(我不需要上面代码中的 m_diag,因为我正在做 LLT,对吧?那会仅当我使用 LDLT 时才相关?)。我希望这不是我需要做的......

最后一点 - 将必要的 getter/setter 添加到 Eigen 类并编译“我自己的”Eigen 不是一种选择(好吧,不是一个好的选择),因为此代码将(希望)作为开源进一步重新分发,因此它会麻烦点。


这是一个非常不寻常的模式。在实践中,与数值因式分解相比,符号因式分解非常便宜,因此我不确定是否值得如此费心。解决此模式的最简洁的解决方案是让 SimplcialL?LT 可复制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重用 Eigen::SimplicialLLT 的符号分解 的相关文章

  • 按欧拉角输入旋转四元数

    我正在编写一段代码来控制 3D 空间中的机械臂 机械臂通过四元数处理旋转 但我希望用户通过改变偏航 俯仰和滚动来控制它 因为人类使用这些更明智 我编写了函数来获取用户想要在每个方向 滚动 俯仰 偏航 旋转手臂的量并输出新的四元数 我将 cu
  • 在 Apple M1 上使用 clang 出现“致命错误:找不到‘omp.h’文件”

    Clang 找不到omp h每当我尝试使用 openMP 标志进行编译时 这就是我想做的 clang dynamiclib I opt homebrew Cellar eigen 3 3 9 include eigen3 Xpreproce
  • 稠密对称矩阵的特征有效类型

    Does Eigen http eigen tuxfamily org index php title Main Page有存储密集 固定大小 对称矩阵的有效类型吗 嘿 它们无处不在 IE 对于 N 9 它应该只存储 1 9 9 2 45
  • Eigen::Tensor 和 Eigen::Matrix 性能比较

    我想用单个 3 D Eigen Tensor 替换代码中的一系列矩阵 考虑到这一点 我尝试比较张量和矩阵的性能 下面的函数 tensorContractTest 执行 n n n 3 阶张量与大小为 n n 500 的 1 阶张量的收缩 此
  • 如何将 Eigen 库添加到 C++ 项目中

    可能是一个愚蠢 简单的问题 但我一直无法找到答案 我不知道如何使用 CodeBlocks c 添加库 我从以下位置下载了 zip 文件http eigen tuxfamily org index php title Main Page ht
  • 将 Eigen::VectorXd 类型转换为 std::vector

    他们有很多相反的链接 但在我的具体情况下 我无法找到从 Eigen Matrix 或 Eigen VectorXd 获取 std vector vector
  • 如何在 CUDA 内核中使用 Eigen

    Eigen 是一个 C 线性代数库http eigen tuxfamily org http eigen tuxfamily org 使用基本数据类型 例如基本浮点数组 很容易 只需将其复制到设备内存并将指针传递给 cuda 内核即可 但是
  • Eigen:返回对带有编译时维度检查的矩阵块的引用

    我要问的是一个概括这个问题 https stackoverflow com questions 13548253 eigen library return a matrix block in a function as lvalue 具体来
  • 在 Eigen3 中实现 Bartels–Stewart 算法?

    过去当我需要解西尔维斯特方程时AX XB C 我用过scipy的函数 solve sylvester 1 它显然是通过使用 Bartels Stewart 算法将事物转化为上三角形式 然后使用lapack 我现在需要使用以下方法求解方程ei
  • 从特征序列化分解矩阵(SparseLU 对象)

    我正在尝试解决Ax b其中矩阵 A 可以大到接近1M x 1M在大小上 是稀疏且对称的 但可能没有明确定义 问题是使用以下方法计算分解可能需要很长时间稀疏LU对象 http eigen tuxfamily org dox devel cla
  • 连接稀疏矩阵特征值

    我在特征中有两个稀疏矩阵 我想将它们垂直连接成一个 例如 代码的目标是 SparseMatrix
  • C++ 在张量流中使用 Eigen

    张量流和特征值之间有什么关系 特别是关于tensor数据结构 有一些较旧的引文 例如 其中指出tensorflow正在广泛使用Eigen 据我所知 tensorflow人员已经扩展了Eigen代码 然而 最近的张量流文档似乎没有明确提及 E
  • 如何确保特征等距保持等距?

    我目前正在调查Eigen Isometry3f 定义为typedef Transform
  • 如何桥接 JavaScript(参差不齐)数组和 std::vector> 对象?

    在 JavaScript 中 我有一个 线 列表 每条线都由不定数量的 点 组成 每个点都有以下形式 x y 所以它是一个 3D 参差不齐的数组 现在我需要在 emscripten 的帮助下将它传递给我的 C 代码 embind https
  • 重用 Eigen::SimplicialLLT 的符号分解

    我在 Eigen 库的 API 上遇到了一些困难 即用于稀疏矩阵 Cholesky 分解的 SimplcialLLT 类 我需要分解三个矩阵 然后用它们来求解许多方程组 仅更改右侧 因此我只想将这些矩阵分解一次 然后重新使用它们 此外 它们
  • RcppEigen - 从包中的内联函数到 .cpp 函数和“Map”

    一切似乎都在我的包中工作 但我想检查其步骤是否正确以及使用 Map 的内存使用情况 这是一个简单的示例 位于内联示例和fastLm 例子 这是一个内联函数 它取矩阵每一列的最大值 library Rcpp library inline li
  • 使用矢量化为 iPhone 编译 Eigen 库

    我正在努力为 iPhone 4 编译 Eigen 库 该库具有带有 armv7 指令集的 ARM 处理器 到目前为止 当我指定预处理器定义 EIGEN DONT VECTORIZE 时 一切正常 但由于一些性能问题 我想使用armv7优化的
  • 如何从二进制文件写入/读取特征矩阵

    要将 Eigen Matrix 写入文件 我真的很喜欢使用以下命令 typedef Eigen Matrix
  • 特征密集稀疏矩阵乘积是线程化的吗?

    我知道稀疏密集产品是根据文档进行线程化的 https eigen tuxfamily org dox TopicMultiThreading html https eigen tuxfamily org dox TopicMultiThre
  • 访问特征矩阵的行向量时复制或引用

    我正在使用的代码Eigen http eigen tuxfamily org index php title Main Page矩阵库 我注意到在整个代码中 有如下访问器 RowVector3f V size t vertex index

随机推荐