我是靠谱客的博主 孤独汽车,最近开发中收集的这篇文章主要介绍Eigen库学习(二)Matrix类,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在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类所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部