Eigen cheatsheet

The Matrix class矩阵类:在Eigen库中,所有的矩阵和向量都是Matrix类,向量是一个只有1行或者1列的特殊矩阵。
一、矩阵的定义
  Matrix类接收六个参数,但是前三个参数足够了。剩下的三个参数都有默认值,现在我们保持后面三个参数不变,只讨论前三个参数。

  Matrix<元素类型 float, int Rows, int Cols>
即:
  Matrix<元素类型 例如float型, int 行, int 列>
例如:
  定义一个3x3的float型的矩阵a:

Matrix<float,3,3> a;
1
二、向量的定义
  可以用typedefs来定义其他类型的矩阵,但是其本质还是Matrix类所定义的。
例如:
  typedef Matrix<float,3,1> Vector3f;
    定义的是列向量,3行1列的float型;
  typedef Matrix< int,1,2> RowVector2i;
    定义的是行向量,1行2列的int型

三、动态矩阵的设置
  在Eigen中的矩阵,可以不在编译时候就指定矩阵大小(row和col),可以使用Dynamic来动态指定矩阵大小。
例如:
  1.typedef Matrix< double,Dynamic,Dynamic> MatrixXd;
  MatrixXd可以用来定义一个大小未知的动态矩阵,元素类型为double型。

  2.typedef Matrix< int,Dynamic,1> VectorXi;
  VectorXi可以用来定义一个元素个数未知的动态向量,元素类型为int型。

  3.Matrix< float,3,Dynamic> a;
  定义一个行数为3,列数不定的动态矩阵a,元素为float型。

  4.
   Matrix3f a; a是一个3x3矩阵,元素为float型。
   MatrixXf b; b是一个动态的矩阵,大小是0x0。

四、构建矩阵和向量
  对于动态的矩阵\向量,直接指定的数值是其初始尺寸。

1
2
3
4
Matrix3f a;		  //a是一个3x3的矩阵,元素为float型
MatrixXf b; //b是一个动态矩阵,大小为0x0,元素为float型。
MatrixXf c(10, 15); //c是一个10x15的动态矩阵。
VectorXf d(30); //d是一个长度为30的动态列向量,元素为float型。

  对于固定的矩阵\向量,直接指定的数值是其初始值。

1
2
3
4
5
6
Vector2d e(5.0, 6.0);
//e是一个长度为2的向量,元素类型为double,元素值为5.0,6.0
Vector3d f(5.0, 6.0, 7.0);
//f是一个长度为3的向量,元素类型为double,元素值为5.0,6.0,7.0
Vector4d g(5.0, 6.0, 7.0, 8.0);
//g是一个长度为4的向量,元素类型为double,元素值为5.0,6.0,7.0,8.0

五、赋值
  矩阵\向量的赋值,直接按照其下标索引赋值即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXd m(2, 2);//2x2的矩阵,元素类型为double
m(0, 0) = 3;
m(1, 0) = 2.5;
m(0, 1) = -1;
m(1, 1) = m(1, 0) + m(0, 1);
cout << "Here is the matrix m:\n" << m << endl;
VectorXd v(2);//动态矩阵,2个元素的列向量
v(0) = 4;
v(1) = v(0) - 1;
cout << "Here is the vector v:\n" << v << endl;
system("pause");
return 0;
}

输出结果如下:

1
2
3
4
5
6
Here is the matrix m:
3 -1
2.5 1.5
Here is the vector v:
4
3

也可以用这种流式输入的方式赋值:

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

输出结果如下:

1
2
3
1 2 3
4 5 6
7 8 9

六、修改矩阵尺寸
  矩阵的尺寸大小可以通过rows(),cols()和size()来获取,分别返回行、列和元素数量。
  修改动态矩阵的大小要用resize()方法。

1
2
3
4
5
6
7
8
MatrixXd m(2, 5);//2x5的矩阵
m.resize(4, 3);//4x3的矩阵
cout << "The matrix m is of size:\n" << m.rows() << "x" << m.cols() << endl;
cout << "It has " << m.size() << " cofficients" << endl;
VectorXd v(2);//2个元素的列向量
v.resize(5);//5个元素的列向量
cout << "The vecotr v is of size:\n" << v.size() << endl;
cout << "As a matrix,v is of size:\n" << v.rows() << "x" << v.cols() << endl;

