Eigen库的使用

目录

一、Dev c++安装eigen环境

二、Eigen库

1.Matrix类(Matrix<类型, 行, 列>):

 2.Vector类(向量)

3.初始化方式

1)通过括号进行赋值

 2)通过逗号初始化

4.矩阵的属性

1)行、列、大小可以通过rows()、cols()、size()获取

2)resize()

3)复制(操作符=)

5.矩阵的操作

1)矩阵的+、-、数×、乘法

2)点×和叉×

3)转置、共轭、伴随

4)所有元素的和,积,最大值,最小值,迹sum())、prod(),、maxCoeff()、minCoeff()、trace()

5)块操作

参考:


一、Dev c++安装eigen环境

  • 打开Dev c++编译器

  • 点击Tools-Package Manager

  • 点击左上角Install, 文件类型选择所有,选择压缩包

  • 弹出窗口后点击Install即可,安装完毕后的包即在菜单中显示

  • 点击Tools(工具)-compiler options(编译选项)-directories(目录)-C++ includes(C++包含文件)-右下角文件选项添加库地址

  •  添加头文件成功后,点击🆗

  •  新建source file,并保存

  •  测试
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
  MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
  std::cout << m << std::endl;
}

二、Eigen库

Eigen库被分为一个Core模块和其他一些模块,每个模块有一些相应的头文件。 为了便于引用,Dense模块整合了一系列模块;Eigen模块整合了所有模块。一般情况下,include<Eigen/Dense> 就够了。

1.Matrix类(Matrix<类型, 行, 列>):

所有矩阵或者向量都是Matrix这个模板类产生的对象。

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>

 其中: 

  • Scalar:表示元素的类型;
  • RowsAtCompileTime:矩阵的行;
  • ColsAtCompileTime:矩阵的列。
Matrix<typename Scalar,
       int RowsAtCompileTime,
       int ColsAtCompileTime,
       int Options = 0,
       int MaxRowsAtCompileTime = RowsAtCompileTime,
       int MaxColsAtCompileTime = ColsAtCompileTime>
  • Options:一个比特位,默认是按列存储,如果使用按行存储:
Matrix<float, 3, 3, RowMajor>
  • MaxRowsAtCompileTime和MaxColsAtCompileTime:表示在编译阶段矩阵的上限。主要是避免动态内存分配 
​Matrix<float, Dynamic, Dynamic, 0, 3, 4>

在库中,用typdef为我们定义了一些常用的矩阵,例如:

typedef Matrix<float, 4, 4> Matrix4f;

当然我们也可以自己设置,矩阵的行和列可以设置为固定的值也可以设置动态的(Dynamic),小的尺寸用固定的,大的尺寸用动态的,使用固定尺寸可以避免动态内存的开辟。 

typedef Matrix<double, Dynamic, Dynamic> MatrixXd;

默认的构造函数不执行任何空间分配,也不初始化矩阵的元素。

Matrix3f a;
MatrixXf b;

指定大小的矩阵,只是分配相应大小的空间,未初始化元素。

MatrixXf a(10,15);
VectorXf b(30);

为了对固定大小和动态大小的矩阵提供统一的API,对指定大小的Matrix传递sizes也是合法的(传递也被忽略)。

Matrix3f a(3,3);

可以用构造函数提供4以内尺寸的vector的初始化。

Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);

 2.Vector类(向量)

列向量:

typedef Matrix<float, 3, 1> Vector3f;

行向量:

typedef Matrix<int, 1, 2> RowVector2i

3.初始化方式

1)通过括号进行赋值

  • 矩阵索引赋值:
    MatrixXd m1(2,2);
    m1(0,0) = 3;
    m1(1,0) = 2.5;
    m1(0,1) = -1;
    m1(1,1) = m1(1,0) + m1(0,1);
  •  向量索引:
	Eigen::VectorXd v(2);
	v[0]=1;
	v[1]=2;

	Eigen::VectorXd v(2);
	v(0)=1;
	v(1)=2;

 注意:

  • 矩阵索引只能用(),因为C++操作符重载[]只能接收一个参数,而矩阵的行和列需要两个参数。
  • []可以用在向量的索引,因为向量的索引是一维的。

 2)通过逗号初始化

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

