Eigen函数查找

Eigen头文件

#include<Eigen/Core>,包含Matrix和Array类,基础的线性代数运算和数组操作。
#include<Eigen/Geometry>,包含旋转,平移,缩放,2维和3维的各种变换。
#include<Eigen/LU>,包含求逆,行列式,LU分解。
#include<Eigen/Cholesky>,包含LLT和LDLT Cholesky分解。
#include<Eigen/SVD>,包含SVD分解。
#include<Eigen/QR>,包含QR分解。
#include<Eigen/Eigenvalues>,包含特征值,特征向量分解。
#include<Eigen/Sparse>,包含稀疏矩阵的存储和运算。
#include<Eigen/Dense>,包含了Core/Geometry/LU/Cholesky/SVD/QR/Eigenvalues模块。
#include<Eigen/Eigen>,包含Dense和Sparse。

坐标系之间的变化

 geodetic2enu enu2geodetic

姿态表示的操作可以参考
其他姿态变换按照网址查即可

姿态的操作

坐标系从0坐标系变换到1坐标系,变换关系为 R 01 R_{01} R01,这个时候如果1系有个坐标点 p 1 p_1 p1,要转到原0系下的坐标就表示为: p 0 = R 01 ∗ p 1 p_0 = R_{01} * p_1 p0=R01p1

  • Eigen使用的角度是弧度制的,坐标都是取得是:x轴向前,y轴向右,z轴向下
  • 坐标系变换先变换yaw R 01 R_{01} R01,再变换pitch R 12 R_{12} R12,最后再变换roll R 23 R_{23} R23,用Eigen的轴角表示就是,物理意义就是,变换之后坐标系的一个点 p 3 p_3 p3 通过以下的变换 R 03 R_{03} R03 就可以变到变换之前的状态 p 0 p_0 p0
Eigen::Matrix3d r03 =Eigen::AngleAxisd(yaw,Eigen::Vector3d::UnitZ())*
                       Eigen::AngleAxisd(pitch, Eigen::Vector3d::UnitY()) *
                       Eigen::AngleAxisd(roll, Eigen::Vector3d::UnitX());
  • 解析欧拉角的操作为旋转的反操作,得到的就是以上的公式得到的yaw,pitch,roll
Eigen::Vector3d ypr = rotation_vector1.matrix().eulerAngles(2,1,0);

表示姿态的操作

  • Eigen使用的角度是弧度制的
// 头文件

