矩阵常见分解算法及其在SLAM中的应用

news2024/9/20 9:06:41

文章目录

  • 常见特殊矩阵定义
  • Cholesky分解(正定Hermittian矩阵,分解结果唯一)
    • Cholesky分解应用
  • SVD分解(将singularvalues排序后分解唯一)
    • SVD 分解的应用(任意矩阵)
  • QR分解(任意矩阵,如果A可逆并且限定分解R对角线为正,则分解唯一)
    • QR分解应用

https://eigen.tuxfamily.org/dox/group__TutorialLinearAlgebra.html
在这里插入图片描述

常见特殊矩阵定义

  • 酉矩阵,正交矩阵
    • A的元素是属于复数域矩阵,如果 A A ∗ = I AA^{*} = I AA=I,那么A是属于酉矩阵(Unitary Matrix)
    • A的元素是属于实数域矩阵,如果 A A T = I AA^{T} = I AAT=I,那么A是属于正交矩阵(Orthogonal Matrix),当然也是Unitary Matrix
  • 埃尔米特矩阵,对阵矩阵
    • A的元素是属于复数域矩阵,如果 A = A ∗ A = A^{*} A=A,那么A是属于埃尔米特矩阵(Hermitian Matrix)
    • A的元素是属于实数域矩阵,如果 A = A T A = A^{T} A=AT,那么A是属于对称矩阵(Symmetric Matrix),当然也是Hermitian Matrix
  • 正定矩阵
    在这里插入图片描述

Cholesky分解(正定Hermittian矩阵,分解结果唯一)

将一个正定Hermitian矩阵分解为两个下三角矩阵的乘积
A = L L T A = LL^T A=LLT
另一种分解方式 A = L L T = L D L T A = LL^T = LDL^T A=LLT=LDLT,要求A是半正定或者半负定矩阵,条件比上面的分解方式宽松

Cholesky分解应用

  • 对于LinearGaussian 系统的状态估计问题求解 H T W − 1 H x = H T W − 1 Z H^TW^{-1}Hx = H^TW^{-1}Z HTW1Hx=HTW1Z
    求解x的时候会把 H T W − 1 H = L L ∗ H^TW^{-1}H = LL^{*} HTW1H=LL 分解完,令 L ∗ x = d L^{*}x = d Lx=d
    (1)求解 L d = H T W − 1 Z Ld = H^TW^{-1}Z Ld=HTW1Z中的d
    (2)求解 L ∗ x = d L^{*}x = d Lx=d中的x
    以上可以导出LG系统的batch递推形式,包括5个前向公式和1个后项公式。其等价于RTS算法。

SVD分解(将singularvalues排序后分解唯一)

将任意矩阵 A M × N = U M ∗ M Σ M × N V N × N A_{M \times N} = U_{M*M} \Sigma_{M \times N} V_{N \times N} AM×N=UMMΣM×NVN×N,其中 U和V都是Unitary Matrix, Σ \Sigma Σ是对角矩阵,
如果M > N,如下图。U_null_space.transpose() * A 应该是零矩阵。
反之如N> M,会有A * V_null_space为零矩阵。
MSCKF利用零空间这个性质,可以消除feature 3d位置估计误差在整个残差中的影响。

  Eigen::MatrixXd A = Eigen::MatrixXd::Random(6, 3);
  // Eigen::MatrixXd A = Eigen::MatrixXd::Random(3, 6);
  A << 1, 0, -1, -2, 1, 4, 3, 4, 5, 5, -7, 9, -1, 4, -6, 4, 7, -9;

  cout << "Here is the matrix A:" << endl << A << endl << endl;
  // do SVD decomposition, and print out the singular values
  Eigen::JacobiSVD<Eigen::MatrixXd> svd(
      A, Eigen::ComputeFullU | Eigen::ComputeFullV);
  cout << "Its singular values are:" << endl
       << svd.singularValues() << endl
       << endl;
  cout << "Its left singular vectors are the columns of the thin U matrix:"
       << endl
       << svd.matrixU() << endl
       << endl;
  cout << "Its right singular vectors are the columns of the thin V matrix:"
       << endl
       << svd.matrixV() << endl
       << endl;

  const int dim = svd.singularValues().size();
  if (A.rows() >= A.cols()) {
    const Eigen::MatrixXd U_null_space =
        svd.matrixU().rightCols(A.rows() - dim);
    const Eigen::MatrixXd U_null_space_times_A = U_null_space.transpose() * A;
    cout << "U null space * A" << endl
         << U_null_space_times_A << endl
         << endl;  // should be zero
  } else {
    const Eigen::MatrixXd V_null_space =
        svd.matrixV().rightCols(A.cols() - dim);
    const Eigen::MatrixXd A_times_V_null_space = A * V_null_space;
    cout << "A * V null space" << endl
         << A_times_V_null_space << endl
         << endl;  // should be zero
  }

  cout << "U*U^T = \n"
       << svd.matrixU() * svd.matrixU().transpose() << endl
       << endl;  // should be identity
  cout << "V*V^T = \n"
       << svd.matrixV() * svd.matrixV().transpose() << endl
       << endl;  // should be identity

  return 0;

