Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

三、矩阵基础篇:声明与基本运算

前置:已完成安装,了解 MatrixArray 的基本区别。

3.1 矩阵和向量的声明

Eigen 中,矩阵表示线性变换、系数表或二维数据;列向量表示坐标、状态、参数或观测值;行向量常用于一行数据、转置结果或统计场景。

后续章节默认以列向量作为主要约定;如果没有特别说明,VectorXd 一般指动态大小的列向量。

Eigen提供了丰富的类型别名,简化矩阵和向量的声明。

类型命名规则

Matrix[尺寸][数据类型]

尺寸:X = 动态大小, N = 固定大小 N (如 2, 3, 4)
数据类型:d = double, f = float, i = int, cd = complex<double>

常用类型速查表

类型完整定义说明
Matrix3dMatrix<double, 3, 3>3×3双精度矩阵
MatrixXdMatrix<double, Dynamic, Dynamic>动态双精度矩阵
Vector3fMatrix<float, 3, 1>3维单精度列向量
RowVector3dMatrix<double, 1, 3>3维双精度行向量
VectorXdMatrix<double, Dynamic, 1>动态双精度列向量
RowVectorXdMatrix<double, 1, Dynamic>动态双精度行向量

声明示例

// 固定大小矩阵(尺寸在编译期确定,通常更容易被优化)
Eigen::Matrix3d A;           // 3×3双精度矩阵
Eigen::Vector3d v1;          // 3维列向量

// 动态大小矩阵(尺寸在运行时确定)
Eigen::MatrixXd D(10, 10);   // 10×10双精度矩阵
Eigen::VectorXd v2(100);     // 100维动态列向量

// 特殊矩阵
Eigen::Matrix3d I = Eigen::Matrix3d::Identity();  // 单位矩阵
Eigen::MatrixXd Z = Eigen::MatrixXd::Zero(5, 5);  // 零矩阵
Eigen::MatrixXd R = Eigen::MatrixXd::Random(3, 3);// 随机矩阵

3.2 矩阵初始化方法

逗号初始化适合小型固定大小对象;循环赋值适合按规则填充;预定义函数适合零矩阵、单位矩阵、常量矩阵、随机矩阵等场景。

// 方法1:逗号初始化
Eigen::Matrix3d A;
A << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;

// 方法2:逐个元素赋值
Eigen::MatrixXd B(3, 3);
for (int i = 0; i < 3; ++i)
    for (int j = 0; j < 3; ++j)
        B(i, j) = i * 3 + j + 1;

// 方法3:预定义函数
Eigen::Matrix3d C = Eigen::Matrix3d::Zero();      // 全零
Eigen::Matrix3d D = Eigen::Matrix3d::Identity();  // 单位矩阵
Eigen::Matrix3d E = Eigen::Matrix3d::Constant(5); // 全为5
Eigen::Matrix3d F = Eigen::Matrix3d::Random();    // 随机值

3.3 基础矩阵运算

A * B 是矩阵乘法,A.array() * B.array() 是逐元素乘法。涉及 sqrtexp、逐元素乘除法时,使用 Array 视图。

Eigen::Matrix3d A, B;
A << 2, -1, 0,
     -1, 2, -1,
     0, -1, 2;                    // 可逆矩阵
B << 9, 8, 7,
     6, 5, 4,
     3, 2, 1;

// 算术运算
Eigen::Matrix3d C = A + B;        // 矩阵加法
Eigen::Matrix3d AB = A * B;       // 矩阵乘法
Eigen::Matrix3d scaled = A * 2.0; // 数乘

// 转置
Eigen::Matrix3d At = A.transpose();

// 矩阵属性
double det = A.determinant();       // 行列式
double tr = A.trace();              // 迹
double norm = A.norm();             // Frobenius范数
Eigen::Matrix3d Ainv = A.inverse(); // 逆矩阵(仅对可逆方阵有意义)

// 逐元素运算(需转换为Array)
Eigen::Matrix3d coeff_product = A.array() * B.array(); // 逐元素乘法

// 逐元素平方根要求元素非负;这里单独构造一个满足前提的示例矩阵
Eigen::Matrix3d P;
P << 1, 4, 9,
     16, 25, 36,
     49, 64, 81;
Eigen::Matrix3d sqrtP = P.array().sqrt();

3.4 向量运算

dot() 是点积,返回标量;cross() 限于三维向量;normalized() 返回新向量(不修改原对象),normalize() 原地修改。

Eigen::Vector3d v1(1, 2, 3);
Eigen::Vector3d v2(4, 5, 6);

// 基本运算
double dot = v1.dot(v2);          // 点积
Eigen::Vector3d cross = v1.cross(v2);  // 叉积(仅3D向量)
double norm = v1.norm();          // 欧几里得范数

// normalized() 返回新的归一化向量,不修改 v1 本身
Eigen::Vector3d normalized = v1.normalized();

// 向量元素运算(此时 v1 仍是原始值 {1, 2, 3})
v1.sum();                         // 所有元素之和
v1.prod();                        // 所有元素之积
v1.mean();                        // 平均值
v1.minCoeff();                    // 最小值
v1.maxCoeff();                    // 最大值

// normalize() 直接修改原向量
v1.normalize();  // 此后 v1 变为单位向量

3.5 数据类型与存储

blockMapRef、切片等功能与对象尺寸是否已知、内存是否连续、存储顺序密切相关。

  • 小矩阵优先用固定大小类型
  • 尺寸运行时确定时用动态大小类型
  • Eigen 默认列优先(ColMajor)

固定大小 vs 动态大小

特性固定大小 (Matrix3d)动态大小 (MatrixXd)
尺寸信息编译期已知运行时确定
性能对小而固定的矩阵通常更容易优化更灵活,但通常会有动态分配开销
适用场景小矩阵、尺寸固定场景大矩阵或尺寸未知

存储顺序

// Eigen默认列优先存储(与MATLAB、Fortran一致)
Eigen::Matrix<double, 3, 4, Eigen::ColMajor> A;  // 列优先(默认)
Eigen::Matrix<double, 3, 4, Eigen::RowMajor> B;  // 行优先(与C一致)

// 访问元素
A(i, j);  // 第i行第j列(从0开始)

对应官方文档The Matrix class | Matrix and vector arithmetic