```cpp
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <iostream>
 
#include <Eigen/Core>
#include <Eigen/Geometry>
 
using namespace std;
 
#define PI (3.1415926535897932346f)
 
int main(int argc, char **argv) 
{
    /**** 1. 旋转向量 ****/
    cout << endl << "********** AngleAxis **********" << endl;
    //1.0 初始化旋转向量,沿Z轴旋转45度的旋转向量
    Eigen::AngleAxisd rotation_vector1 (M_PI/4, Eigen::Vector3d(0, 0, 1)); 
 
    //1.1 旋转向量转换为旋转矩阵
    //旋转向量用matrix()转换成旋转矩阵
    Eigen::Matrix3d rotation_matrix1 = Eigen::Matrix3d::Identity();
    rotation_matrix1 = rotation_vector1.matrix();
    cout << "rotation matrix1 =\n" << rotation_matrix1 << endl;                
    //或者由罗德里格公式进行转换
    rotation_matrix1 = rotation_vector1.toRotationMatrix();
    cout << "rotation matrix1 =\n" << rotation_matrix1 << endl; 
 
    /*1.2 旋转向量转换为欧拉角*/
    //将旋转向量转换为旋转矩阵,再由旋转矩阵转换为欧拉角,详见旋转矩阵转换为欧拉角
    Eigen::Vector3d eulerAngle1 = rotation_vector1.matrix().eulerAngles(2,1,0);
    cout << "eulerAngle1, z y x: " << eulerAngle1 << endl;
 
    /*1.3 旋转向量转四元数*/
    Eigen::Quaterniond quaternion1(rotation_vector1);
    //或者
    Eigen::Quaterniond quaternion1_1;
    quaternion1_1 = rotation_vector1;
    cout << "quaternion1 x: " << quaternion1.x() << endl;
    cout << "quaternion1 y: " << quaternion1.y() << endl;
    cout << "quaternion1 z: " << quaternion1.z() << endl;
    cout << "quaternion1 w: " << quaternion1.w() << endl;
    
    cout << "quaternion1_1 x: " << quaternion1_1.x() << endl;
    cout << "quaternion1_1 y: " << quaternion1_1.y() << endl;
    cout << "quaternion1_1 z: " << quaternion1_1.z() << endl;
    cout << "quaternion1_1 w: " << quaternion1_1.w() << endl;
 
 
    /**** 2. 旋转矩阵 *****/
    cout << endl << "********** RotationMatrix **********" << endl;
    //2.0 旋转矩阵初始化
    Eigen::Matrix3d rotation_matrix2;
    rotation_matrix2 << 0.707107, -0.707107, 0, 0.707107, 0.707107, 0, 0, 0, 1;
;
    //或直接单位矩阵初始化
    Eigen::Matrix3d rotation_matrix2_1 = Eigen::Matrix3d::Identity();
 
    //2.1 旋转矩阵转换为欧拉角
    //ZYX顺序,即先绕x轴roll,再绕y轴pitch,最后绕z轴yaw,0表示X轴,1表示Y轴,2表示Z轴
    Eigen::Vector3d euler_angles = rotation_matrix2.eulerAngles(2, 1, 0); 
    cout << "yaw(z) pitch(y) roll(x) = " << euler_angles.transpose() << endl;
 
    //2.2 旋转矩阵转换为旋转向量
    Eigen::AngleAxisd rotation_vector2;
    rotation_vector2.fromRotationMatrix(rotation_matrix2);
    //或者
    Eigen::AngleAxisd rotation_vector2_1(rotation_matrix2);
    cout << "rotation_vector2 " << "angle is: " << rotation_vector2.angle() * (180 / M_PI) 
                                << " axis is: " << rotation_vector2.axis().transpose() << endl;
 
    cout << "rotation_vector2_1 " << "angle is: " << rotation_vector2_1.angle() * (180 / M_PI) 
                                  << " axis is: " << rotation_vector2_1.axis().transpose() << endl;
 
    //2.3 旋转矩阵转换为四元数
    Eigen::Quaterniond quaternion2(rotation_matrix2);
    //或者
    Eigen::Quaterniond quaternion2_1;
    quaternion2_1 = rotation_matrix2;
    cout << "quaternion2 x: " << quaternion2.x() << endl;
    cout << "quaternion2 y: " << quaternion2.y() << endl;
    cout << "quaternion2 z: " << quaternion2.z() << endl;
    cout << "quaternion2 w: " << quaternion2.w() << endl;
    
    cout << "quaternion2_1 x: " << quaternion2_1.x() << endl;
    cout << "quaternion2_1 y: " << quaternion2_1.y() << endl;
    cout << "quaternion2_1 z: " << quaternion2_1.z() << endl;
    cout << "quaternion2_1 w: " << quaternion2_1.w() << endl;
 
 
    /**** 3. 欧拉角 ****/
    cout << endl << "********** EulerAngle **********" << endl;
    //3.0 初始化欧拉角(Z-Y-X,即RPY, 先绕x轴roll,再绕y轴pitch,最后绕z轴yaw)
    Eigen::Vector3d ea(0.785398, -0, 0);
 
    //3.1 欧拉角转换为旋转矩阵
    Eigen::Matrix3d rotation_matrix3;
    rotation_matrix3 = Eigen::AngleAxisd(ea[0], Eigen::Vector3d::UnitZ()) * 
                       Eigen::AngleAxisd(ea[1], Eigen::Vector3d::UnitY()) * 
                       Eigen::AngleAxisd(ea[2], Eigen::Vector3d::UnitX());
    cout << "rotation matrix3 =\n" << rotation_matrix3 << endl;   
 
    //3.2 欧拉角转换为四元数,
    Eigen::Quaterniond quaternion3;
    quaternion3 = Eigen::AngleAxisd(ea[0], Eigen::Vector3d::UnitZ()) * 
                  Eigen::AngleAxisd(ea[1], Eigen::Vector3d::UnitY()) * 
                  Eigen::AngleAxisd(ea[2], Eigen::Vector3d::UnitX());
    cout << "quaternion3 x: " << quaternion3.x() << endl;
    cout << "quaternion3 y: " << quaternion3.y() << endl;
    cout << "quaternion3 z: " << quaternion3.z() << endl;
    cout << "quaternion3 w: " << quaternion3.w() << endl;
 
    //3.3 欧拉角转换为旋转向量
    Eigen::AngleAxisd rotation_vector3;
    rotation_vector3 = Eigen::AngleAxisd(ea[0], Eigen::Vector3d::UnitZ()) * 
                       Eigen::AngleAxisd(ea[1], Eigen::Vector3d::UnitY()) * 
                       Eigen::AngleAxisd(ea[2], Eigen::Vector3d::UnitX());  
    cout << "rotation_vector3 " << "angle is: " << rotation_vector3.angle() * (180 / M_PI) 
                                << " axis is: " << rotation_vector3.axis().transpose() << endl;
 
 
    /**** 4.四元数 ****/
    cout << endl << "********** Quaternion **********" << endl;
    //4.0 初始化四元素,注意eigen Quaterniond类四元数初始化参数顺序为w,x,y,z
    Eigen::Quaterniond quaternion4(0.92388, 0, 0, 0.382683);
 
    //4.1 四元数转换为旋转向量
    Eigen::AngleAxisd rotation_vector4(quaternion4);
    //或者
    Eigen::AngleAxisd rotation_vector4_1;
    rotation_vector4_1 = quaternion4;
    cout << "rotation_vector4 " << "angle is: " << rotation_vector4.angle() * (180 / M_PI) 
                                << " axis is: " << rotation_vector4.axis().transpose() << endl;
 
    cout << "rotation_vector4_1 " << "angle is: " << rotation_vector4_1.angle() * (180 / M_PI) 
                                  << " axis is: " << rotation_vector4_1.axis().transpose() << endl;
 
    //4.2 四元数转换为旋转矩阵
    Eigen::Matrix3d rotation_matrix4;
    rotation_matrix4 = quaternion4.matrix();
    Eigen::Matrix3d rotation_matrix4_1;
    rotation_matrix4_1 = quaternion4.toRotationMatrix();
    cout << "rotation matrix4 =\n" << rotation_matrix4 << endl;
    cout << "rotation matrix4_1 =\n" << rotation_matrix4_1 << endl;      
 
 
    //4.4 四元数转欧拉角(Z-Y-X,即RPY)
    Eigen::Vector3d eulerAngle4 = quaternion4.matrix().eulerAngles(2,1,0);
    cout << "yaw(z) pitch(y) roll(x) = " << eulerAngle4.transpose() << endl;
 
 
    return 0;
}

四元数的操作

定义两个四元数。四元数和一般的数组或者向量在构造上没有区别,只是理解的方法(运算结果)不一样而已
p=[1 2 3 4];
q=[4,3,2,1];
模(Modulus):quatmod(p)    %  5.4772
范数(Norm):quatnorm(p)   0
单位化(Normalize):quatnormalize(p)   %  0.1826   0.3651   0.5477   0.7303
求逆(Inverse):quatinv(p)   %0.0333   -0.0667   -0.1000   -0.1333
四元数除法:quatdivide(q,p)   %0.6667        0   -0.6667   -0.3333
四元数乘法:quatmultiply(p,q)  % -12     6   24    12
共轭四元数:quatconj(p)     % 1    -2    -3   -4 
另外还有旋转函数quatrotate、四元数和欧拉角互换的函数quat2angle、angle2quat

四元数转矩阵
q1=quatnormalize(q1); %单位化  
R1=quat2dcm(q1);%q1的第一位是实部

R2=eul2rotm(eul,'ZYX');%欧拉角转旋转矩阵
欧拉角转四元数
q = angle2quat(yaw/180*pi,pitch/180*pi,roll/180*pi); 
欧拉角转旋转矩阵
R = angle2dcm(yaw/180*pi,pitch/180*pi,roll/180*pi);
四元数转旋转矩阵
R=quat2dcm([q0 q1 q2 q3])
旋转矩阵转四元数
q =dcm2quat(R);

欧拉角转四元数
q=angle2quat(r1,r2,r3,S);

以下两种输出都是以Eigen中的向量Vector形式输出
q.coeffs();     //[x y z w] 输出系数
q.vec();    //[x y z] 输出虚部

输出选择矩阵,四元数表示旋转矩阵首先要进行单位化,单位矩阵才能表示旋转矩阵
q.normalized();	//important
Matrix3d R=q.toRotationMatrix();

共轭反向矩阵,一般不用inverse,在表示旋转的时候(范数是1),共轭即可表示相反的的旋转。
//q.inverse();
q.conjugate();

遍历元素
cout<<q.w()<<"  "<<q.x()<<"  "<<q.y()<<"  "<<q.z()<<endl;

单元素操作

// Vectorized operations on each element independently
// Eigen                  // Matlab
R = P.cwiseProduct(Q);    // R = P .* Q
R = P.array() * s.array();// R = P .* s
R = P.cwiseQuotient(Q);   // R = P ./ Q
R = P.array() / Q.array();// R = P ./ Q
R = P.array() + s.array();// R = P + s
R = P.array() - s.array();// R = P - s
R.array() += s;           // R = R + s
R.array() -= s;           // R = R - 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.array().max(P.array())  // max(R, P)
R.cwiseMin(P)             // min(R, P)
R.array().min(P.array())  // min(R, P)
R.cwiseAbs()              // abs(P)
R.array().abs()           // abs(P)
R.cwiseAbs2()             // abs(P.^2)
R.array().abs2()          // abs(P.^2)
(R.array() < s).select(P,Q);  // (R < s ? P : Q)

Matrix类

Matrix<typename Scalar, 
       int RowsAtCompileTime, 
       int ColsAtCompileTime,
       int Options = 0,
       int MaxRowsAtCompileTime = RowsAtCompileTime,
       int MaxColsAtCompileTime = ColsAtCompileTime>
# Scalar 元素类型
# RowsAtCompileTime 行
# ColsAtCompileTime 列
# 例 typedef Matrix<int, 3, 3> Matrix3i;
# Options 比特标志位
# MaxRowsAtCompileTime和MaxColsAtCompileTime表示在编译阶段矩阵的上限。

# 列向量
typedef Matrix<double, 3, 1> Vector3d;
# 行向量
typedef Matrix<float, 1, 3> RowVector3f;

# 动态大小
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<float, Dynamic, 1> VectorXf;
type

矩阵与向量的运算

MatrixXcf a = MatrixXcf::Random(3,3);
a.transpose();  # 转置
a.conjugate();  # 共轭
a.adjoint();       # 共轭转置(伴随矩阵)
# 对于实数矩阵,conjugate不执行任何操作,adjoint等价于transpose
a.transposeInPlace() #原地转置

Vector3d v(1,2,3);
Vector3d w(4,5,6);
v.dot(w);    # 点积
v.cross(w);  # 叉积

Matrix2d a;
a << 1, 2, 3, 4;
a.sum();      # 所有元素求和
a.prod();      # 所有元素乘积
a.mean();    # 所有元素求平均
a.minCoeff();    # 所有元素中最小元素
a.maxCoeff();   # 所有元素中最大元素
a.trace();      # 迹,对角元素的和
# minCoeff和maxCoeff还可以返回结果元素的位置信息
int i, j;
a.minCoeff(&i, &j);

Array类

Array<typename Scalar,
      int RowsAtCompileTime,
      int ColsAtCompileTime>
# 常见类定义
typedef Array<float, Dynamic, 1> ArrayXf
typedef Array<float, 3, 1> Array3f
typedef Array<double, Dynamic, Dynamic> ArrayXXd
typedef Array<double, 3, 3> Array33d

ArrayXf a = ArrayXf::Random(5);
a.abs();    # 绝对值
a.sqrt();    # 平方根
a.min(a.abs().sqrt());  # 两个array相应元素的最小值

归约,迭代器,广播

  • 范数计算
    • squareNorm():L2范数,等价于计算vector自身点积
    • norm():返回`squareNorm的开方根
    • .lpNorm

      ():p范数,p可以取Infinity,表无穷范数

  • 布尔归约
    • all()=true: matrix或array中所有元素为true
    • any()=true: 到少有一个为true
    • count(): 返回true元素个数
