前言
记录Eigen库的使用方法。
头文件
如Eigen官方教程中所示,头文件分为以下几种:
其中,较为常用的分别为
1 | // 基础矩阵运算 |
初始化
静态初始化
创建已知维度的矩阵,比如Matrix3d、Vector4f。Matrix2Xd (行数固定) MatrixX2d (列数固定)
逗号初始化
1
2
3
4
5
6
7Eigen::Matrix3d mat;
mat << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Eigen::Vector4d vec;
vec << 1, 2, 3, 4;构造函数初始化
1
2
3Eigen::Matrix2d mat(1.0, 2.0, // 按行填充
3.0, 4.0);
Eigen::Vector3d vec(1.0, 2.0, 3.0);
动态初始化
创建可调节维度的矩阵,比如MatrixXd、VectorXf。
指定大小后赋值
1
2
3
4
5
6Eigen::MatrixXd mat(2, 3); // 2行3列,未初始化
mat << 1, 2, 3,
4, 5, 6;
mat(0, 0) = 1.0; // 第1行第1列
mat(1, 1) = 4.0; // 第2行第2列使用函数进行特殊赋值
1
2
3Eigen::MatrixXd mat = Eigen::MatrixXd::Zero(3, 3); // 全0矩阵
Eigen::VectorXf vec = Eigen::VectorXf::Ones(5); // 全1向量
Eigen::Matrix3f I = Eigen::Matrix3f::Identity(); // 单位矩阵
特殊矩阵赋值
常量矩阵
1
Eigen::Matrix4f mat = Eigen::Matrix4f::Constant(3.14); // 所有元素为3.14
随机矩阵
1
Eigen::MatrixXd rand_mat = Eigen::MatrixXd::Random(3, 3); // 范围[-1, 1]
线性序列矩阵
1
Eigen::VectorXd lin_vec = Eigen::VectorXd::LinSpaced(5, 0, 10); // 0到10的5等分
映射赋值
1 | double data[] = {1, 2, 3, 4}; |
块操作
提取块
取固定大小的块 matrix.block
(startRow, startCol) 1
2
3
4
5
6
7
8Eigen::Matrix3d mat;
mat << 1, 2, 3,
4, 5, 6,
7, 8, 9;
// 提取左上角 2x2 子块
Eigen::Block<Eigen::Matrix3d, 2, 2> block = mat.block<2, 2>(0, 0);
cout << "2x2 Block:\n" << block << endl; // 输出 [1, 2; 4, 5]提取动态大小的块 matrix.block(startRow, startCol, rows, cols)
1
2
3// 提取右下角 2x2 子块(动态大小)
Eigen::MatrixXd dynamic_block = mat.block(1, 1, 2, 2);
cout << "Dynamic Block:\n" << dynamic_block << endl; // 输出 [5, 6; 8, 9]特殊位置的块
操作 | 语法 | 示例 |
---|---|---|
前n行 | matrix.topRows(n) | mat.topRows(2) → 前2行 |
后n行 | matrix.bottomRows(n) | mat.bottomRows(1) → 最后1行 |
左n行 | matrix.leftCols(n) | mat.leftCols(2) → 左2列 |
右n行 | matrix.rightCols(n) | mat.rightCols(1) → 右1列 |
任意行 | matrix.row(i) | mat.row(0) → 第1行 |
任意列 | matrix.col(j) | mat.col(1) → 第2列 |
主对角线 | matrix.diagonal() | mat.diagonal() → [1, 5, 9] |
特殊函数
转置
1 | MatrixXcf a = MatrixXcf::Random(2,2); |
共轭
1 | MatrixXcf a = MatrixXcf::Random(2,2); |
共轭转置
1 | MatrixXcf a = MatrixXcf::Random(2,2); |
点积
两向量维度必须相同,输出标量
1 | double dot_product = a.dot(b); |
差积
叉积结果是一个新向量 c,其方向垂直于原始 a 和 b 所在的平面。仅三维向量
1 | double angle = acos(a.dot(b) / (a.norm() * b.norm())); // 弧度制 |
归约操作
所有元素求和
1
double sum = mat.sum();
所有元素求积
1
double prod = mat.prod();
所有元素的平均值
1
double mean = mat.mean();
最小元素值
1
2
3int row, col;
double min_val = mat.minCoeff(&row, &col); // 获取最小值及其位置
cout << "Min: " << min_val << " at (" << row << "," << col << ")" << endl;最大元素值
1
2
3int row, col;
double max_val = mat.maxCoeff(&row, &col); // 获取最大值及其位置
cout << "Max: " << max_val << " at (" << row << "," << col << ")" << endl;矩阵的迹(主对角线元素之和)
1
double trace = mat.trace();
范数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Eigen::MatrixXd m(2, 2);
m << 1, 2,
3, 4;
// Frobenius 范数(类似于向量的 L2 范数)
double frob_norm = m.norm(); // sqrt(1² + 2² + 3² + 4²) = sqrt(30) ≈ 5.47723
// 平方范数
double frob_norm = squaredNorm(); // 等于上面的平方
// L1 范数(最大绝对列和)
double l1_norm = m.colwise().lpNorm<1>().maxCoeff(); // max(1+3, 2+4) = 6
// 无穷范数(最大绝对行和)
double inf_norm = m.rowwise().lpNorm<1>().maxCoeff(); // max(1+2, 3+4) = 7
// 谱范数(最大奇异值,即 L2 范数)
double l2_norm = m.lpNorm<2>();