在这里插入图片描述

SVD 分解的应用(任意矩阵)

  • 用于PCA,SVD的奇异值的平方等于特征值,即 σ i = λ i \sigma_i = \sqrt{\lambda_i} σi=λi 。比如一堆点云,可以利用PCA性质提取line point和plane point。
  • 求矩阵零空间。MSCKF中的应用。矩阵列向量的零空间维度为:dim(null space) = cols(A) - rank(A)
    • 行向量子空间的维度 = rank(A) = m - (A的零空间的维度)= m - dim[Null(A)]
    • 列向量子空间的维度 = rank(A) = n - (A的零空间的维度)=n - dim[Null(A)]

QR分解(任意矩阵,如果A可逆并且限定分解R对角线为正,则分解唯一)

一个m*n矩阵A(m>=n),可以分解为一个Unitary Matrix Q和一个上三角矩阵R
A m × n = Q m × m R m × n A_{m \times n} = Q_{m \times m} R_{m \times n} Am×n=Qm×mRm×n
其中R的后m-n行全部为零,可以写作
A = Q R = Q [ R 1 n × n 0 ] = [ Q 1 m × n Q 2 m × ( m − n ) ] [ R 1 n × n 0 ( m − n ) × n ] = Q 1 m × n R 1 n × n A=Q R=Q\left[\begin{array}{c} R_{1_{n \times n}} \\ 0 \end{array}\right]=\left[\begin{array}{ll} Q_{1_{m \times n}} & Q_{2_{m \times (m-n)}} \end{array}\right]\left[\begin{array}{c} R_{1_{n \times n}} \\ 0_{(m-n) \times n} \end{array}\right]=Q_{1_{m \times n}} R_{1_{n \times n}} A=QR=Q[R1n×n0]=[Q1m×nQ2m×(mn)][R1n×n0(mn)×n]=Q1m×nR1n×n
类似的可以有QL,RQ,LQ分解,其中L是下三角矩阵。

  Eigen::MatrixXd A = Eigen::MatrixXd::Random(6, 3);
  A << 1, 0, -1, -2, 1, 4, 3, 4, 5, 5, -7, 9, -1, 4, -6, 4, 7, -9;
  Eigen::VectorXd b = Eigen::VectorXd::Random(6);

  Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qr(A);
  MatrixXd householderQ = qr.householderQ();
  MatrixXd matrixQ = qr.matrixQ();  // 和householderQ一样
  MatrixXd matrixQR_triangular_upper =
      qr.matrixQR().triangularView<Eigen::Upper>();
  MatrixXd matrixR = qr.matrixR();

  cout << "The rank of A is " << qr.rank() << endl << endl;
  cout << "householderQ matrix is:\n" << householderQ << endl << endl;
  cout << "matrixQ matrix is:\n" << matrixQ << endl << endl;
  cout << "matrixQR matrix is:\n" << qr.matrixQR() << endl << endl;
  cout << "matrixQR.triangularView<Eigen::Upper>() matrix is:\n"
       << matrixQR_triangular_upper << endl
       << endl;
  cout << "matrixR matrix is:\n" << matrixR << endl << endl;

  // Do QR decomposition to sove Ax = b
  Eigen::VectorXd x = qr.solve(b);
  cout << "The solution is:\n" << x << endl << endl;