// sample
ArrayXXf A(2, 2);
A << 1,2,3,4;
(A > 0).all();
(A > 0).any();
(A > 0).count();
  • 迭代器
// sample
Eigen::MatrixXf m(2,2);
m << 1,2,3,4;
MatrixXf::Index maxRow, maxCol;
float max = m.maxCoeff(&minRow, &minCol);
  • 部分归约
// sample
Eigen::MatrixXf mat(2,3);
mat << 1,2,3,
       4,5,6;
std::cout << mat.colwise().maxCoeff();
// output: 4, 5, 6
// mat.rowWise() the same as before
  • 广播,针对vector,沿行或列重复构建一个matrix。
// sample
Eigen::MatrixXf mat(2,3);
Eigen::VectorXf v(2);

mat << 1,2,3,4,5,6;
v << 0,1;
mat.colwise() += v;
// output: 1, 2, 3, 5, 6, 7

Map类

  • Map类用于利用数据的内在,并将其转为Eigen类型。
    定义:
Map<Matrix<typename Scalar, int RowAtCompileTime, int ColsAtCompileTime> >

通过Map来reshape矩阵的形状。

Eigen常用的操作

#include <Eigen/Dense>  
  
Matrix<double, 3, 3> A;               // Fixed rows and cols. Same as Matrix3d.  
Matrix<double, 3, Dynamic> B;         // Fixed rows, dynamic cols.  
Matrix<double, Dynamic, Dynamic> C;   // Full dynamic. Same as MatrixXd.  
Matrix<double, 3, 3, RowMajor> E;     // Row major; default is column-major.  
Matrix3f P, Q, R;                     // 3x3 float matrix.  
Vector3f x, y, z;                     // 3x1 float matrix.  
RowVector3f a, b, c;                  // 1x3 float matrix.  
VectorXd v;                           // Dynamic column vector of doubles  
double s;                              
Eigen 基础使用

