Eigen矩阵操作类 (Map, Block, 视图类)

1. Map 类:内存映射(零拷贝操作)

核心功能

将现有的 C/C++ 数组或缓冲区映射为 Eigen 矩阵/向量,不复制数据,直接操作原内存。

模板参数

cpp

复制代码
Map<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
  • 参数与 Matrix 一致,通常简化为 Map<MatrixXd>(动态大小)或 Map<Vector3f>(固定大小)。
构造函数与方法
方法/构造函数 参数说明 功能 示例
Map(Scalar* data) data: 原始数组指针 映射为一维向量 float arr[3]; Map<Vector3f> v(arr);
Map(Scalar* data, Index rows, Index cols) data: 数组指针,rows/cols: 矩阵尺寸 映射为矩阵 double buf[4]; Map<Matrix2d> m(buf, 2, 2);
data() 返回原始指针 float* ptr = v.data();
注意事项
  • 内存对齐 :若原始数据未对齐(如动态分配的数组),需使用 Eigen::Unaligned 标志:

    cpp

    复制代码
    Map<Matrix3f, Unaligned> m(ptr);

2. Block 类:子矩阵操作

核心功能

提取矩阵的某一块区域(子矩阵),返回一个视图(不复制数据)。

主要方法
方法 参数说明 返回值/功能 示例
block(Index startRow, Index startCol, Index blockRows, Index blockCols) startRow/startCol: 起始位置,blockRows/blockCols: 子块大小 动态大小子块 MatrixXd B = A.block(1, 1, 2, 2);
block<BlockRows, BlockCols>(startRow, startCol) 模板参数:子块固定大小,startRow/startCol: 起始位置 固定大小子块(编译时优化) auto C = A.block<2,2>(0, 0);
topLeftCorner(rows, cols) 提取左上角子块 block Matrix3f D = A.topLeftCorner(3, 3);
middleRows(startRow, numRows) 提取中间连续多行 行子矩阵 VectorXd seg = v.middleRows(2, 3);
变体方法
  • 列/行操作
    col(j).segment(start, length)(列向量的子段)、row(i).head(n)(行的前 n 元素)。

3. 视图类(Transpose, Diagonal 等)

核心功能

通过视图(View)操作原矩阵的特定结构(如转置、对角元素),不复制数据

常用视图类
类/方法 参数说明 功能 示例
transpose() 返回转置视图 MatrixXd AT = A.transpose();(注意:赋值会触发复制)
adjoint() 返回共轭转置视图 MatrixXcf AH = A.adjoint();
diagonal() 可指定偏移量(默认 0) 返回对角线的向量视图 VectorXd diag = A.diagonal();
diagonal<Offset>() Offset: 对角线的偏移(正数=上对角线,负数=下对角线) 返回指定对角线的视图 VectorXd sup_diag = A.diagonal<1>();
triangularView<Mode>() Mode: Upper, Lower, StrictlyUpper 返回三角矩阵视图 auto L = A.triangularView<Lower>();
视图的赋值与计算
  • 视图可直接参与运算,但若需保存结果,需赋值给具体矩阵:

    cpp

    复制代码
    MatrixXd B = A.transpose() * A;  // 合法:触发实际计算
    auto C = A.transpose();          // C 仍是视图,依赖 A 的生命周期!

4. 代码示例

cpp

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

// Map 示例
float data[] = {1, 2, 3, 4};
Map<Matrix<float, 2, 2, RowMajor>> mat_map(data);  // 按行映射
mat_map(1, 1) = 5;  // 修改原数组 data[3] = 5

// Block 示例
MatrixXd A(4, 4);
A.setRandom();
MatrixXd B = A.block(1, 1, 2, 2);  // 提取 2x2 子矩阵
A.topLeftCorner(2, 2).setZero();   // 将左上角置零

// 视图示例
Vector3d v(1, 2, 3);
MatrixXd M = v * v.transpose();     // 外积(v.transpose() 是视图)
double d = v.dot(v);                // 点积

5. 关键注意事项

  1. 生命周期管理 :视图类(如 BlockTranspose)依赖原矩阵的数据,原矩阵销毁后视图无效。

  2. 性能优化 :固定尺寸的 Block(如 block<2,2>())比动态尺寸更快。

  3. 别名问题:操作视图时避免与原矩阵混用,可能导致错误:

    cpp

    复制代码
    A = A.transpose();  // 错误!需使用 A.transposeInPlace();

完整方法速查表

操作类型 类/方法 典型用途
内存映射 Map<MatrixXd> 包装现有数组为 Eigen 矩阵
子块提取 block(), segment() 操作局部数据
结构视图 diagonal(), transpose() 快速访问对角线、转置等结构
相关推荐
黄卷青灯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
太阳风暴1 年前
Eigen-矩阵和向量运算
c++·线性代数·矩阵·eigen·矩阵向量运算·矩阵和向量运算
Fandes_F1 年前
vscode debug无法直接查看eigen变量的问题(解决方法)
c++·ide·vscode·编辑器·eigen