4.矩阵的属性

1)行、列、大小可以通过rows()、cols()、size()获取

	std::cout<<"行:"<<m.rows()<<std::endl;
	std::cout<<"列:"<<m.cols()<<std::endl;
	std::cout<<"大小:"<<m.size()<<std::endl; 

可以指定输出某行或列的数据。

OperationMethod
ith rowmatrix.row(i)
jth colummatrix.col(j)
std::cout<<"第一行: "<<std::endl<<m.row(0)<<std::endl;

2)resize()

    m.resize(2,3);
    cout<<m<<endl;
    cout<<"行: "<<m.cols()<<" 列: "<<m.rows()<<" 大小: "<<m.size()<<endl;

注意:

  • 只有行和列是动态参数的时候才可以使用,否则会报错,而且输入的时候编译器会检查;
  • 如果matrix的实际大小不改变,resize函数不做任何操作。resize操作会执行析构函数,元素的值会被改变,如果不想改变执行 conservativeResize()

3)复制(操作符=)

将一个矩阵复制到另外一个。Eigen会自动resize左变量大小等于右变量大小,比如:

#include<iostream>
#include<Eigen/Dense>
int main(){
	Eigen::MatrixXi m(2,3);
	std::cout<<"m'size: "<<m.rows()<<"x"<<m.cols()<<std::endl;
	Eigen::MatrixXi n(5,3);
	m=n;	
	std::cout<<"m'size: "<<m.rows()<<"x"<<m.cols()<<std::endl;
return 0; 
} 

 

5.矩阵的操作

1)矩阵的+、-、数×、乘法

左右两侧变量具有相同的尺寸(行和列),并且元素类型相同(Eigen不自动转化类型),其运算和int,float等基本类型相同。

  • 二元运算 + 如a+b
  • 二元运算 - 如a-b
  • 一元运算 - 如-a
  • 复合运算 += 如a+=b
  • 复合运算 -= 如a-=b

  • 二元运算 * 如matrix*scalar
  • 二元运算 * 如scalar*matrix
  • 二元运算 / 如matrix/scalar
  • 复合运算 *= 如matrix*=scalar
  • 复合运算 /= 如matrix/=scalar
#include<iostream>
#include<Eigen/Dense>
using namespace std;

int main()
{
	Eigen::Matrix2i m;
	m<<1,0,2,0;
	Eigen::Matrix<int,2,3> n;
	n(0,0)=1;
	n(0,1)=2;
	n(0,2)=3;
	
	n(1,0)=1;
	n(1,1)=2;
	n(1,2)=3;
	

	std::cout<<"m: "<<std::endl<<m<<std::endl;
	std::cout<<"n: "<<std::endl<<n<<std::endl;
	/*
	*乘法 
	*/
	Eigen::MatrixXi M;
	M=m*n;
	std::cout<<"M: "<<std::endl<<M<<std::endl;
	/*
	*加法 
	*/
	Eigen::MatrixXi N;
	N=M+n;
	std::cout<<"N: "<<std::endl<<N<<std::endl; 
	/*
	*数乘 
	*/
	Eigen::MatrixXi L;
	L=M*3;
	std::cout<<"L: "<<std::endl<<L<<std::endl; 
	
	return 0;
}

2)点×和叉×

  • 点乘:dot();
  • 叉乘:cross();
Eigen::Vector3d v(3,4,5);
Eigen::Vector3d w(0,2,3);
cout<<"dot: "<<v.dot(w)<<endl;
cout<<"cross: "<<std::endl<<v.cross(w)<<endl;

3)转置、共轭、伴随

  • img 表示transpose(转置)
  • img 表示conjugate(共轭)
  • img 表示adjoint(共轭转置/ 伴随矩阵)