[cpp] view plain copy
// Basic usage  
// Eigen          // Matlab           // comments  
x.size()          // length(x)        // vector size  
C.rows()          // size(C,1)        // number of rows  
C.cols()          // size(C,2)        // number of columns  
x(i)              // x(i+1)           // Matlab is 1-based  
C(i,j)            // C(i+1,j+1)       //  
  
A.resize(4, 4);   // Runtime error if assertions are on.  
B.resize(4, 9);   // Runtime error if assertions are on.  
A.resize(3, 3);   // Ok; size didn't change.  
B.resize(3, 9);   // Ok; only dynamic cols changed.  
                    
A << 1, 2, 3,     // Initialize A. The elements can also be  
     4, 5, 6,     // matrices, which are stacked along cols  
     7, 8, 9;     // and then the rows are stacked.  
B << A, A, A;     // B is three horizontally stacked A's.  
A.fill(10);       // Fill A with all 10's.  
Eigen 特殊矩阵生成

[cpp] view plain copy
// Eigen                            // Matlab  
MatrixXd::Identity(rows,cols)       // eye(rows,cols)  
C.setIdentity(rows,cols)            // C = eye(rows,cols)  
MatrixXd::Zero(rows,cols)           // zeros(rows,cols)  
C.setZero(rows,cols)                // C = ones(rows,cols)  
MatrixXd::Ones(rows,cols)           // ones(rows,cols)  
C.setOnes(rows,cols)                // C = ones(rows,cols)  
MatrixXd::Random(rows,cols)         // rand(rows,cols)*2-1        // MatrixXd::Random returns uniform random numbers in (-1, 1).  
C.setRandom(rows,cols)              // C = rand(rows,cols)*2-1  
VectorXd::LinSpaced(size,low,high)   // linspace(low,high,size)'  
v.setLinSpaced(size,low,high)        // v = linspace(low,high,size)'  
Eigen 矩阵分块

[cpp] view plain copy
// Matrix slicing and blocks. All expressions listed here are read/write.  
// Templated size versions are faster. Note that Matlab is 1-based (a size N  
// vector is x(1)...x(N)).  
// Eigen                           // Matlab  
x.head(n)                          // x(1:n)  
x.head<n>()                        // x(1:n)  
x.tail(n)                          // x(end - n + 1: end)  
x.tail<n>()                        // x(end - n + 1: end)  
x.segment(i, n)                    // x(i+1 : i+n)  
x.segment<n>(i)                    // x(i+1 : i+n)  
P.block(i, j, rows, cols)          // P(i+1 : i+rows, j+1 : j+cols)  
P.block<rows, cols>(i, j)          // P(i+1 : i+rows, j+1 : j+cols)  
P.row(i)                           // P(i+1, :)  
P.col(j)                           // P(:, j+1)  
P.leftCols<cols>()                 // P(:, 1:cols)  
P.leftCols(cols)                   // P(:, 1:cols)  
P.middleCols<cols>(j)              // P(:, j+1:j+cols)  
P.middleCols(j, cols)              // P(:, j+1:j+cols)  
P.rightCols<cols>()                // P(:, end-cols+1:end)  
P.rightCols(cols)                  // P(:, end-cols+1:end)  
P.topRows<rows>()                  // P(1:rows, :)  
P.topRows(rows)                    // P(1:rows, :)  
P.middleRows<rows>(i)              // P(i+1:i+rows, :)  
P.middleRows(i, rows)              // P(i+1:i+rows, :)  
P.bottomRows<rows>()               // P(end-rows+1:end, :)  
P.bottomRows(rows)                 // P(end-rows+1:end, :)  
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)  
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)  
Eigen 矩阵元素交换

[cpp] view plain copy
// Of particular note is Eigen's swap function which is highly optimized.  
// Eigen                           // Matlab  
R.row(i) = P.col(j);               // R(i, :) = P(:, i)  
R.col(j1).swap(mat1.col(j2));      // R(:, [j1 j2]) = R(:, [j2, j1])  
Eigen 矩阵转置

[cpp] view plain copy
// Views, transpose, etc; all read-write except for .adjoint().  
// Eigen                           // Matlab  
R.adjoint()                        // R'  
R.transpose()                      // R.' or conj(R')  
R.diagonal()                       // diag(R)  
x.asDiagonal()                     // diag(x)  
R.transpose().colwise().reverse(); // rot90(R)  
R.conjugate()                      // conj(R)  
Eigen 矩阵乘积

[cpp] view plain copy
// All the same as Matlab, but matlab doesn't have *= style operators.  
// Matrix-vector.  Matrix-matrix.   Matrix-scalar.  
y  = M*x;          R  = P*Q;        R  = P*s;  
a  = b*M;          R  = P - Q;      R  = s*P;  
a *= M;            R  = P + Q;      R  = P/s;  
                   R *= Q;          R  = s*P;  
                   R += Q;          R *= s;  
                   R -= Q;          R /= s;  
Eigen 矩阵单个元素操作

[cpp] view plain copy
// Vectorized operations on each element independently  
// Eigen                  // Matlab  
R = P.cwiseProduct(Q);    // R = P .* Q  
R = P.array() * s.array();// R = P .* s  
R = P.cwiseQuotient(Q);   // R = P ./ Q  
R = P.array() / Q.array();// R = P ./ Q  
R = P.array() + s.array();// R = P + s  
R = P.array() - s.array();// R = P - s  
R.array() += s;           // R = R + s  
R.array() -= s;           // R = R - 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.array().max(P.array())  // max(R, P)  
R.cwiseMin(P)             // min(R, P)  
R.array().min(P.array())  // min(R, P)  
R.cwiseAbs()              // abs(P)  
R.array().abs()           // abs(P)  
R.cwiseAbs2()             // abs(P.^2)  
R.array().abs2()          // abs(P.^2)  
(R.array() < s).select(P,Q);  // (R < s ? P : Q)  
Eigen 矩阵化简

[cpp] view plain copy
// Reductions.  
int r, c;  
// Eigen                  // Matlab  
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)  
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)  
Eigen 矩阵点乘

[cpp] view plain copy
// Dot products, norms, etc.  
// Eigen                  // Matlab  
x.norm()                  // norm(x).    Note that norm(R) doesn't work in Eigen.  
x.squaredNorm()           // dot(x, x)   Note the equivalence is not true for complex  
x.dot(y)                  // dot(x, y)  
x.cross(y)                // cross(x, y) Requires #include <Eigen/Geometry>  
Eigen 矩阵类型转换