输出结果如下:

1
2
3
4
5
6
7
The matrix m is of size:
4x3
It's has 12 cofficients
The vecotr v is of size:
5
As a matrix,v is of size:
5x1

  当给动态矩阵赋值一个动态矩阵时,原先的动态矩阵的尺寸也会发生改变。

1
2
3
4
5
MatrixXf a(2, 2);
cout << "a is of size:\n" << a.rows() << "x" << a.cols() << endl;
MatrixXf b(3, 3);
a = b;
cout << "a is now of size:\n" << a.rows() << "x" << a.cols() << endl;

输出结果如下:

1
2
3
4
a is of size:
2x2
a is now of size:
3x3

1.矩阵实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

int test_current()
{
//矩阵赋值,方法一
MatrixXi m(2, 2);
m(0, 0) = 1;
m(1, 0) = 2;
m(0, 1) = 3;
m(1, 1) = m(0, 0) + m(0, 1);
cout <<"m矩阵:"<<endl << m << endl << endl;

//矩阵赋值,方法二
Matrix2i n; //2表示矩阵为2*2
n << 1,2,
3,4; //此处需要一次传入,不能分多次传入
cout << "n矩阵:" << endl << n << endl << endl;

//向量赋值
VectorXd v(2);
v(0) = 4;
v(1) = v(0) - 1;
cout << "v向量:\n" << v << endl << endl;

}

运行结果:

1
2
3
4
5
6
7
8
9
10
m矩阵:
1 3
2 4

n矩阵:
1 2
3 4
v向量:
4
3

这部分大家可以思考一下m和n矩阵的排列为何不同?Eigen中矩阵默认是列优先存储的,所以m输出是列优先的,而n是指定了如何输出,所以是按输入的形式输出的。

2.数组与矩阵转化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double *A = new double[6] {2, 4, 5, 8, 7, 3};
int *B = new int[6] {1, 5, 0, 7, 3, 9};
Map<Matrix<double, Dynamic, Dynamic, RowMajor>> aa(A, 2, 3); //通过数组获取矩阵实例
Map<Matrix<int, Dynamic, Dynamic, RowMajor>> bb(B, 3, 2);
MatrixXd cc = bb.cast<double>(); //不同数值类型矩阵相互转换,相同数据类型的矩阵之间才可以运算
cout << aa << endl << endl;
cout << cc << endl << endl;
Matrix<double, Dynamic, Dynamic, RowMajor> dd = aa*cc; //矩阵相乘,注意声明结果为行优先
cout << dd << endl << endl;
int rowCount = dd.rows(); //获取矩阵的行数
int colCount = dd.cols();
double* ff = dd.data(); //通过矩阵获取数组实例
for (int i = 0; i < rowCount*colCount; i++) {
cout << ff[i] << " ";
}
cout << endl;

注意图中注释部分,运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
2 4 5
8 7 3

1 5
0 7
3 9

17 83
17 116

17 83 17 116

3.Matrix对象的释放
Eigen中Matrix对象可以实现自动释放,不过会稍有延迟。同时也可以手动释放:

1
2
3
4
MatrixXd mA = MatrixXd::Random(10000, 10000); //构建一个随机矩阵
MatrixXd mB = mA; //通过查看内存可以看出矩阵赋值过程是内存拷贝的,不是引用传递
mA.resize(0, 0); //手动释放矩阵
mB.resize(0, 0);

4.支持的数据类型

Eigen::MatrixXd:定义一个大小未知的动态矩阵,元素类型为double型。

Eigen::Matrix3d

Eigen::Matrix3f:

Eigen::MatrixXf

Eigen::VectorXf

Eigen::VectorXi:定义一个元素个数未知的动态向量,元素类型为int型。

Eigen::MatrixXcd

References:

  1. Eigen库矩阵运算使用方法