/*
*转置、共轭、伴随 
*/
Eigen::MatrixXd a=Eigen::MatrixXd::Random(2,2); 
cout<<"a: "<<std::endl<<a<<endl;
cout<<"转置: "<<std::endl<<a.transpose()<<endl;
cout<<"共轭: "<<std::endl<<a.conjugate()<<endl;
cout<<"伴随: "<<std::endl<<a.adjoint()<<endl;

注意:

  •  transpose和adjoint会简单的返回一个代理对象并不对本身做转置。
  • 如果执行 b=a.transpose() ,a不变,转置结果被赋值给b。
  • 如果执行 a=a.transpose() Eigen在转置结束之前结果会开始写入a,所以a的最终结果不一定等于a的转置。
  • 对 a=a.transpose() 这种操作,如果要就地转置可以使用a.transposeInPlace();(别名问题
Matrix2i a; a << 1, 2, 3, 4;
cout << "Here is the matrix a:\n" << a << endl;
a = a.transpose(); // !!! do NOT do this !!!
cout << "and the result of the aliasing effect:\n" << a << endl;

Here is the matrix a:
1 2
3 4
and the result of the aliasing effect:
1 2
2 4

 4)所有元素的和,积,最大值,最小值,迹

  • 和:sum();
  • 积:prod();
  • 最大值:maxCoeff();
  • 最小值:minCoeff();
  • 迹:trace();
#include <Eigen/Core>
#include<Eigen/Dense>
#include<iostream>
using namespace std;
using namespace Eigen;
int main()
{
    Matrix2d m(2,2);
    m(0,0)=-1;
    m(0,1)=2;
    m(1,0)=3;
    m(1,1)=1;
    Vector2d v1(1,2),v2(2,3);


    cout<<m.sum()<<endl;
    cout<<m.prod()<<endl;
    cout<<m.trace()<<endl;
    cout<<m.minCoeff()<<endl;
}

同时,maxCoeff()minCoeff()可以换回最大值或者最小值的位置

int max=m.maxCoeff(&i,&j);

5)块操作

函数.block():

operation构建一个动态尺寸的block构建一个固定尺寸的block
起点(i,j)块大小(p,q).block(i,j,p,q).block< p,q >(i,j)

注意:

  • Eigen中的索引从0开始。
  • 两种方式都可以用于固定尺寸和动态尺寸的matrix/array,功能是等价的;
  • 区别:只是固定尺寸的版本在block较小时速度更快一些。
int main()
{
  Eigen::MatrixXf m(4,4);
  m <<  1, 2, 3, 4,
        5, 6, 7, 8,
        9,10,11,12,
       13,14,15,16;
  cout << "Block in the middle" << endl;
  cout << m.block<2,2>(1,1) << endl << endl;
  for (int i = 1; i <= 3; ++i)
  {
    cout << "Block of size " << i << "x" << i << endl;
    cout << m.block(0,0,i,i) << endl << endl;
  }
}
  •  矩阵的其他块。
operationdynamic-size blockfixed-size block
左上角p\*qmatrix.topLeftCorner(p,q);matrix.topLeftCorner< p,q >();
左下角p\*qmatrix.bottomLeftCorner(p,q);matrix.bottomLeftCorner< p,q >();
右上角p\*qmatrix.topRightCorner(p,q);matrix.topRightCorner< p,q >();
右下角p\*qmatrix.bottomRightCorner(p,q);matrix.bottomRightCorner< p,q >();
前q行matrix.topRows(q);matrix.topRows< q >();
后q行matrix.bottomRows(q);matrix.bottomRows< q >();
左p列matrix.leftCols(p);matrix.leftCols< p >();
右p列matrix.rightCols(p);matrix.rightCols< p >();

  •  vector的块
operationdynamic-size blockfixed-size block
前n个vector.head(n);vector.head< n >();
后n个vector.tail(n);vector.tail< n >();
i起始的n个元素vector.segment(i,n);vector.segment< n >(i);

参考:

Dev C++安装第三方库小教程(以配置Eigen为例)_YTS8885的博客-CSDN博客_devc++添加库文件

Eigen教程(3) - 侯凯 - 博客园

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火柴的初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值