A Blog

or A notebook

0%

Eigen Manual

前言

​ 记录Eigen库的使用方法。

头文件

​ 如Eigen官方教程中所示,头文件分为以下几种:

Eigen

​ 其中,较为常用的分别为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 基础矩阵运算
#include <Eigen/Core> // 必须包含
#include <Eigen/Dense> // 稠密矩阵扩展(推荐)

// 线性系统求解
#include <Eigen/LU> // LU分解
#include <Eigen/Cholesky> // Cholesky分解
#include <Eigen/QR> // QR分解

// 稀疏矩阵
#include <Eigen/Sparse> // 稀疏矩阵核心
#include <Eigen/SparseLU> // 稀疏LU求解器

// 几何变换
#include <Eigen/Geometry> // 旋转、平移等

初始化

静态初始化

​ 创建已知维度的矩阵,比如Matrix3d、Vector4f。Matrix2Xd (行数固定) MatrixX2d (列数固定)

  1. 逗号初始化

    1
    2
    3
    4
    5
    6
    7
    Eigen::Matrix3d mat;
    mat << 1, 2, 3,
    4, 5, 6,
    7, 8, 9;

    Eigen::Vector4d vec;
    vec << 1, 2, 3, 4;
  2. 构造函数初始化

    1
    2
    3
    Eigen::Matrix2d mat(1.0, 2.0,  // 按行填充
    3.0, 4.0);
    Eigen::Vector3d vec(1.0, 2.0, 3.0);

动态初始化

​ 创建可调节维度的矩阵,比如MatrixXd、VectorXf。

  1. 指定大小后赋值

    1
    2
    3
    4
    5
    6
    Eigen::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列
  2. 使用函数进行特殊赋值

    1
    2
    3
    Eigen::MatrixXd mat = Eigen::MatrixXd::Zero(3, 3); // 全0矩阵
    Eigen::VectorXf vec = Eigen::VectorXf::Ones(5); // 全1向量
    Eigen::Matrix3f I = Eigen::Matrix3f::Identity(); // 单位矩阵

特殊矩阵赋值

  1. 常量矩阵

    1
    Eigen::Matrix4f mat = Eigen::Matrix4f::Constant(3.14); // 所有元素为3.14
  2. 随机矩阵

    1
    Eigen::MatrixXd rand_mat = Eigen::MatrixXd::Random(3, 3); // 范围[-1, 1]
  3. 线性序列矩阵

    1
    Eigen::VectorXd lin_vec = Eigen::VectorXd::LinSpaced(5, 0, 10); // 0到10的5等分

映射赋值

1
2
3
double data[] = {1, 2, 3, 4};
Eigen::Map<Eigen::VectorXd> vec(data, 4); // 直接映射数组
Eigen::Map<Eigen::MatrixXd> mat(data, 2, 2); // 2x2矩阵

块操作

提取块

  1. 取固定大小的块 matrix.block(startRow, startCol)

    1
    2
    3
    4
    5
    6
    7
    8
    Eigen::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]
  2. 提取动态大小的块 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]
  3. 特殊位置的块

操作 语法 示例
前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
2
3
MatrixXcf a = MatrixXcf::Random(2,2);
cout << "Here is the matrix a^T\n" << a.transpose() << endl;
// a = a.transpose(); // 禁止

共轭

1
2
MatrixXcf a = MatrixXcf::Random(2,2);
cout << "Here is the conjugate of a\n" << a.conjugate() << endl;

共轭转置

1
2
MatrixXcf a = MatrixXcf::Random(2,2);
cout << "Here is the matrix a^*\n" << a.adjoint() << endl;

点积

两向量维度必须相同,输出标量

1
double dot_product = a.dot(b);

差积

叉积结果是一个新向量 c,其方向垂直于原始 a 和 b 所在的平面。仅三维向量

1
double angle = acos(a.dot(b) / (a.norm() * b.norm())); // 弧度制

归约操作

  1. 所有元素求和

    1
    double sum = mat.sum();
  2. 所有元素求积

    1
    double prod = mat.prod();
  3. 所有元素的平均值

    1
    double mean = mat.mean();
  4. 最小元素值

    1
    2
    3
    int row, col;
    double min_val = mat.minCoeff(&row, &col); // 获取最小值及其位置
    cout << "Min: " << min_val << " at (" << row << "," << col << ")" << endl;
  5. 最大元素值

    1
    2
    3
    int row, col;
    double max_val = mat.maxCoeff(&row, &col); // 获取最大值及其位置
    cout << "Max: " << max_val << " at (" << row << "," << col << ")" << endl;
  6. 矩阵的迹(主对角线元素之和)

    1
    double trace = mat.trace();
  7. 范数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Eigen::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>();