在Eigen库中,所有的矩阵(matrices)和向量(Vector)都是Matrix模板的具体类。Vectors只是matrices的一种特殊情况,表示仅有一列的矩阵。
Matrix模板有六个模板参数,一般我们只需要用到最前面的三个。这三个参数都有默认参数,现阶段暂时不必理会。这三个强制参数如下:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
对于一些常见的矩阵类型,我们还提供了便利的typedef。例如:Matrix4f是一个 4 × 4 4\times4 4×4的浮点型矩阵,其typedef如下:
typedef Matrix<float,4,4> Matrix4f;
便捷类型 | 举例 |
---|---|
MatrixNt for Matrix |
MatrixXi for Matrix |
VectorNt for Matrix |
Vector2f for Matrix |
RowVectorNt for Matrix |
RowVector3d for Matrix |
前面说道Vector是Matrix的一种特殊情况,所以Vector只是一些别名:
typedef Matrix<float, 3, 1> Vector3f;
typedef Matrix<int, 1, 2> RowVector2i;
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1> VectorXi;
默认构造函数将执行默认初始化:
Matrix3f a;
MatrixXf b;
这种方式是分配在栈上的,下面这个例子则是分配在堆上的:
MatrixXf a(10,15);//10*15未初始化的动态可扩展矩阵
VectorXf b(30);//30*1未初始化动态可扩展矩阵
为了保持编程的一致性,对于方阵Matrix3f,我们仍然可以使用下面这个方法进行初始化:
Matrix3f a(3,3);//虽然说,大小已经固定,但是为了逻辑一致性还是允许这样初始化
最后,对于向量这种类型,我们提供了一些额外的初始化方法:
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);
#include
#include
using namespace Eigen;
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 << "Here is the matrix m:\n" << m << std::endl;
VectorXd v(2);
v(0) = 4;//v0可以写成v(0,0),v1可写成v(0,1)
v(1) = v(0) - 1;
std::cout << "Here is the vector v:\n" << v << std::endl;
}
可以看出可以通过小括号加两个数字访问指定元素,对于向量则可以省略系数为1的那一个数字。
<<
实现赋值矩阵和向量的元素可以非常方便的使用comma-initailizer语法,一个简单的例子:
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
resize是针对于动态矩阵的,换句话说,你不能对Matrix3d对象进行resize操作。如果往小里resize,顺序不变;如果不变,那什么也不做;如果往大里resize,所有数据将会丢失。如果不想丢失,考虑conservativeResize
。
#include
#include
using namespace Eigen;
int main()
{
MatrixXd m(2,5);
m.resize(4,3);//m内存将会重置,原有内容将会丢失
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;
}
矩阵的操作 | 含义 |
---|---|
rows() | 行 |
cols() | 列 |
size() | 总个数 |
为什么MatrixXf叫做动态数据的原因是,它可以随着程序的运行resize其大小。
MatrixXf a(2,2);
std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;
MatrixXf b(3,3);
a = b;
std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;
简单来说,当矩阵较小时应该用fix-size;矩阵不得不或者较大时则使用dynamic-size。至于什么是小,大概就是16大小。
Matrix<typename Scalar,
int RowsAtCompileTime,
int ColsAtCompileTime,
int Options = 0,
int MaxRowsAtCompileTime = RowsAtCompileTime,
int MaxColsAtCompileTime = ColsAtCompileTime>
前面三个已经介绍过了,Option是一个选项,代表存储方式是列存储还是行存储;剩下的两个选项是指定最大行列值,如一个矩阵永远不能超过12,但是运行时又未知,那么使用这个选项就可以帮助你减少动态分配内存了。
https://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html#TutorialMatrixTypedefs