[图片]

QR分解应用

  • 求矩阵的零空间,类似SVD
  • 用来求解线性最小二乘问题 A m × n x n × 1 = b m × 1 A_{m\times n}x_{n \times 1} = b_{m \times 1} Am×nxn×1=bm×1, m >> n
    通常的解法 x = ( A T A ) m × m − 1 b x = (A^TA)_{m \times m}^{-1}b x=(ATA)m×m1b 直接求逆的话,维度很大,耗时
    将A进行QR分解,化简得到 R 1 x = Q 1 T b R_1 x = Q_1^Tb R1x=Q1Tb 并且R1是上三角矩阵,无需求逆,直接方程最后一行开始求解,便可以快速得到x
  • Kalman filter中观测量的维度m过大导致m>>状态维度n, H m × n H_{m \times n} Hm×n矩阵计算 ( H P H T + R ) − 1 (HPH^T + R)^{-1} (HPHT+R)1非常耗时
 const MatrixXX innovation_covariance = H * P * HT + V;
 const MatrixNX K = P * HT * innovation_covariance.inverse();

观测误差方程 r ( x ) = H X ~ + n 0 r(x) = H \tilde{X} + n_0 r(x)=HX~+n0
对H进行QR分解,两边乘以 Q T Q^T QT并带入上式得到 [ Q 1 T r o Q 2 T r o ] = [ R 1 0 ] X ~ + [ Q 1 T n o Q 2 T n o ] \left[\begin{array}{l} \mathbf{Q}_1^T \mathbf{r}_o \\ \mathbf{Q}_2^T \mathbf{r}_o \end{array}\right]=\left[\begin{array}{c} \mathbf{R}_1 \\ \mathbf{0} \end{array}\right] \tilde{\mathbf{X}}+\left[\begin{array}{l} \mathbf{Q}_1^T \mathbf{n}_o \\ \mathbf{Q}_2^T \mathbf{n}_o \end{array}\right] [Q1TroQ2Tro]=[R10]X~+[Q1TnoQ2Tno]
于是观测量维度为m的问题转化为了观测量维度为n的
Q 1 T r 0 = R 1 X ~ + Q 1 T n 0 Q_1^Tr_0 = R1 \tilde{X} + Q_1^T n_0 Q1Tr0=R1X~+Q1Tn0
将原问题中的H,残差r,观测噪声n都进行了变换,代码实现如下

  MatrixXd H_thin;
  VectorXd r_thin;

  if (H.rows() > H.cols()) {
    // Convert H to a sparse matrix.
    SparseMatrix<double> H_sparse = H.sparseView();

    // Perform QR decompostion on H_sparse.
    SPQR<SparseMatrix<double>> spqr_helper;
    spqr_helper.setSPQROrdering(SPQR_ORDERING_NATURAL);
    spqr_helper.compute(H_sparse);

    MatrixXd H_temp;
    VectorXd r_temp;
    (spqr_helper.matrixQ().transpose() * H).evalTo(H_temp);
    (spqr_helper.matrixQ().transpose() * r).evalTo(r_temp);

    H_thin = H_temp.topRows(21 + state_server.cam_states.size() * 6);
    r_thin = r_temp.head(21 + state_server.cam_states.size() * 6);

    // HouseholderQR<MatrixXd> qr_helper(H);
    // MatrixXd Q = qr_helper.householderQ();
    // MatrixXd Q1 = Q.leftCols(21+state_server.cam_states.size()*6);

    // H_thin = Q1.transpose() * H;
    // r_thin = Q1.transpose() * r;
  } else {
    H_thin = H;
    r_thin = r;
  }

  // Compute the Kalman gain.
  const MatrixXd &P = state_server.state_cov;
  MatrixXd S = H_thin * P * H_thin.transpose() +
               Feature::observation_noise *
                   MatrixXd::Identity(H_thin.rows(), H_thin.rows());
  // MatrixXd K_transpose = S.fullPivHouseholderQr().solve(H_thin*P);
  MatrixXd K_transpose = S.ldlt().solve(H_thin * P);
  MatrixXd K = K_transpose.transpose();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第六周:机器学习周报