[cpp] view plain copy
 Type conversion  
// 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)  
// if the original type equals destination type, no work is done  
[cpp] view plain copy
// Note that for most operations Eigen requires all operands to have the same type:  
MatrixXf F = MatrixXf::Zero(3,3);  
A += F;                // illegal in Eigen. In Matlab A = A+F is allowed  
A += F.cast<double>(); // F converted to double and then added (generally, conversion happens on-the-fly)  
  
// Eigen can map existing memory into Eigen matrices.  
float array[3];  
Vector3f::Map(array).fill(10);            // create a temporary Map over array and sets entries to 10  
int data[4] = {1, 2, 3, 4};  
Matrix2i mat2x2(data);                    // copies data into mat2x2  
Matrix2i::Map(data) = 2*mat2x2;           // overwrite elements of data with 2*mat2x2  
MatrixXi::Map(data, 2, 2) += mat2x2;      // adds mat2x2 to elements of data (alternative syntax if size is not know at compile time)  
Eigen 求解线性方程组 Ax = b

[cpp] view plain copy
// Solve Ax = b. Result stored in x. Matlab: x = A \ b.  
x = A.ldlt().solve(b));  // A sym. p.s.d.    #include <Eigen/Cholesky>  
x = A.llt() .solve(b));  // A sym. p.d.      #include <Eigen/Cholesky>  
x = A.lu()  .solve(b));  // Stable and fast. #include <Eigen/LU>  
x = A.qr()  .solve(b));  // No pivoting.     #include <Eigen/QR>  
x = A.svd() .solve(b));  // Stable, slowest. #include <Eigen/SVD>  
// .ldlt() -> .matrixL() and .matrixD()  
// .llt()  -> .matrixL()  
// .lu()   -> .matrixL() and .matrixU()  
// .qr()   -> .matrixQ() and .matrixR()  
// .svd()  -> .matrixU(), .singularValues(), and .matrixV()  
Eigen 矩阵特征值

[cpp] view plain copy
// Eigenvalue problems  
// Eigen                          // Matlab  
A.eigenvalues();                  // eig(A);  
EigenSolver<Matrix3d> eig(A);     // [vec val] = eig(A)  
eig.eigenvalues();                // diag(val)  
eig.eigenvectors();               // vec  
// For self-adjoint matrices use SelfAdjointEigenSolver<> 

matlab实现队列

classdef myQueue <handle  
properties (Access = public)%private
    buffer      % a cell, to maintain the data
    beg         % the start position of the queue
    rear        % the end position of the queue
                % the actually data is buffer(beg:rear-1)
end
 
properties (Access = public)
    capacity    
end
 
methods
    function obj = myQueue(c) 
        if nargin >= 1 && iscell(c)
            obj.buffer = [c(:); cell(numel(c), 1)];% numel - Number of array elements
            obj.beg = 1;
            obj.rear = numel(c) + 1;
            obj.capacity = 2*numel(c);
        elseif nargin >= 1
            obj.buffer = cell(100, 1);
            obj.buffer{1} = c;
            obj.beg = 1;
            obj.rear = 2;
            obj.capacity = 100;                
        else
            obj.buffer = cell(100, 1);
            obj.capacity = 100;
            obj.beg = 1;
            obj.rear = 1;
        end
    end
 
    function s = size(obj) 
        if obj.rear >= obj.beg
            s = obj.rear - obj.beg;
        else
            s = obj.rear - obj.beg + obj.capacity;
        end
    end
 
    function b = isempty(obj)   % return true when the queue is empty
        b = ~logical(obj.size());
    end
 
    function s = empty(obj) % clear all the data in the queue
        s = obj.size();
        obj.beg = 1;
        obj.rear = 1;
    end
 
    function push(obj, el)
        if obj.size >= obj.capacity - 1
            sz = obj.size();
            if obj.rear >= obj.beg 
                obj.buffer(1:sz) = obj.buffer(obj.beg:obj.rear-1);                    
            else
                obj.buffer(1:sz) = obj.buffer([obj.beg:obj.capacity 1:obj.rear-1]);
            end
            obj.buffer(sz+1:obj.capacity*2) = cell(obj.capacity*2-sz, 1);
            obj.capacity = numel(obj.buffer);
            obj.beg = 1;
            obj.rear = sz+1;
        end
        obj.buffer{obj.rear} = el;
        obj.rear = mod(obj.rear, obj.capacity) + 1;
    end
 
    function el = front(obj) 
        if obj.rear ~= obj.beg
            el = obj.buffer{obj.beg};
        else
            el = [];
            warning('CQueue:NO_DATA', 'try to get data from an empty queue');
        end
    end
 
    function el = back(obj)         
 
       if obj.rear == obj.beg
           el = [];
           warning('CQueue:NO_DATA', 'try to get data from an empty queue');
       else
           if obj.rear == 1
               el = obj.buffer{obj.capacity};
           else
               el = obj.buffer{obj.rear - 1};
           end
        end
 
    end
 
    function el = pop(obj) 
        if obj.rear == obj.beg
            error('CQueue:NO_Data', 'Trying to pop an empty queue');
        else
            el = obj.buffer{obj.beg};
            obj.beg = obj.beg + 1;
            if obj.beg > obj.capacity, obj.beg = 1; end
        end             
    end
 
    function remove(obj) 
        obj.beg = 1;
        obj.rear = 1;
    end
 
    function display(obj)
        if obj.size()
            if obj.beg <= obj.rear 
                for i = obj.beg : obj.rear-1
                    disp([num2str(i - obj.beg + 1) '-th element of the stack:']);
                    disp(obj.buffer{i});
                end
            else
                for i = obj.beg : obj.capacity
                    disp([num2str(i - obj.beg + 1) '-th element of the stack:']);
                    disp(obj.buffer{i});
                end     
                for i = 1 : obj.rear-1
                    disp([num2str(i + obj.capacity - obj.beg + 1) '-th element of the stack:']);
                    disp(obj.buffer{i});
                end
            end
        else
            disp('The queue is empty');
        end
    end
 
    function c = content(obj) 
        if obj.rear >= obj.beg
            c = obj.buffer(obj.beg:obj.rear-1);                    
        else
            c = obj.buffer([obj.beg:obj.capacity 1:obj.rear-1]);
        end
    end
