Eigen中Dense 模块简要介绍和实战应用示例(最小二乘拟合直线、协方差矩阵计算和稀疏求解等)

1、Dense简介

1️.Dense 模块概述

Eigen::Dense 模块是 Eigen 的核心模块之一,主要用于处理 密集矩阵(Dense Matrix)和向量(Dense Vector) 。它与 Eigen 的稀疏矩阵模块(Eigen::Sparse)互补。

特点

  1. 支持固定和动态大小

    • 固定大小:如 Matrix3dVector4f
    • 动态大小:如 MatrixXdVectorXd
    • 优势:固定大小矩阵在编译期优化,速度快;动态大小矩阵灵活性高。
  2. 面向表达式模板(Expression Templates)

    • Eigen 的运算不是立即计算,而是构建表达式树
    • 优点:减少临时变量、延迟计算、优化性能
  3. 高性能

    • 内存连续(RowMajor 或 ColumnMajor,可选)
    • 支持 SIMD 向量化(如 SSE、AVX)
    • 适合线性代数、最小二乘、矩阵分解、几何变换等场景
  4. 丰富的线性代数支持

    • 基本运算:加减、乘除、转置
    • 矩阵分解:LU、QR、SVD、Cholesky、EigenSolver
    • 特殊矩阵生成:零矩阵、单位矩阵、全1矩阵
    • 块操作:block()row()col()segment()
  5. 模板化设计

    • 数据类型可选:floatdoubleint
    • 支持矩阵和向量混合运算

2️.Dense 模块核心类型

