Eigen线性代数求解器(分解类)

1. 核心分解类概览

Eigen 提供多种矩阵分解方法,适用于不同矩阵类型(稠密/稀疏、正定/非正定等):

分解类 适用矩阵类型 分解形式 典型应用场景
PartialPivLU 方阵(可逆) A=PLUA=PLU 通用线性方程组求解
FullPivLU 任意矩阵 A=P−1LUQ−1A=P−1LUQ−1 高稳定性求解(计算成本高)
HouseholderQR 任意矩阵(列满秩) A=QRA=QR 最小二乘问题(快速但不稳定)
ColPivHouseholderQR 任意矩阵 A=QRA=QR(列主元) 稳定的最小二乘解
FullPivHouseholderQR 任意矩阵 A=QRA=QR(完全主元) 高稳定性(计算成本最高)
LLT 正定矩阵 A=LLTA=LLT Cholesky 分解(快速)
LDLT 半正定/正定矩阵 A=LDLTA=LDLT 带对角调整的 Cholesky

2. 通用方法与属性

所有分解类均继承自 Eigen::SolverBase,提供以下统一接口:

核心方法
方法 参数说明 返回值/功能 示例
compute(const MatrixType& A) A: 待分解矩阵 无(更新分解状态) lu.compute(A);
solve(const MatrixType& b) b: 右侧矩阵/向量 解 Ax=bAx=b VectorXf x = lu.solve(b);
matrixLU() 返回 LU 分解后的矩阵 MatrixXd LU = lu.matrixLU();
info() 返回计算状态(Success/NumericalIssue if (lu.info() != Success) { /* error */ }
属性
属性 说明
rows(), cols() 返回分解矩阵的行数/列数
rank() 返回矩阵的秩(仅 FullPiv* 类支持)

3. 各分解类详解

(1) PartialPivLU(部分主元 LU 分解)
  • 适用场景:通用方阵求解(推荐默认使用)。

  • 特有方法

    cpp

    复制代码
    PermutationMatrix P = lu.permutationP();  // 返回排列矩阵 P
    MatrixXd L = lu.matrixLU().triangularView<UnitLower>();  // 提取 L
    MatrixXd U = lu.matrixLU().triangularView<Upper>();      // 提取 U
(2) HouseholderQRColPivHouseholderQR
  • 区别:后者通过列主元提高稳定性,但稍慢。

  • 特有方法

    cpp

    复制代码
    MatrixXd Q = qr.householderQ();  // 获取 Q 矩阵(需显式计算)
    VectorXd hCoeffs = qr.hCoeffs(); // 返回 Householder 系数
    // 仅 ColPivHouseholderQR:
    PermutationMatrix P = qr.colsPermutation(); // 列排列矩阵
(3) LLTLDLT(Cholesky 分解)
  • 要求 :矩阵必须正定(LLT)或半正定(LDLT)。

  • 特有方法

    cpp

    复制代码
    MatrixXd L = llt.matrixL();  // 获取下三角矩阵 L(LLT)
    VectorXd D = ldlt.vectorD(); // 获取对角矩阵 D(LDLT)

4. 稀疏矩阵分解类

类名 适用场景 关键方法
SimplicialLLT 稀疏正定矩阵 analyzePattern(), factorize()
SparseLU 通用稀疏方阵 solve() 支持多右手边
ConjugateGradient 稀疏对称正定矩阵(迭代) setTolerance(), compute()

5. 代码示例

稠密矩阵求解

cpp

复制代码
#include <Eigen/Dense>
using namespace Eigen;

Matrix3f A;
Vector3f b;
A << 1, 2, 3, 
     4, 5, 6, 
     7, 8, 10;
b << 3, 3, 4;

// PartialPivLU 分解(推荐默认)
PartialPivLU<Matrix3f> lu(A);
Vector3f x = lu.solve(b);  // 解 Ax = b

// Cholesky 分解(正定矩阵)
LLT<Matrix3f> llt(A.transpose() * A);  // A^T A 正定
Vector3f y = llt.solve(A.transpose() * b);  // 解正规方程
稀疏矩阵求解

cpp

复制代码
#include <Eigen/Sparse>
SparseMatrix<double> mat(100, 100);
VectorXd b = VectorXd::Random(100);

// SimplicialLLT 分解
SimplicialLLT<SparseMatrix<double>> solver;
solver.compute(mat);
VectorXd x = solver.solve(b);

6. 选择分解方法的准则

矩阵类型 推荐分解类 原因
通用稠密方阵 PartialPivLU 平衡速度与稳定性
最小二乘问题(非对称) ColPivHouseholderQR 稳定性优于 HouseholderQR
正定稠密矩阵 LLT 最快(约 2 倍加速)
稀疏对称正定矩阵 SimplicialLLT 内存高效

注意事项

  1. 分解重用 :若矩阵不变,可先调用 compute(A) 再多次 solve(b) 提高效率。

  2. 数值稳定性 :对于病态矩阵,优先选择 FullPivLUColPivHouseholderQR

  3. 稀疏矩阵 :分解前需调用 analyzePattern() 优化内存分配。

通过合理选择分解类,可以显著提升计算性能!更多细节见 Eigen 文档

相关推荐
byxdaz1 天前
Eigen核心矩阵/向量类 (Matrix, Vector, Array)
eigen
byxdaz4 天前
Eigen矩阵操作类 (Map, Block, 视图类)
eigen
黄卷青灯777 个月前
c++ vector类 和 eigen库 处理向量的区别 列出代码举例
开发语言·c++·vector·eigen
风与铃的约定9 个月前
2.2 视觉SLAM 实践:Eigen
c++·机器人·slam·视觉slam·eigen·机器人运动学
西西弗Sisyphus9 个月前
softmax 函数的多种实现方式 包括纯C语言、C++版本、Eigen版本等
c语言·c++·softmax·eigen
点云兔子10 个月前
Eigen::Isometry3d 的定义和用途
3d·eigen·isometry3d
西西弗Sisyphus10 个月前
Eigen中 Row-Major 和 Column-Major 存储顺序的区别
开发语言·python·eigen·跟踪
大米粥哥哥1 年前
Qt 配置Eigen矩阵库 - 并简单测试
开发语言·qt·矩阵·eigen·fft·低通滤波
小林up1 年前
Eigen笔记2:矩阵拼接
线性代数·eigen