end
end

矩阵的赋值和输出

矩阵的赋值和输出
Eigen::Matrix2d m_matrix;
m_matrix<< 2,3,2.2,1;
std::cout << "m_matrix = \n"<< m_matrix<std::endl;
Eigen::MatrixXd xx(5,2);
xx << 2,3,2.2,1,2,3,2,1,2,3;
特殊矩阵之零矩阵
Eigen::MatrixXf m_matrix = Eigen::MatrixXf::Zero(5,5);
Eigen::MatrixXf m_matrix = Eigen::MatrixXf::Zero(5,2);
特殊矩阵之对角矩阵
Eigen::MatrixXf m_matrix = Eigen::MatrixXf::Identity(5,5);
Eigen::MatrixXf m_matrix = Eigen::MatrixXf::Identity(2,5);

矩阵大小

int cols = m_matrix.cols();
int rows = m_matrix.rows();
std::cout<<cols<<std::endl;
std::cout<<rows<<std::endl;

矩阵元素操作

矩阵里的每个元素求绝对值eigen中矩阵是无法直接对矩阵操作,让每个元素都求绝对值的。但是可以通过转化为Array类型来操作。

m_matrix(1,1) = 2;
m_matrix = A * B;
A = B; 
矩阵的最大元素和绝对值
    matrix转为array: .array()
    array转为matrix:.matrix()
    求绝对值
Eigen::MatrixXf x;
Eigen::ArrayXXf x_abs = x.array().abs();
求矩阵绝对值后的最大元素
Eigen::MatrixXf x;
Eigen::ArrayXXf x_abs = x.array().abs();
float max_value = x_abs.maxCoeff();

矩阵转置和矩阵求逆

转置
Eigen::MatrixXf m_matrix;
Eigen::MatrixXf m_matrix_T;
m_matrix_T = m_matrix.transpose();
求逆
Eigen::MatrixXf m_matrix;
Eigen::MatrixXf m_matrix_inv;
m_matrix_inv = m_matrix.inverse();

特征值和特征向量

特征值
Eigen::Matrix2d m_matrix;
m_matrix << 2,3,2.2,1;
Eigen::EigenSolver<Eigen::Matrix2d> eigen_solver ( m_matrix );
Eigen::MatrixXd eig_value = eigen_solver.pseudoEigenvalueMatrix();
std::cout << "matrix values = \n" <<eig_value<<std::endl;
特征向量
Eigen::Matrix2d m_matrix;
m_matrix << 2,3,2.2,1;
Eigen::EigenSolver<Eigen::Matrix2d> eigen_solver ( m_matrix );
Eigen::MatrixXd eig_vector = eigen_solver.pseudoEigenvectors();
std::cout << "matrix vectors = \n" <<eig_vector<<std::endl;
std::cout << "matrix vectors(1,0) = \n" <<eig_vector(1,0)<<std::endl;

Eigen 矩阵定义


#include <Eigen/Dense>
 
Matrix<double, 3, 3> A;               // Fixed rows and cols. Same as Matrix3d.
Matrix<double, 3, Dynamic> B;         // Fixed rows, dynamic cols.
Matrix<double, Dynamic, Dynamic> C;   // Full dynamic. Same as MatrixXd.
Matrix<double, 3, 3, RowMajor> E;     // Row major; default is column-major.
Matrix3f P, Q, R;                     // 3x3 float matrix.
Vector3f x, y, z;                     // 3x1 float matrix.
RowVector3f a, b, c;                  // 1x3 float matrix.
VectorXd v;                           // Dynamic column vector of doubles
// Eigen          // Matlab           // comments
x.size()          // length(x)        // vector size
C.rows()          // size(C,1)        // number of rows
C.cols()          // size(C,2)        // number of columns
x(i)              // x(i+1)           // Matlab is 1-based
动态大小矩阵的定义
int rows,cols;//从其他地方获取的尺寸行列数
Eigen::MatrixXf tmp_mat;
tmp_mat=Eigen::Matrix<float,Dynamic,Dynamic>();
tmp_mat.resize(rows,cols);

Eigen 基础使用

// Basic usage
// Eigen        // Matlab           // comments
x.size()        // length(x)        // vector size
C.rows()        // size(C,1)        // number of rows
C.cols()        // size(C,2)        // number of columns
x(i)            // x(i+1)           // Matlab is 1-based
C(i, j)         // C(i+1,j+1)       //
 
A.resize(4, 4);   // Runtime error if assertions are on.
B.resize(4, 9);   // Runtime error if assertions are on.
A.resize(3, 3);   // Ok; size didn't change.
B.resize(3, 9);   // Ok; only dynamic cols changed.
                  
A << 1, 2, 3,     // Initialize A. The elements can also be
     4, 5, 6,     // matrices, which are stacked along cols
     7, 8, 9;     // and then the rows are stacked.
B << A, A, A;     // B is three horizontally stacked A's.
A.fill(10);       // Fill A with all 10's

Eigen 特殊矩阵生成

// Eigen                            // Matlab
MatrixXd::Identity(rows,cols)       // eye(rows,cols)
C.setIdentity(rows,cols)            // C = eye(rows,cols)
MatrixXd::Zero(rows,cols)           // zeros(rows,cols)
C.setZero(rows,cols)                // C = ones(rows,cols)
MatrixXd::Ones(rows,cols)           // ones(rows,cols)
C.setOnes(rows,cols)                // C = ones(rows,cols)
MatrixXd::Random(rows,cols)         // rand(rows,cols)*2-1        // MatrixXd::Random returns uniform random numbers in (-1, 1).
C.setRandom(rows,cols)              // C = rand(rows,cols)*2-1
VectorXd::LinSpaced(size,low,high)  // linspace(low,high,size)'
v.setLinSpaced(size,low,high)       // v = linspace(low,high,size)'
Eigen::MatrixXd test(10, 10);
test.setRandom();
test.diagonal() << 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; // 对角线元素确定,其他值随意的矩阵

Eigen 矩阵分块

