Eigen学习与使用

Eigen是一个C++开源线性代数库,采用模板方式实现,无需链接库文件,只需引入头文件即可使用。支持动态和静态矩阵定义,提供丰富的矩阵操作,如矩阵运算、转置、共轭、伴随和对角矩阵等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介
Eigen是一个C++开源线性代数库,Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。在使用时,只需引入Eigen的头文件,不需链接库文件(没有库文件)。
在这里插入图片描述
数组、矩阵和向量的表示

typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;     //矩阵
typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;    //行列式
//Scalar为数据类型,如,float,double,bool,int...
//RowATCompileTime为行数
//ColsAtCompileTime为列数
//Options为数据存储方式,分为按列存储(ColMajor)和按行存储(RowMajor),默认为按列存储

Eigen支持定义动态矩阵和静态矩阵:

Matrix<double, 6, Dynamic>                  // Dynamic number of columns (heap allocation)
Matrix<double, Dynamic, 2>                  // Dynamic number of rows (heap allocation)
Matrix<double, Dynamic, Dynamic, RowMajor>  // Fully dynamic, row major (heap allocation)
Matrix<double, 13, 3>                       // Fully fixed (usually allocated on stack)

在大多数情况下,矩阵和数组都有简单的表示方式:

Matrix<float,Dynamic,Dynamic>   <=>   MatrixXf
Matrix<double,Dynamic,1>        <=>   VectorXd
Matrix<int,1,Dynamic>           <=>   RowVectorXi
Matrix<float,3,3>               <=>   Matrix3f
Matrix<float,4,1>               <=>   Vector4f

Array<float,Dynamic,Dynamic>    <=>   ArrayXXf
Array<double,Dynamic,1>         <=>   ArrayXd
Array<int,1,Dynamic>            <=>   RowArrayXi
Array<float,3,3>                <=>   Array33f
Array<float,4,1>                <=>   Array4f

访问和赋值:
与 C++ 数组的操作不同的是,Eigen::Matrix 是不能通过 [] 来访问赋值数据的,而是需要通过 ()。矩阵之间也可以通过 = 来进行赋值(拷贝)。

MatrixXd mat,mat1,mat2;
int x;
x = mat(a, b);  //  获取到矩阵 mat 的 a 行 b 列的元素并赋值给 x
mat(b, a) = x;  //  将 x 赋值给矩阵 mat 的 b 行 a 列
mat1 = mat2;    //  将矩阵 mat2 赋值(拷贝)给矩阵 mat1
//通过 = 进行矩阵之间的拷贝时,如果左右两侧矩阵尺寸不一样并且左侧矩阵为动态矩阵,那么会将左侧矩阵的尺寸修改为与右侧一致。

在 Eigen 中还重载了 << 可以用来赋值矩阵,也可以用来 cout 输出矩阵。

MatrixXf m(4, 4);   //  定义一个 4x4 的 float 类型的动态矩阵
m << 1, 2, 3, 4,
     5, 6, 7, 8,
     9, 10, 11, 12,
     13, 14, 15, 16;//  赋值
std::cout << m;     //  输出 m

Eigen矩阵还可以进行分块操作,通过成员函数block()获取某一部分矩阵。

mat = mat1.block(i, j, p, q);   //  从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵
mat = mat1.block<p, q>(i, j);   //  从矩阵 mat1 的 i 行 j 列开始获取一个 p 行 q 列的子矩阵(动态矩阵)

Eigen矩阵可以使用成员函数row()、col()来获取某一行或某一列。

mat = mat1.row(i);  //  获取 mat1 的第 i 行
mat = mat1.col(j);  //  获取 mat1 的第 j 列  

Eigen矩阵还可以使用成员函数fill()进行统一赋值。

mat.fill(n);    //  将 mat 的所有元素均赋值为 n

矩阵运算
Eigen 重载了 +、−(减)、∗、/、−(负)、+=、−=、∗=、/=。

mat = mat1 + mat2;  //  +
mat = mat1 - mat2;  //  -(减)
mat = mat1 * mat2;  //  *
mat = mat1 * n;     //  *
mat = mat1 / n;     //  /
mat = -mat1;        //  -(负)
mat += mat1;        //  +=
mat -= mat1;        //  -=
mat *= mat1;        //  *=
mat *= n;           //  *=
mat /= n;           //  /=

