slam十四讲 02 Eigen实践

目录

前言

安装

Eigen使用示例


前言

Eigen是一个c++开源线性代数库,提供了快速的线性代数运算。许多上层软件库也是使用了Eigen进行矩阵运算。

教程可参考:Eigen: Matrix and vector arithmetichttp://eigen.tuxfamily.org/dox/group__TutorialMatrixArithmetic.html

安装

# 头文件的默认安装位置:/usr/include/eigen3/
sudo apt-get install libeigen3-dev

# 定位库安装的位置:
sudo updatedb
locate eigen3

Eigen库只有头文件,是一个纯用头文件搭建起来的库,没有.so或者.a二进制文件,所以在使用时,只需要引入Eigen头文件即可。

Eigen使用示例

c++代码

#include <iostream>
#include <ctime>
using namespace std;

// eigen
#include <eigen3/Eigen/Core>
// 稠密矩阵的代数运算
#include <eigen3/Eigen/Dense>
//#include <Eigen/Core>
//#include <Eigen/Dense>


#define MATRIX_SIZE 50

int main(int argc, char** argv)
{
    // eigen以矩阵为基本的数据单元。模板类。前三个参数:数据类型,行,列。
    Eigen::Matrix<float, 2, 3> matrix_23;
    
    // 同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是Eigen::Matrix
    // 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>,即三维向量
    Eigen::Vector3d v_3d;
    
    // 还有Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
    Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero();  // 初始化为0
    
    // 如果不确定矩阵大小,可以使用动态大小的矩阵
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> matrix_dynamic;
    
    // 更简单的
    Eigen::MatrixXd matrix_x;
    
    // 对矩阵的操作
    // 输入数据
    matrix_23 << 1, 2, 3, 4, 5, 6;
    // 输出
    cout << matrix_23 << endl;  // 2row,3col
    
    // 用()访问
    for (int i = 0; i < 1; i++)
        for (int j=0; j < 2; j++)
            cout << matrix_23(i, j) << endl;
        
    v_3d << 3, 2, 1;
    
    // 矩阵和向量相乘(实际上仍然矩阵和矩阵)
    // 但是在Eigen里你不能混合两种不同类型的矩阵,像这样是错的
    // Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
    // 应该显式转换,转成double,(2,3)*(3,1)->(2,1)
    Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
    cout << result << endl;
    
    // 同样你不能搞错矩阵的维度
    // 试着取消下面的注释,看看Eigen会报什么错
    // Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;
    
    // 矩阵运算
    // 四则运算就不演示了,直接用+-*/即可。
    matrix_33 =Eigen::Matrix3d::Random();
    cout << matrix_33 << endl;
    
    cout << matrix_33.transpose() << endl; // 转置
    cout << matrix_33.sum() << endl; //各元素求和
    cout << matrix_33.trace() << endl; //迹
    cout << matrix_33 * 10 << endl; // 数乘
    cout << matrix_33.inverse() << endl; // 逆
    cout << matrix_33.determinant() << endl;  // 行列式
    
    // 特征值
    // 实对称矩阵可以保证对角化成功(实对称矩阵:matrix_33.transpose()*matrix_33)
    Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver(matrix_33.transpose()*matrix_33);
    cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl;
    cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl;
    
    // 解方程
    // 我们求解 matrix_NN * x = v_Nd 这个方程.
    // N的大小在前边的宏里定义,它由随机数生成
    // 直接求逆自然是最直接的,但是求逆运算量大
    
    Eigen::Matrix<double, MATRIX_SIZE, MATRIX_SIZE> matrix_NN;  // 定义固定大小矩阵, (N, N)
    matrix_NN = Eigen::MatrixXd::Random(MATRIX_SIZE, MATRIX_SIZE);  // 赋值
    Eigen::Matrix<double, MATRIX_SIZE, 1> v_Nd;   // 定义固定大小向量, (N,1)
    v_Nd = Eigen::MatrixXd::Random(MATRIX_SIZE, 1);
    
    // 直接求逆  2.067ms
    clock_t time_st = clock();  
    Eigen::Matrix<double, MATRIX_SIZE, 1> x = matrix_NN.inverse() * v_Nd;  // (n,n) * (n,1) -> (n, 1)
    cout <<"time use in normal inverse is " << 1000*(clock()-time_st) / (double)CLOCKS_PER_SEC << "ms" << endl;
    
    // 通常用矩阵分解来求,例如QR分解,速度会快很多。 2.05ms
    time_st = clock();  
    x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
    cout <<"time use in Qr decomposition is " << 1000*(clock()-time_st) / (double)CLOCKS_PER_SEC << "ms" << endl;
    
    return 0;    
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(standard_ter)

# 添加头文件
include_directories("/usr/include/eigen3")

set(CMAKE_BUILD_TYPE "Debug")

add_executable(standard_ter main.cpp)

install(TARGETS standard_ter RUNTIME DESTINATION bin)

注:直接求逆和使用QR,时间相差不大,不知道原因是啥~

待续。。。

猜你喜欢

转载自blog.csdn.net/jizhidexiaoming/article/details/121606112
今日推荐