类型 描述 备注
Matrix<T, Rows, Cols> 通用矩阵 RowsCols 可固定或动态(用 Dynamic
Vector<T, Size> 列向量 等价于 Matrix<T, Size, 1>
RowVector<T, Size> 行向量 等价于 Matrix<T, 1, Size>
Array<T, Rows, Cols> 元素逐一运算 用于逐元素加减乘除等
DiagonalMatrix<T, Size> 对角矩阵 可与矩阵相乘或求逆
Quaternion<T> 四元数 用于旋转表示
AngleAxis<T> 旋转轴角表示 可转换为旋转矩阵

3.Dense 模块内部机制

  1. 内存布局

    • 默认按列主序(ColumnMajor)
    • 可改为行主序(Matrix<T, Rows, Cols, RowMajor>
  2. 表达式模板

    • 避免临时矩阵
    • 支持链式运算 A + B + C 高效执行
  3. 固定 vs 动态大小

    • 固定大小在编译期优化,适合小矩阵(如 2x2, 3x3)
    • 动态大小适合大矩阵(如点云处理、最小二乘)
  4. SIMD 向量化

    • 自动利用 CPU SIMD 指令(SSE/AVX)
    • 速度可接近手写优化代码

2、Eigen/Dense 基础

2.1 引入头文件

cpp 复制代码
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;
  • Eigen/Dense 会自动包含 Eigen 所有核心模块,适合大部分线性代数操作。
  • 使用 using namespace Eigen 简化类型书写。

2.2 向量类型

Eigen 中向量是矩阵的特殊情况,行向量或列向量。

cpp 复制代码
Vector3d v1(1.0, 2.0, 3.0);   // 列向量 3x1, double 类型
Vector3f v2(1.0f, 2.0f, 3.0f); // float 类型
VectorXd vDynamic(5);           // 动态大小向量
vDynamic << 1, 2, 3, 4, 5;
  • Vector3d → 3维 double 列向量
  • VectorXd → 动态维度列向量
  • << 可快速赋值

2.3 矩阵类型

cpp 复制代码
Matrix3d A; // 3x3 double 矩阵
MatrixXd B(2, 3); // 2x3 动态矩阵

A << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;

B << 1, 2, 3,
     4, 5, 6;
  • Matrix3d → 3x3 固定大小矩阵
  • MatrixXd → 动态大小矩阵
  • << 支持逐行填充

2.4 矩阵操作

cpp 复制代码
Matrix3d M;
M << 1, 2, 3,
     0, 1, 4,
     5, 6, 0;

// 转置
Matrix3d Mt = M.transpose();

// 逆矩阵
Matrix3d Minv = M.inverse();

// 矩阵乘法
Matrix3d R = M * Mt;

// 元素逐一操作
Matrix3d N = M.array() + 1.0; // 每个元素加1
Matrix3d P = M.array() * 2;   // 每个元素乘2
  • matrix.array() → 逐元素操作
  • matrix * matrix2 → 矩阵乘法
  • matrix.inverse() → 求逆(仅对方阵有效)

2.5 特殊矩阵生成

cpp 复制代码
Matrix3d I = Matrix3d::Identity(); // 单位矩阵
MatrixXd Z = MatrixXd::Zero(2, 3); // 零矩阵
MatrixXd O = MatrixXd::Ones(2, 3); // 全1矩阵

2.6 矩阵块操作

cpp 复制代码
Matrix3d M;
M << 1,2,3,
     4,5,6,
     7,8,9;

// 提取子矩阵
Matrix2d sub = M.block<2,2>(0,0); // 左上角2x2块

// 改变子矩阵
M.block<2,2>(1,1) = Matrix2d::Identity();
  • block<rows,cols>(i,j) → 固定大小块
  • block(i,j,rows,cols) → 动态块

2.7 特征值与奇异值分解

cpp 复制代码
Matrix3d A;
A << 1, 2, 3,
     0, 1, 4,
     5, 6, 0;

// Eigen值分解(仅对方阵)
EigenSolver<Matrix3d> es(A);
cout << "Eigenvalues:\n" << es.eigenvalues() << endl;
cout << "Eigenvectors:\n" << es.eigenvectors() << endl;

// 奇异值分解
JacobiSVD<MatrixXd> svd(A, ComputeFullU | ComputeFullV);
cout << "U:\n" << svd.matrixU() << endl;
cout << "S:\n" << svd.singularValues() << endl;
cout << "V:\n" << svd.matrixV() << endl;
  • EigenSolver → 特征值与特征向量
  • JacobiSVD → 奇异值分解,用于非方阵或最小二乘

3、Eigen 实战示例

示例1:最小二乘拟合直线

cpp 复制代码
int n = 5;
VectorXd x(n), y(n);
x << 0, 1, 2, 3, 4;
y << 1, 3, 7, 13, 21;

// 构造 A*x = b
MatrixXd A(n,2);
A.col(0) = VectorXd::Ones(n);
A.col(1) = x;

VectorXd coeff = A.colPivHouseholderQr().solve(y);
cout << "y = " << coeff(1) << " * x + " << coeff(0) << endl;
  • colPivHouseholderQr() 进行最小二乘求解
  • 输出拟合直线参数

示例2:旋转矩阵 + 向量变换(机器人/SLAM常用)

cpp 复制代码
Matrix3d R;
R = AngleAxisd(M_PI/4, Vector3d::UnitZ()).toRotationMatrix();
Vector3d t(1, 2, 3);
Vector3d p(1, 0, 0);

// 变换
Vector3d p_trans = R * p + t;
cout << "Transformed point: " << p_trans.transpose() << endl;
  • AngleAxisd → 构造绕某轴旋转的旋转矩阵
  • R*p + t → 坐标变换

示例3:点云质心和协方差矩阵

cpp 复制代码
MatrixXd points(3,5);
points << 1,2,3,4,5,
          0,1,0,1,0,
          2,3,4,5,6;

// 计算质心
Vector3d centroid = points.rowwise().mean();

// 去质心
MatrixXd centered = points.colwise() - centroid;

// 协方差矩阵
Matrix3d cov = (centered * centered.transpose()) / (points.cols() - 1);
cout << "Covariance matrix:\n" << cov << endl;
  • 常用于 PCA、点云处理、SLAM

示例4:动态稀疏求解(大规模线性系统)

cpp 复制代码
MatrixXd A = MatrixXd::Random(1000, 500);
VectorXd b = VectorXd::Random(1000);

// 最小二乘解
VectorXd x = A.colPivHouseholderQr().solve(b);
cout << "Residual norm: " << (A*x - b).norm() << endl;
  • 大规模系统可直接用 Eigen 的 QRSVD 求解
  • 高性能场景可使用稀疏模块(Eigen/Sparse

4、️总结与应用场景

Dense 模块特点

  • 面向密集矩阵、向量运算
  • 支持固定和动态维度
  • 支持矩阵运算、分解、块操作
  • 高度模板化,性能优秀

实战应用

  • 机器人/SLAM:位姿变换、最小二乘优化、点云协方差计算
  • 计算机视觉:PCA、SVD、特征提取
  • 数值计算:大规模线性方程求解、矩阵分解、特征值问题

相关推荐
计算机sci论文精选1 分钟前
CVPR 2025 | 具身智能 | HOLODECK:一句话召唤3D世界,智能体的“元宇宙练功房”来了
人工智能·深度学习·机器学习·计算机视觉·机器人·cvpr·具身智能
秋难降11 分钟前
LRU缓存算法(最近最少使用算法)——工业界缓存淘汰策略的 “默认选择”
数据结构·python·算法
Christo332 分钟前
SIGKDD-2023《Complementary Classifier Induced Partial Label Learning》
人工智能·深度学习·机器学习
CoovallyAIHub2 小时前
线性复杂度破局!Swin Transformer 移位窗口颠覆高分辨率视觉建模
深度学习·算法·计算机视觉
JXL18602 小时前
机器学习概念(面试题库)
人工智能·机器学习
星期天要睡觉2 小时前
机器学习深度学习 所需数据的清洗实战案例 (结构清晰、万字解析、完整代码)包括机器学习方法预测缺失值的实践
人工智能·深度学习·机器学习·数据挖掘
岁月静好20252 小时前
BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain
人工智能·机器学习
renhongxia12 小时前
大模型微调RAG、LORA、强化学习
人工智能·深度学习·算法·语言模型