Matlab和Eigen的对应用法
模块和头文件
- Core #include<Eigen/Core>,包含Matrix和Array类,基础的线性代数运算和数组操作。
- Geometry #include<Eigen/Geometry>,包含旋转,平移,缩放,2维和3维的各种变换。
- LU #include<Eigen/LU>,包含求逆,行列式,LU分解。
- Cholesky #include<Eigen/Cholesky>,包含LLT和LDLT Cholesky分解。
- SVD #include<Eigen/SVD>,包含SVD分解。
- QR #include<Eigen/QR>,包含QR分解。
- Eigenvalues #include<Eigen/Eigenvalues>,包含特征值,特征向量分解。
- Sparse #include<Eigen/Sparse>,包含稀疏矩阵的存储和运算。
- Dense #include<Eigen/Dense>,包含了Core/Geometry/LU/Cholesky/SVD/QR/Eigenvalues模块。
- Eigen #include<Eigen/Eigen>,包含Dense和Sparse。
1、Eigen库的基本数据变量
#include <Eigen/Dense>
Matrix<double, 3, 3> A; // 固定大小的双精度矩阵,和Matrix3d一样。
Matrix<double, 3, Dynamic> B; // 固定行数,列数为动态大小
Matrix<double, Dynamic, Dynamic> C; // 行数和列数都是动态大小,和MatrixXd一样。
Matrix<double, 3, 3, RowMajor> E; // 行优先的矩阵(默认是列优先)
Matrix3f P, Q, R; // 3x3 的浮点型矩阵
Vector3f x, y, z; // 3x1 的浮点型矩阵(列向量)
RowVector3f a, b, c; // 1x3 的浮点型矩阵(行向量)
VectorXd v; // 动态大小的双精度列向量
double s;
2、Eigen库用法(与matlab对比)
2.1 常见数据处理
Eigen | Matlab | 注释 |
---|---|---|
x.size() | length(x) | 向量的长度 |
C.rows() | size(C,1) | 矩阵的行数 |
C.cols()} | size(C,1) | 矩阵的列数 |
x(i) | x(i+1) | 访问向量元素(Matlab的下标从1开始计数) |
C(i,j) | C(i+1,1) | 访问矩阵元素 |
2.2 矩阵手动初始化
A << 1, 2, 3, // 初始化A。元素也可以是矩阵,先按列堆叠,再按行堆叠。
4, 5, 6,
7, 8, 9;
2.3 常见矩阵
Eigen | Matlab | 注释 |
---|---|---|
C.setIdentity(rows,cols) | C = eye(rows,cols) | 单位矩阵 |
C.setZero(rows,cols) | C = zeros(rows,cols) | 全零矩阵 |
C.setOnes(rows,cols) | C = ones(rows,cols) | 全一矩阵 |
C.setRandom(rows,cols) | C = rand(rows,cols)*2-1 | 返回范围为(-1, 1)的均匀分布的随机数 |
v.setLinSpaced(size,low,high) | v = linspace(low,high,size) | 返回size个等差数列,第一个数为low,最后一个数为high |
2.4 矩阵切片和块
注意:Matlab是的下标是从1开始的。
Eigen | Matlab | 注释 |
---|---|---|
x.head() | x(1:n) | 前n个元素 |
x.tail() | // x(end - n + 1: end) //倒数n个元素 | |
x.segment(i) | x(i+1 : i+n) | 切片 |
P.block<rows, cols>(i, j) | P(i+1 : i+rows, j+1 : j+cols) | 块 |
P.row(i) | P(i+1, : ) | 第i行 |
P.col(j) | P(:, j+1) | 第j列 |
P.leftCols() | P(:, 1:cols) | 前cols列 |
P.middleCols(j) | P(:, j+1:j+cols) | 中间cols列 |
P.rightCols() | P(:, end-cols+1:end) | 后cols列 |
P.topRows() | P(1:rows, : ) | 前rows行 |
P.middleRows(i) | P(i+1:i+rows, : ) | 中间rows行 |
P.bottomRows() | P(end-rows+1:end, : ) | 最后rows行 |
P.topLeftCorner<rows,cols>() | P(1:rows, 1:cols) | 左上角块 |
P.topRightCorner<rows,cols>() | P(1:rows, end-cols+1:end) | 右上角块 |
P.bottomLeftCorner<rows,cols>() | P(end-rows+1:end, 1:cols) | 左下角块 |
P.bottomRightCorner<rows,cols>() | P(end-rows+1:end, end-cols+1:end) | 右下角块 |
2.5 矩阵运算
Eigen | Matlab | 注释 |
---|---|---|
R.inverse() | inv( R ) | 求逆 |
R.adjoint() | R’ | 共轭转置 |
R.transpose() | R.’ or conj(R’) | 转置 |
R.diagonal() | diag( R ) | 对角元素 |
x.asDiagonal() | diag(x) | 矩阵对角化 |
R = P.cwiseProduct(Q) | R = P .* Q | 逐元素乘法 |
R = P.array() * s.array() | R = P .* s | 逐元素乘法(s为标量) |
R = P.cwiseQuotient(Q) | R = P ./ Q | 逐元素除法 |
R = P.array() / Q.array() | R = P ./ Q | 逐元素除法 |
R = P.array() + s.array() | R = P + s | 逐元素加法(s为标量) |
R = P.array() - s.array() | R = P - s | 逐元素减法(s为标量) |
R.array() += s | R = R + s | 逐元素加法(s为标量) |
R.array() -= s | R = R - s | 逐元素减法(s为标量) |
R.array() < Q.array() | R < Q | 逐元素比较运算 |
R.array() <= Q.array() | R <= Q | 逐元素比较运算 |
R.cwiseInverse() | 1 ./ P | 逐元素取倒数 |
R.array().inverse() | 1 ./ P | 逐元素取倒数 |
R.array().sin() | sin( P) | 逐元素计算正弦函数 |
R.array().cos() | cos( P) | 逐元素计算余弦函数 |
R.array().pow(s) | P .^ s | 逐元素计算幂函数 |
R.array().square() | P .^ 2 | 逐元素计算平方 |
R.array().cube() | P .^ 3 | 逐元素计算立方 |
R.cwiseSqrt() | sqrt( P) | 逐元素计算平方根 |
R.array().sqrt() | sqrt( P) | 逐元素计算平方根 |
R.array().exp() | exp( P) | 逐元素计算指数函数 |
R.array().log() | log( P) | 逐元素计算对数函数 |
R.cwiseMax( P) | max(R, P) | 逐元素计算R和P的最大值 |
R.array().max(P.array()) | max(R, P) | 逐元素计算R和P的最大值 |
R.cwiseMin( P) | min(R, P) | 逐元素计算R和P的最小值 |
R.array().min(P.array()) | min(R, P) | 逐元素计算R和P的最小值 |
R.cwiseAbs( ) | abs§ | 逐元素计算R和P的绝对值 |
R.array().abs() | abs§ | 逐元素计算绝对值 |
R.cwiseAbs2() | abs(P.^2) | 逐元素计算平方 |
R.array().abs2() | abs(P.^2) | 逐元素计算平方 |
(R.array() < s).select(P,Q) | (R < s ? P : Q) | 根据R的元素值是否小于s,选择P和Q的对应元素 |
R = (Q.array()==0).select(P,A) | R(Q==0 ) = P(Q ==0) R(Q!=0) = P(Q!=0) | 根据Q中元素等于零的位置选择P中元素 |
R.minCoeff() | min(R( : )) | 最小值 |
R.maxCoeff() | max(R( : )) | 最大值 |
s = R.minCoeff(&r, &c) | [s, i] = min(R( : )); [r, c] = ind2sub(size( R ), i) | 计算最小值和它的位置 |
s = R.maxCoeff(&r, &c) | [s, i] = max(R( : )); [r, c] = ind2sub(size( R ), i) | 计算最大值和它的位置 |
R.sum() | sum(R( : )) | 求和(所有元素) |
R.colwise().sum() | sum( R ) | 按列求和 |
R.rowwise().sum() | sum(R, 2) or sum(R’)’ | 按行求和 |
R.prod() | prod(R( : )) | 累积 |
R.colwise().prod() | prod® | 按列累积 |
R.rowwise().prod() | prod(R, 2) or prod(R’)’ | 按行累积 |
R.trace() | trace( R ) | 迹 |
R.all() | all(R( : )) | 是否所有元素都非零 |
R.colwise().all() | all( R ) | 按列判断,是否该列所有元素都非零 |
R.rowwise().all() | all(R, 2) | 按行判断,是否该行所有元素都非零 |
R.any() | any(R( : )) | 是否有元素非零 |
R.colwise().any() | any( R ) | 按列判断,是否该列有元素都非零 |
R.rowwise().any() | any(R, 2) | 按行判断,是否该行有元素都非零 |
x.norm() | norm(x) | 范数(注意:Eigen中没有norm®) |
x.squaredNorm() | dot(x, x) | 平方和(注意:对于复数而言,不等价) |
x.dot(y) | dot(x, y) | 点积 |
x.cross(y) | cross(x, y) | 交叉积,需要头文件 #include <Eigen/Geometry> |
2.6 类型转换
Eigen | Matlab | 注释 |
---|---|---|
A.cast< double >() | double(A) | 变成双精度类型 |
A.cast< float >() | single(A) | 变成单精度类型 |
A.cast< int >() | int32(A) | 编程整型 |
A.real() | real(A) | 实部 |
A.imag() | imag(A) | 虚部 |
2.7 Eigen 可以将已存储数据的缓存映射成Eigen矩阵
float array[3];
Vector3f::Map(array).fill(10);
int data[4] = {1, 2, 3, 4};
Matrix2i mat2x2(data); // 将 data 复制到 mat2x2
Matrix2i::Map(data) = 2mat2x2; // 使用 2mat2x2 覆写data的元素
MatrixXi::Map(data, 2, 2) += mat2x2; // 将 mat2x2 加到 data的元素上 (当编译时不知道大小时,可选语法)
2.8 求解线性方程组 Ax = b。
结果保存在x中。 Matlab: x = A \ b.
x = A.ldlt().solve(b)); // #include <Eigen/Cholesky>
x = A.llt() .solve(b)); // #include <Eigen/Cholesky>
x = A.lu() .solve(b)); // 稳定,快速 #include <Eigen/LU>
x = A.qr() .solve(b)); // No pivoting. #include <Eigen/QR>
x = A.svd() .solve(b)); // 稳定,慢速 #include <Eigen/SVD>
2.8 特征值问题
Eigen | Matlab | 注释 |
---|---|---|
A.eigenvalues() | eig(A) | 特征值 |
EigenSolver eig(A) | [vec val] = eig(A) | 特征值求解器 |
eig.eigenvalues() | diag(val) | 特征值,向量形式 |
eig.eigenvectors() | vec(val) | 特征向量,矩阵形式 |
- 对于伴矩阵(Hermitian矩阵或对称矩阵),使用SelfAdjointEigenSolver<>