对于 Matrix 的转置矩阵、共轭矩阵、伴随矩阵、对角矩阵可以通过成员函数transpose()、conjugate()、adjoint()、diagonal() 来获得,如果想要在原矩阵上进行转换,则需要通过成员函数transposeInPlace()、conjugateInPlace()、adjointInPlace()、diagonalInPlace() 。

mat = mat1.transpose(); //  获取 mat1 的转置矩阵
mat = mat1.conjugate(); //  获取 mat1 的共轭矩阵
mat = mat1.adjoint();   //  获取 mat1 的伴随矩阵
mat = mat1.diagonal();  //  获取 mat1 的对角矩阵
mat1.transposeInPlace();//  mat1 转换为对应的转置矩阵
mat1.conjugateInPlace();//  mat1 转换为对应的共轭矩阵
mat1.adjointInPlace();  //  mat1 转换为对应的伴随矩阵
mat1.diagonalInPlace(); //  mat1 转换为对应的对角矩阵
mat1.transpose().colwise().reverse();   //  mat1 Rot90

动态矩阵可以通过成员函数 resize() 来进行修改大小,静态矩阵是不可以 resize() 的,并且动态矩阵 resize() 后元素不能保证不变。

mat.resize(rows, cols); //  将动态矩阵 mat 大小尺寸修改为 rows x cols
### Eigen库的使用方法教程 #### 1. 安装配置 Eigen库是一个轻量级的C++开源模板库,专注于线性代数运算。它的一个重要特点是完全基于头文件实现,因此无需编译或链接额外的动态/静态库[^2]。 在项目中集成Eigen库非常简单,只需将Eigen的头文件目录添加到项目的包含路径中即可。如果使用CMake构建系统,则可以通过`find_package(Eigen3 REQUIRED)`来查找并加载Eigen库;或者手动指定头文件路径,例如: ```cmake include_directories(/path/to/eigen-3.4.0) ``` #### 2. 基本概念 在Eigen中,所有的矩阵和向量都由`Matrix`模板类表示[^4]。该类具有高度灵活性,可以定义任意维度的矩阵以及固定大小或动态大小的矩阵。 以下是创建矩阵的一些基本方式: - 动态大小矩阵:`Eigen::MatrixXd matrix(rows, cols);` - 静态大小矩阵:`Eigen::Matrix3d matrix;` (用于3×3双精度浮点型矩阵) #### 3. 创建初始化矩阵 下面展示如何创建一个简单的矩阵并对其进行初始化[^3]: ```cpp #include <iostream> #include <Eigen/Dense> int main() { // 创建一个3x3的矩阵 Eigen::Matrix3d A; // 初始化矩阵A A << 1, 0, 0, 0, 2, 0, 0, 0, 3; std::cout << "Matrix A:\n" << A << "\n\n"; return 0; } ``` 这段代码展示了如何通过逗号分隔的方式快速填充矩阵的内容。 #### 4. 特征值分解 Eigen提供了强大的功能来进行特征值分解。以下是如何计算矩阵的特征值和特征向量的例子[^3]: ```cpp #include <iostream> #include <Eigen/Dense> int main() { // 创建一个3x3的矩阵 Eigen::Matrix3d A; A << 1, 0, 0, 0, 2, 0, 0, 0, 3; // 使用SelfAdjointEigenSolver进行特征值分解 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> solver(A); // 输出特征值 std::cout << "Eigenvalues of A:\n" << solver.eigenvalues().transpose() << "\n\n"; // 输出特征向量 std::cout << "Eigenvectors of A:\n" << solver.eigenvectors() << "\n\n"; return 0; } ``` 以上程序会打印出矩阵A的所有特征值及其对应的特征向量。 #### 5. 矩阵操作 除了基础的矩阵创建外,Eigen还支持丰富的矩阵操作,比如加法、乘法、转置等。以下是一些常见的操作示例: ```cpp #include <iostream> #include <Eigen/Dense> int main() { // 创建两个矩阵 Eigen::Matrix2d B, C; B << 1, 2, 3, 4; C << 5, 6, 7, 8; // 加法 Eigen::Matrix2d sum = B + C; std::cout << "Sum of matrices:\n" << sum << "\n\n"; // 转置 Eigen::Matrix2d transpose_B = B.transpose(); std::cout << "Transpose of B:\n" << transpose_B << "\n\n"; // 乘法 Eigen::Matrix2d product = B * C; std::cout << "Product of matrices:\n" << product << "\n\n"; return 0; } ``` 这些操作均能高效执行,并充分利用现代CPU架构的优势。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值