eigen库的安装与基本使用教程

Eigen是可以用来进行线性代数、矩阵、向量操作等运算的C++库,它里面包含了很多算法。在用C++写运动控制算法(例如MPC控制算法)的时候,由于算法包括矩阵运算,c++对矩阵的运算支持不是很好,而Eigen(读作 ['aɪgən])是一个简单易用的用于矩阵运算的库。可以利用Eigen库进行运算,并且可以直接求解矩阵的逆、转置、伴随矩阵等,不需要利用数组进行计算了,比较方便快捷。

一.eigen库的安装与VS配置

1. Eigen库的安装
首先在官网下载Eigen库,库的官网下载地址
在这里插入图片描述
解压缩文件可以得到以下的文件
![](https://img-blog.csdnimg.cn/20200726204716546.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0x1X2ds,size_16,color_FFFFFF,t_70
2. VS 的附加依赖库的配置
由于Eigen都是由头文件组成的,所以包含相应的库路径即可。
在VS2017运行环境下,首先包含相应的库路径
**在项目上右键,找到属性,添加相应的库路径即可,注意我这里包含到路径到Eigen这个文件夹,所以在包含头文件时,#include <Dense即可,不需要写#include<Eigen/Dense>,如果没有的话需要包含到Eigen/Dense
在这里插入图片描述
在这里插入图片描述
如果是在ROS系统里面,在你的项目的CMakeLists中包含相应的库路径即可。

二.eigen库的简单使用

矩阵的定义:Eigen中关于矩阵类的模板函数中,共有六个模板参数,常用的只有前三个。其前三个参数分别表示矩阵元素的类型、行数和列数。
矩阵定义时可以使用Dynamic来表示矩阵的行列数为未知。
1.程序的声明
在添加了相应的路径之后,在程序开头写这几行即可使用了

#include <iostream>    
#include <Dense>   //或者是 #include "Eigen/Dense"
using Eigen::MatrixXd;
using namespace std;

声明一个矩阵:
矩阵类型:Eigen中的矩阵类型一般都是用类似MatrixXXX来表示,可以根据该名字来判断其数据类型,比如”d”表示double类型,”f”表示float类型,”i”表示整数,”c”表示复数;Matrix2f,表示的是一个2*2维的,其每个元素都是float类型。

MatrixXd P(3, 6);  //说明矩阵成员是double  类型的
MatrixXf s(3, 1);  //说明矩阵成员是float   类型的
MatrixXd v(6, 1);

第一行表示生成一个3行6列的矩阵

2.矩阵、向量的初始化
向矩阵输入数据,顺序输入即可(逗号初始化
动态矩阵和静态矩阵:动态矩阵是指其大小在运行时确定,静态矩阵是指其大小在编译时确定。
MatrixXd:表示任意大小的元素类型为double的矩阵变量,其大小只有在运行时被赋值之后才能知道。
Matrix3d:表示元素类型为double大小为3*3的矩阵变量,其大小在编译时就知道。
在Eigen中行优先的矩阵会在其名字中包含有row,否则就是列优先。Eigen中的向量只是一个特殊的矩阵,其维度为1而已。

Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;
std::cout << m;

输入常见矩阵
矩阵元素的访问:在矩阵的访问中,行索引总是作为第一个参数,Eigen中矩阵、数组、向量的下标都是从0开始。矩阵元素的访问可以通过”()”操作符完成。例如m(2, 3)既是获取矩阵m的第2行第3列元素。获取元素:通过中括号获取元素,对于矩阵是:(行,列);对于向量,只是传递它的索引,以0为起始。

#include<iostream>
#include<Eigen/Dense>
//matrix
int main1()
{
	Eigen::MatrixXd m(2, 2);
	m(0, 0) = 1;
	m(0, 1) = 2;
	m(1, 0) = 3;
	m(1, 1) = 4;
	std::cout << "m= " << std::endl << m << std::endl;
	return 0;
}

设置矩阵的元素:在Eigen中重载了”<<”操作符,通过该操作符即可以一个一个元素的进行赋值,也可以一块一块的赋值。另外也可以使用下标进行赋值。
重置矩阵大小:当前矩阵的行数、列数、大小可以通过rows()、cols()和size()来获取,对于动态矩阵可以通过resize()函数来动态修改矩阵的大小。注意:(1)、固定大小的矩阵是不能使用resize()来修改矩阵的大小;(2)、resize()函数会析构掉原来的数据,因此调用resize()函数之后将不能保证元素的值不改变;(3)、使用”=”操作符操作动态矩阵时,如果左右两边的矩阵大小不等,则左边的动态矩阵的大小会被修改为右边的大小。
如何选择动态矩阵和静态矩阵:对于小矩阵(一般大小小于16)使用固定大小的静态矩阵,它可以带来比较高的效率;对于大矩阵(一般大小大于32)建议使用动态矩阵。注意:如果特别大的矩阵使用了固定大小的静态矩阵则可能会造成栈溢出的问题。

int main
{
MatrixXf m1(3,4);   //动态矩阵,建立3行4列。
MatrixXf m2(3,3);
Vector3f v1;		//若是静态数组,则不用指定行或者列
/* 初始化 */
m1 = MatrixXf::Zero(3,4);		//用0矩阵初始化,要指定行列数
m2 = MatrixXf::Identity(3,3);	//用单位矩阵初始化
v1 = Vector3f::Zero();			//同理,若是静态的,不用指定行列数
 m1 << 1,0,0,1,      //也可以以这种方式初始化
        1,5,0,1,
        0,0,9,1;
    //向量初始化,与矩阵类似
    Vector3d v3(1,2,3);
    VectorXf vx(30);
}

列向量

typedef Matrix<float, 3, 1> Vector3f;

行向量

typedef Matrix<int, 1, 2> RowVector2i;

3.矩阵基础操作(加减乘除)
eigen重载了基础的+ - * / += -= = /= 可以表示标量和矩阵或者矩阵和矩阵

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
    //单个取值,单个赋值
    double value00 = staMat(0,0);
    double value10 = staMat(1,0);
    staMat(0,0) = 100;
    std::cout << value00 <<value10<<std::endl;
    std::cout <<staMat<<std::endl<<std::endl;
    //加减乘除示例 Matrix2d 等同于 Matrix<double,2,2>
    Matrix2d a;
     a << 1, 2,
     3, 4;
    MatrixXd b(2,2);
     b << 2, 3,
     1, 4;

    Matrix2d c = a + b; //矩阵的加法
    std::cout<< c<<std::endl;
    c = a - b;  //矩阵的减法
    std::cout<<c<<std::endl;
    c = a * 2;//矩阵的乘法
    std::cout<<c<<std::endl;
    c = 2.5 * a;//矩阵的乘法
    std::cout<<c<<std::endl;
    c = a / 2;//矩阵的除法
    std::cout<<c<<std::endl;
    c = a * b;//矩阵的乘法
    std::cout<<c<<std::endl;

4.C++数组和矩阵的转换
使用Map函数,可以实现Eigen的矩阵和c++中的数组直接转换,如下:

  int i;
    //数组转矩阵
    double *aMat = new double[20];
    for(i =0;i<20;i++)
    {
        aMat[i] = rand()%11;
    }
    //静态矩阵,编译时确定维数 Matrix<double,4,5> 
    Eigen:Map<Matrix<double,4,5> > staMat(aMat);


    //输出
    for (int i = 0; i < staMat.size(); i++)
        std::cout << *(staMat.data() + i) << " ";
    std::cout << std::endl << std::endl;


    //动态矩阵,运行时确定 MatrixXd
    Map<MatrixXd> dymMat(aMat,4,5);


    //输出,应该和上面一致
    for (int i = 0; i < dymMat.size(); i++)
        std::cout << *(dymMat.data() + i) << " ";
    std::cout << std::endl << std::endl;

    //Matrix中的数据存在一维数组中,默认是行优先的格式,即一行行的存
    //data()返回Matrix中的指针
    dymMat.data();

5.重置矩阵的大小,重新设置矩阵尺寸
重置矩阵大小:当前矩阵的行数、列数、大小可以通过rows()、cols()和size()来获取,对于动态矩阵可以通过resize()函数来动态修改矩阵的大小。注意:(1)、固定大小的矩阵是不能使用resize()来修改矩阵的大小;(2)、resize()函数会析构掉原来的数据,因此调用resize()函数之后将不能保证元素的值不改变;(3)、使用”=”操作符操作动态矩阵时,如果左右两边的矩阵大小不等,则左边的动态矩阵的大小会被修改为右边的大小。
matrix的大小可以通过rows()、cols()、size()获取,resize()可以重新调整动态matrix的大小

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
  MatrixXd m(2,5);
  m.resize(4,3);
  std::cout << "The matrix m is of size "
            << m.rows() << "x" << m.cols() << std::endl;
  std::cout << "It has " << m.size() << " coefficients" << std::endl;
  VectorXd v(2);
  v.resize(5);
  std::cout << "The vector v is of size " << v.size() << std::endl;
  std::cout << "As a matrix, v is of size "
            << v.rows() << "x" << v.cols() << std::endl;
}

对应的输出为:

The matrix m is of size 4x3
It has 12 coefficients
The vector v is of size 5
As a matrix, v is of size 5x1

6.矩阵的常用矩阵:转置、伴随、行列式、特征值等
小矩阵(4 * 4及以下)eigen会自动优化,默认采用LU分解,效率不高
转置、伴随、行列式、逆矩阵

#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
    Matrix2d c;
     c << 1, 2,
     3, 4;
    //转置、伴随
    std::cout<<c<<std::endl<<std::endl;
    std::cout<<"转置\n"<<c.transpose()<<std::endl<<std::endl;
    std::cout<<"伴随\n"<<c.adjoint()<<std::endl<<std::endl;
    //逆矩阵、行列式
    std::cout << "行列式: " << c.determinant() << std::endl;
    std::cout << "逆矩阵\n" << c.inverse() << std::endl;
}

计算特征值和特征向量

#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
    //特征向量、特征值
    std::cout << "Here is the matrix A:\n" << a << std::endl;
    SelfAdjointEigenSolver<Matrix2d> eigensolver(a);
    if (eigensolver.info() != Success) abort();
     std::cout << "特征值:\n" << eigensolver.eigenvalues() << std::endl;
     std::cout << "Here's a matrix whose columns are eigenvectors of A \n"
     << "corresponding to these eigenvalues:\n"
     << eigensolver.eigenvectors() << std::endl;
}

感谢下面博主的分享:
Eigen介绍及简单使用(基本的知识的了解)
有关eigen库的一些基本使用方法(基本的操作实例)
Eigen(3)矩阵Matrix及其简单操作

  • 5
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
众所周知,人工智能是当前最热门的话题之一, 计算机技术与互联网技术的快速发展更是将对人工智能的研究推向一个新的高潮。 人工智能是研究模拟和扩展人类智能的理论与方法及其应用的一门新兴技术科学。 作为人工智能核心研究领域之一的机器学习, 其研究动机是为了使计算机系统具有人的学习能力以实现人工智能。 那么, 什么是机器学习呢? 机器学习 (Machine Learning) 是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析的一门学科。 机器学习的用途 机器学习是一种通用的数据处理技术,其包含了大量的学习算法。不同的学习算法在不同的行业及应用中能够表现出不同的性能和优势。目前,机器学习已成功地应用于下列领域: 互联网领域----语音识别、搜索引擎、语言翻译、垃圾邮件过滤、自然语言处理等 生物领域----基因序列分析、DNA 序列预测、蛋白质结构预测等 自动化领域----人脸识别、无人驾驶技术、图像处理、信号处理等 金融领域----证券市场分析、信用卡欺诈检测等 医学领域----疾病鉴别/诊断、流行病爆发预测等 刑侦领域----潜在犯罪识别与预测、模拟人工智能侦探等 新闻领域----新闻推荐系统等 游戏领域----游戏战略规划等 从上述所列举的应用可知,机器学习正在成为各行各业都会经常使用到的分析工具,尤其是在各领域数据量爆炸的今天,各行业都希望通过数据处理与分析手段,得到数据中有价值的信息,以便明确客户的需求和指引企业的发展。
众所周知,人工智能是当前最热门的话题之一, 计算机技术与互联网技术的快速发展更是将对人工智能的研究推向一个新的高潮。 人工智能是研究模拟和扩展人类智能的理论与方法及其应用的一门新兴技术科学。 作为人工智能核心研究领域之一的机器学习, 其研究动机是为了使计算机系统具有人的学习能力以实现人工智能。 那么, 什么是机器学习呢? 机器学习 (Machine Learning) 是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析的一门学科。 机器学习的用途 机器学习是一种通用的数据处理技术,其包含了大量的学习算法。不同的学习算法在不同的行业及应用中能够表现出不同的性能和优势。目前,机器学习已成功地应用于下列领域: 互联网领域----语音识别、搜索引擎、语言翻译、垃圾邮件过滤、自然语言处理等 生物领域----基因序列分析、DNA 序列预测、蛋白质结构预测等 自动化领域----人脸识别、无人驾驶技术、图像处理、信号处理等 金融领域----证券市场分析、信用卡欺诈检测等 医学领域----疾病鉴别/诊断、流行病爆发预测等 刑侦领域----潜在犯罪识别与预测、模拟人工智能侦探等 新闻领域----新闻推荐系统等 游戏领域----游戏战略规划等 从上述所列举的应用可知,机器学习正在成为各行各业都会经常使用到的分析工具,尤其是在各领域数据量爆炸的今天,各行业都希望通过数据处理与分析手段,得到数据中有价值的信息,以便明确客户的需求和指引企业的发展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值