概述
在Eigen库中,所有的矩阵(matrices)和向量(Vector)都是Matrix模板的具体类。Vectors只是matrices的一种特殊情况,表示仅有一列的矩阵。
一、Matrix 矩阵
Matrix模板有六个模板参数,一般我们只需要用到最前面的三个。这三个参数都有默认参数,现阶段暂时不必理会。这三个强制参数如下:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
- Scalar 是一个标量类型,换句话说就是系数类型。如果你想要操作的是浮点型,那就是float;如果操作的是整数,那就是int;
- RowsAtCompileTime和ColsAtCompileTime是编译阶段已经确定的行列大小;
对于一些常见的矩阵类型,我们还提供了便利的typedef。例如:Matrix4f是一个 4 × 4 4times4 4×4的浮点型矩阵,其typedef如下:
typedef Matrix<float,4,4> Matrix4f;
便捷类型 | 举例 |
---|---|
MatrixNt for Matrix<type, N, N> | MatrixXi for Matrix<int, Dynamic, Dynamic>. |
VectorNt for Matrix<type, N, 1> | Vector2f for Matrix<float, 2, 1>. |
RowVectorNt for Matrix<type, 1, N> | RowVector3d for Matrix<double, 1, 3>. |
二、Vector 向量
前面说道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);
五、访问系数(元素,coefficient)
#include <iostream>
#include <Eigen/Dense>
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;
七、重塑(Resizing)
resize是针对于动态矩阵的,换句话说,你不能对Matrix3d对象进行resize操作。如果往小里resize,顺序不变;如果不变,那什么也不做;如果往大里resize,所有数据将会丢失。如果不想丢失,考虑conservativeResize
。
#include <iostream>
#include <Eigen/Dense>
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
最后
以上就是孤独汽车为你收集整理的Eigen库学习(二)Matrix类的全部内容,希望文章能够帮你解决Eigen库学习(二)Matrix类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复