机器学习周报 摘要Abstract机器学习——类神经网络训练不起来怎么办&#xff1f;1. 自动调整学习率&#xff08;learning rate&#xff09;1.1 特制化的Learning Rate——parameter dependent1.1.1 Root Mean Square&#xff08;RMS&#xff0c;均方根&#xff09;1.1.2 RMSPro…

【Python】基础语法(下)

本篇文章将接着上篇文章继续讲解基础语法&#xff1a; &#xff08;4&#xff09;变量 &#xff08;5&#xff09;注释 &#xff08;6&#xff09;输入 &#xff08;7&#xff09;条件语句 四&#xff1a;变量 变量其实就是我们生活中起别名和外号。让变量名指向某个值&a…

旅游卡,免费,旅游是真的吗?真相是……

但这种包来回大交通&#xff0c;一旦成本大于利润&#xff0c;他们就会以各种理由推卸责任。这就是我在“揭秘&#xff1a;共享旅游卡免费旅游&#xff0c;包来回路费&#xff0c;这背后的3大真相&#xff01;”这篇文章里面讲到那个大妈的惨痛教训。 以上这5点真相&#xff0…

Python 中的@符号:如何用装饰器改变你的编程方式?

Python 是一种强大且灵活的编程语言&#xff0c;其中有许多独特的语法元素和概念。 符号通常用于装饰器。它看起来可能有些神秘&#xff0c;但实际上它的工作原理非常简单。 什么是装饰器&#xff1f; 在了解 符号之前&#xff0c;我们首先需要理解什么是装饰器。简单来说&am…

C++设计模式笔记(内附可运行代码示例)

持续更新, 欢迎关注....... 前言 设计目的 高内聚&#xff0c;低耦合 设计原则 1、开放封闭原则 类的改动是通过增加代码进行&#xff0c;而不是修改源代码。 2、单一职责原则 职责单一&#xff0c;对外只提供一种功能&#xff0c;引起类变化的原因都应该只有一个。 3…

【中项】系统集成项目管理工程师-第9章 项目管理概论-9.1PMBOK的发展与9.2项目基本要素

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

数据库设计效率提高的5大注意事项

数据库设计效率和质量的提高对项目影响深远&#xff0c;能够显著提升数据访问速度&#xff0c;确保数据一致性和完整性&#xff0c;减少应用开发和维护成本&#xff0c;同时提升系统稳定性和用户体验。如果数据库设计不佳会导致项目性能低下&#xff0c;数据访问缓慢&#xff0…

