当前位置: 首页 > news >正文

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)提取左上角子块同 blockMatrix3f 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. 视图类(TransposeDiagonal 等)

核心功能

通过视图(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>()ModeUpperLowerStrictlyUpper 等返回三角矩阵视图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()快速访问对角线、转置等结构

相关文章:

  • 系统设计(2)—Redis—消息队列—数据库—熔限降
  • babel核心知识点
  • 理想星环OS选择NuttX作为MCU侧OS的核心原因分析​
  • 在 Linux 上安装 PNPM 的教程
  • 20250426在ubuntu20.04.2系统上打包NanoPi NEO开发板的FriendlyCore系统刷机eMMC的固件
  • Windows---注册表
  • Redis | Redis集群模式技术原理介绍
  • 如何选择游戏支付平台呢?
  • 基于OpenMV+STM32+OLED与YOLOv11+PaddleOCR的嵌入式车牌识别系统开发笔记
  • LINUX426 文件权限rwx、ugo、高级权限(冒险、强制、粘滞位)、chmod修改权限 umask默认权限 软件包
  • C++---类和对象(二)
  • WPF 上位机开发模板
  • 动态规划求解leetcode300.最长递增子序列(LIS)详解
  • NdrpEmbeddedPointerUnmarshall函数分析之第二次循环处理第二部分DomainSid
  • 三维重建(二十)——思路整理与第一步的进行
  • MongoDB 入门使用教程
  • 算法习题-力扣446周赛题解
  • 关于调度策略的系统性解析与物流机器人应用实践
  • 机器学习基础理论 - 频率派 vs 贝叶斯派
  • 在 Ubuntu24.04 LTS 上 Docker 部署英文版 n8n 和 部署中文版 n8n-i18n-chinese
  • 杭州打造商业航天全产业链,请看《浪尖周报》第22期
  • 六朝文物草连空——丹阳句容南朝石刻考察纪
  • 知名计算机专家、浙江大学教授张森逝世
  • 地下管道密布成难题,道路修整如何破局?
  • “归雁经济”能带来什么?川大商学院调研团队深入乡村与返乡青年人才交流
  • 王旭任甘肃省副省长