// Matrix slicing and blocks. All expressions listed here are read/write.
// Templated size versions are faster. Note that Matlab is 1-based (a size N
// vector is x(1)...x(N)).
// Eigen                           // Matlab
x.head(n)                          // x(1:n)
x.head<n>()                        // x(1:n)
x.tail(n)                          // x(end - n + 1: end)
x.tail<n>()                        // x(end - n + 1: end)
x.segment(i, n)                    // x(i+1 : i+n)
x.segment<n>(i)                    // x(i+1 : i+n)
P.block(i, j, rows, cols)          // P(i+1 : i+rows, j+1 : j+cols)
P.block<rows, cols>(i, j)          // P(i+1 : i+rows, j+1 : j+cols)
P.row(i)                           // P(i+1, :)
P.col(j)                           // P(:, j+1)
P.leftCols<cols>()                 // P(:, 1:cols)
P.leftCols(cols)                   // P(:, 1:cols)
P.middleCols<cols>(j)              // P(:, j+1:j+cols)
P.middleCols(j, cols)              // P(:, j+1:j+cols)
P.rightCols<cols>()                // P(:, end-cols+1:end)
P.rightCols(cols)                  // P(:, end-cols+1:end)
P.topRows<rows>()                  // P(1:rows, :)
P.topRows(rows)                    // P(1:rows, :)
P.middleRows<rows>(i)              // P(i+1:i+rows, :)
P.middleRows(i, rows)              // P(i+1:i+rows, :)
P.bottomRows<rows>()               // P(end-rows+1:end, :)
P.bottomRows(rows)                 // P(end-rows+1:end, :)
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)
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)

Eigen 矩阵元素交换

// Of particular note is Eigen's swap function which is highly optimized.
// Eigen                           // Matlab
R.row(i) = P.col(j);               // R(i, :) = P(:, i)
R.col(j1).swap(mat1.col(j2));      // R(:, [j1 j2]) = R(:, [j2, j1])

Eigen 矩阵转置

// Views, transpose, etc; all read-write except for .adjoint().
// Eigen                           // Matlab
R.adjoint()                        // R'
R.transpose()                      // R.' or conj(R')
R.diagonal()                       // diag(R)
x.asDiagonal()                     // diag(x)
R.transpose().colwise().reverse(); // rot90(R)
R.conjugate()                      // conj(R)

Eigen 矩阵乘积

// All the same as Matlab, but matlab doesn't have *= style operators.
// Matrix-vector.  Matrix-matrix.   Matrix-scalar.
y  = M*x;          R  = P*Q;        R  = P*s;
a  = b*M;          R  = P - Q;      R  = s*P;
a *= M;            R  = P + Q;      R  = P/s;
                   R *= Q;          R  = s*P;
                   R += Q;          R *= s;
                   R -= Q;          R /= s;

Eigen 矩阵单个元素操作

// Vectorized operations on each element independently
// Eigen                  // Matlab
R = P.cwiseProduct(Q);    // R = P .* Q
R = P.array() * s.array();// R = P .* s
R = P.cwiseQuotient(Q);   // R = P ./ Q
R = P.array() / Q.array();// R = P ./ Q
R = P.array() + s.array();// R = P + s
R = P.array() - s.array();// R = P - s
R.array() += s;           // R = R + s
R.array() -= s;           // R = R - 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.array().max(P.array())  // max(R, P)
R.cwiseMin(P)             // min(R, P)
R.array().min(P.array())  // min(R, P)
R.cwiseAbs()              // abs(P)
R.array().abs()           // abs(P)
R.cwiseAbs2()             // abs(P.^2)
R.array().abs2()          // abs(P.^2)
(R.array() < s).select(P,Q);  // (R < s ? P : Q)

Eigen 矩阵化简

// Reductions.
int r, c;
// Eigen                  // Matlab
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)
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)

Eigen 矩阵点乘

// Dot products, norms, etc.
// Eigen                  // Matlab
x.norm()                  // norm(x).    Note that norm(R) doesn't work in Eigen.
x.squaredNorm()           // dot(x, x)   Note the equivalence is not true for complex
x.dot(y)                  // dot(x, y)
x.cross(y)                // cross(x, y) Requires #include <Eigen/Geometry>

Eigen 矩阵类型转换

 Type conversion
// 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)
// if the original type equals destination type, no work is done

Eigen 求解线性方程组 Ax = b

// Solve Ax = b. Result stored in x. Matlab: x = A \ b.
x = A.ldlt().solve(b));  // A sym. p.s.d.    #include <Eigen/Cholesky>
x = A.llt() .solve(b));  // A sym. p.d.      #include <Eigen/Cholesky>
x = A.lu()  .solve(b));  // Stable and fast. #include <Eigen/LU>
x = A.qr()  .solve(b));  // No pivoting.     #include <Eigen/QR>
x = A.svd() .solve(b));  // Stable, slowest. #include <Eigen/SVD>
// .ldlt() -> .matrixL() and .matrixD()
// .llt()  -> .matrixL()
// .lu()   -> .matrixL() and .matrixU()
// .qr()   -> .matrixQ() and .matrixR()
// .svd()  -> .matrixU(), .singularValues(), and .matrixV()

//非方阵的函数svd求解
 9     MatrixXf A = MatrixXf::Random(3,2);
10     cout<<"Here is the matrix A:\n"<<A<<endl;
11     VectorXf b = VectorXf::Random(3);
12     cout<<"Here is the right hand side b:\n"<<b<<endl;
13     cout<<"The least-squares solution is:\n"
14         <<A.bdcSvd(ComputeThinU|ComputeThinV).solve(b)<<endl;

最小二乘解的三种求解方式

svd求解

#include <iostream>
#include <Eigen/Dense>
 
using namespace std;
using namespace Eigen;
 
int main()
{
   MatrixXf A = MatrixXf::Random(3, 2);
   cout << "Here is the matrix A:\n" << A << endl;
   VectorXf b = VectorXf::Random(3);
   cout << "Here is the right hand side b:\n" << b << endl;
   cout << "The least-squares solution is:\n"
        << A.bdcSvd(ComputeThinU | ComputeThinV).solve(b) << endl;
}

QR分解
有3种QR分解类: There are three QR decomposition classes: HouseholderQR (no pivoting, so fast but unstable), ColPivHouseholderQR (column pivoting, thus a bit slower but more accurate) and FullPivHouseholderQR (full pivoting, so slowest and most stable).

#include <iostream>
#include <Eigen/Dense>
 