Java7.0标准之重要特性及用法实例(十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…

APDL(ANSYS Parametric Design Language)初识

APDL&#xff08;ANSYS Parametric Design Language&#xff09;编写涉及使用ANSYS的参数化设计语言来创建、修改和执行有限元分析&#xff08;FEA&#xff09;任务。以下是一些关于APDL编写的基本步骤、技巧和示例&#xff1a; 一、基本步骤 了解APDL基础&#xff1a; 熟悉AP…

并发--快速查询死锁信息

使用jstack查看线程堆栈信息 jstack&#xff1a;jdk提供的一个工具&#xff0c;可以查看java进程中线程堆栈信息。 位于&#xff1a;jdk1.8.0_121\bin包下 死锁代码 public class DeadLockDemo {private static String A "A";private static String B "B"…

视频平台麓战奥运经济,谁能接住这“破天的富贵”?

文丨郭梦仪 与巴黎奥运会炸裂开幕式的“松弛感”不同&#xff0c;赛场外的流量之争早已硝烟弥漫。 今年&#xff0c;腾讯、咪咕、快手、抖音与中央广播电视总台达成奥运转播版权合作&#xff0c;长短视频平台各占一半。 而今&#xff0c;获得转播权的视频平台们&#xff0c;…

20240731 每日AI必读资讯

&#x1f4f1;苹果AI版iOS首日火爆&#xff1a;聊天秒变高情商&#xff0c;大模型成最强嘴替&#xff0c;Siri华丽变身 - 苹果的Apple Intelligence终于面世&#xff01;随着iOS 18.1 Beta版的上线&#xff0c;注册开发者从即日起就能体验到苹果AI的部分功能。 - Siri的全面换…

出行方案,智能推荐:用友BIP商旅云6.0推出AI新装备

随着企业业务的不断拓展和员工出行需求的日益复杂化&#xff0c;传统的商旅预订方式已经难以应对&#xff0c;同时企业在商旅成本控制方面也面临着巨大的挑战。为此用友BIP商旅云6.0推出了创新性的AI新装备——智能推荐&#xff0c;以智能分析与精准预测&#xff0c;为企业提供…

基于springboot的大学奖学金评定管理系统表结构调试讲解源码

基于springboot的大学奖学金评定管理系统 赠送自己录的运行教程视频&#xff0c;无经验也可以运行起来。 提供远程调试服务&#xff0c;加钱可远程帮忙运行起来。 项目功能: 二、项目功能介绍 管理员 个人中心&#xff1a;这是管理员的个人工作区域&#xff0c;允许管理员…

vue基础3

1.推荐好用的第三方框架 BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务 1.moment.js 2.dayjs 2.收集表达数据 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Document</title><…

MSYS2下载安装和使用

Minimalist GNU&#xff08;POSIX&#xff09;system on Windows&#xff0c;Windows下的GNU环境。 目录 1. 安装 2. pacman命令 3. 配置vim 4. 一些使用示例 4.1 编译代码 4.2 SSH登录远程服务器 1. 安装 官网下载&#xff1a;https://www.msys2.org/ 双击.exe文件&am…

【python】OpenCV—Faster Video File FPS

文章目录 1、需求描述2、正常方法 cv2.read3、加速方法 imutils.video.FileVideoStream4、涉及到的核心库函数4.1、imutils.video.FPS4.2、imutils.video.FileVideoStream 5、参考 1、需求描述 使用线程和队列数据结构将视频文件的 FPS 速率提高 &#xff01; 我们的目标是将…

解决Qt3D程序场景中无法显示创建的立体图形?

有的新手在创建Qt3D程序时&#xff0c;因为不熟练&#xff0c;导致经常遇到无法显示3D图形的情况。 原因其实也简单&#xff0c;就是设置的摄像机的位置不对&#xff0c;或者压根没有设置摄像机。 // CameraQt3DRender::QCamera *cameraEntity view.camera();cameraEntity-&g…

文件未保存后能否恢复?分享实用恢复指南,6个方法

在日常用电脑时文件未保存而导致的数据丢失&#xff0c;是许多人都会遭遇的棘手问题。那么面对这样的情况&#xff0c;文件真的能够恢复吗&#xff1f;本文将深入分析文件恢复的可能性&#xff0c;并提供一系列实用的建议。 一、了解文件恢复的基础 首先我们需要明白文件恢复并…

每一次新建终端固定到某个环境,配置PyCharm终端以自动激活环境

在PyCharm中&#xff0c;即使已经为项目设置了特定的Python解释器&#xff0c;默认情况下&#xff0c;新建的终端可能不会自动激活与项目绑定的Conda虚拟环境。要解决这个问题&#xff0c;可以采取以下步骤&#xff1a; 1. 配置PyCharm终端以自动激活环境 PyCharm支持为每个项…