using namespace std;
using namespace Eigen;
 
int main()
{
    MatrixXf A = MatrixXf::Random(3, 2);
    VectorXf b = VectorXf::Random(3);
    cout << "The solution using the QR decomposition is:\n"
         << A.colPivHouseholderQr().solve(b) << endl;
}

使用normal equations
找到Ax = b的最小二乘解等效于求解法线方程 A T A x = A T b A^{^{T}}Ax = A^{T}b ATAx=ATb

#include <iostream>
#include <Eigen/Dense>
 
using namespace std;
using namespace Eigen;
 
int main()
{
    MatrixXf A = MatrixXf::Random(3, 2);
    VectorXf b = VectorXf::Random(3);
    cout << "The solution using normal equations is:\n"
         << (A.transpose() * A).ldlt().solve(A.transpose() * b) << endl;
}

Eigen 矩阵特征值

// Eigenvalue problems
// Eigen                          // Matlab
A.eigenvalues();                  // eig(A);
EigenSolver<Matrix3d> eig(A);     // [vec val] = eig(A)
eig.eigenvalues();                // diag(val)
eig.eigenvectors();               // vec

Eigen求解最大特征值和最大特征值对应的特征向量,同理最小

 Matrix<double, 4, 4>K= MatrixXd::Random(4,4);
    EigenSolverdouble, 4, 4>> es(K);
    MatrixXcd evecs = es.eigenvectors();//獲取矩陣特征向量4*4,這裏定義的MatrixXcd必須有c,表示獲得的是complex複數矩陣
    MatrixXcd evals = es.eigenvalues();//獲取矩陣特征值 4*1
    MatrixXd evalsReal;//注意這裏定義的MatrixXd裏沒有c
    evalsReal=evals.real();//獲取特征值實數部分
    MatrixXf::Index evalsMax;
    evalsReal.rowwise().sum().maxCoeff(&evalsMax);//得到最大特征值的位置
    Vector4d q;
    q << evecs.real()(0, evalsMax), evecs.real()(1, evalsMax), evecs.real()(2, evalsMax), evecs.real()(3, evalsMax);//得到對應特征向量

Eigen齐次坐标和非齐次坐标

Eigen::Vector3d vec{1,2,3};
vec_homo = vec.homogeneous; // 转化为齐次坐标
vec_hnorm = vec_homo.hnormalized; // 转回正常坐标
vec.normalize() 自身修改成归一化的坐标
vec.norm() 二范数
vec.normalized() 不修改自身的坐标,就是返回一个新的向量

Eigen求解矩阵近似逆

A v i = λ i v i , A [ v 1 , v 2 , ⋯ v n ] = [ v 1 , v 2 , ⋯ v n ] [ λ 1 λ 2 ⋯ λ n ] Av_i = \lambda_iv_i,A[v_1,v_2,\cdots v_n]=[v_1,v_2,\cdots v_n]\begin{equation} \begin{bmatrix} \lambda_1 & & & \\ & \lambda_2 & & \\ & & \cdots&\\ & & &\lambda_n \end{bmatrix} \end{equation} Avi=λivi,A[v1,v2,vn]=[v1,v2,vn] λ1λ2λn

A = [ v 1 , v 2 , ⋯ v n ] [ λ 1 λ 2 ⋯ λ n ] [ v 1 T v 2 T ⋮ v n T ] A = L T V L , A − 1 = L V − 1 L T A = \left[ \begin{array}{l} v_1,v_2,\cdots v_n\end{array}\right] \begin{bmatrix} \lambda_1 & & & \\ & \lambda_2 & & \\ & & \cdots&\\ & & &\lambda_n \end{bmatrix} \left[ \begin{array}{l} v_1^T \\ v_2^T \\ \vdots \\v_n^T\end{array} \right] \\A = L^TVL,A^{-1}=LV^{-1}L^T A=[v1,v2,vn] λ1λ2λn v1Tv2TvnT A=LTVL,A1=LV1LT
s a e s . e i g e n v e c t o r s ( ) = L = [ v 1 T v 2 T ⋮ v n T ] s a e s . e i g e n v e c t o r s ( ) . t r a n s p o s e ( ) = L T = [ v 1 , v 2 , ⋯ v n ] saes.eigenvectors()=L=\left[ \begin{array}{l} v_1^T \\ v_2^T \\ \vdots \\v_n^T\end{array} \right] \\ saes.eigenvectors().transpose()=L^T=\left[ \begin{array}{l} v_1,v_2,\cdots v_n\end{array}\right] saes.eigenvectors()=L= v1Tv2TvnT saes.eigenvectors().transpose()=LT=[v1,v2,vn]

对应到Eigen中的代码为:

//1.用于求解特征值和特征向量
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> saes(Amm);
//2.具体求解逆矩阵
Eigen::MatrixXd Amm_inv = saes.eigenvectors() * Eigen::VectorXd((saes.eigenvalues().array() > eps).select(saes.eigenvalues().array().inverse(), 0)).asDiagonal() * saes.eigenvectors().transpose();
// saes.eigenvectors() L
// Eigen::VectorXd((saes.eigenvalues().array() > eps).select(saes.eigenvalues().array().inverse(), 0)).asDiagonal() D^{-1}
// saes.eigenvectors().transpose() LT

Eigen分解信息矩阵边缘化后的信息矩阵A和边缘化后的b

Eigen中的基础的矩阵类模板使用

template <typename Derived>
nlohmann::json CreateEigenJson(Eigen::MatrixBase<Derived> const& matrix){
	std::vector<Derived> datas;
	...
}

Eigen库求解icp

  • 比如说两组轨迹进行icp
1.pts0
Eigen::Matrix<double,3,Eigen::Dynamic> pts0(3,size),pts1(3,size);
2.对齐
Eigen::Matrix4d T10 = Eigen::umeyame(pts0,pts1,false);

umeyama(const MatrixBase<Derived>& src, const MatrixBase<OtherDerived>& dst, bool with_scaling = true)

Eigen::MatrixBase类

  • 作用是输入任意的Eigen::Matrix,都可以用该类来表示
template <typename Derived>
json EigenMatrixTojson(Eigen::MatrixBase<Derived> const& matrix){
	。。。。
}

比如输入:Eigen::Vector3d 实际上Derived对应的是Vector3d,而不是double
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值