Eigen入门之密集矩阵 1 -- 类Matrix介绍
简介
本篇介绍Eigen中的Matrix类。在Eigen中,矩阵和向量的类型都用Matrix来表示。向量是一种特殊的矩阵,其只有一行或者一列。
Matrix构造
在Matrix.h
中,定义了Matrix类,
其中的构造器包括如下的5个,可以看到定义Vector也是使用Matrix。
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */EIGEN_DEVICE_FUNCexplicit Matrix(const Scalar *data);/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors** This is useful for dynamic-size vectors. For fixed-size vectors,* it is redundant to pass these parameters, so one should use the default constructor* Matrix() instead.* * \warning This constructor is disabled for fixed-size \c 1x1 matrices. For instance,* calling Matrix<double,1,1>(1) will call the initialization constructor: Matrix(const Scalar&).* For fixed-size \c 1x1 matrices it is therefore recommended to use the default* constructor Matrix() instead, especially when using one of the non standard* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).*/EIGEN_STRONG_INLINE explicit Matrix(Index dim);/** \brief Constructs an initialized 1x1 matrix with the given coefficient */Matrix(const Scalar& x);/** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.** This is useful for dynamic-size matrices. For fixed-size matrices,* it is redundant to pass these parameters, so one should use the default constructor* Matrix() instead.* * \warning This constructor is disabled for fixed-size \c 1x2 and \c 2x1 vectors. For instance,* calling Matrix2f(2,1) will call the initialization constructor: Matrix(const Scalar& x, const Scalar& y).* For fixed-size \c 1x2 or \c 2x1 vectors it is therefore recommended to use the default* constructor Matrix() instead, especially when using one of the non standard* \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).*/EIGEN_DEVICE_FUNCMatrix(Index rows, Index cols);/** \brief Constructs an initialized 2D vector with given coefficients */Matrix(const Scalar& x, const Scalar& y);//......
简化Matrix和Vector定义
还有使用macro
定义的一些简化类名定义,用于固定column 或者Row的方阵,以及向量。比如在一些项目中看到的 Matrix3f, Matrix4i, Vector4f……。
这些macro
如下:
#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \
/** \ingroup matrixtypedefs */ \
typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix; \
/** \ingroup matrixtypedefs */ \
typedef Matrix<Type, Size, 1> Vector##SizeSuffix##TypeSuffix; \
/** \ingroup matrixtypedefs */ \
typedef Matrix<Type, 1, Size> RowVector##SizeSuffix##TypeSuffix;#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \
/** \ingroup matrixtypedefs */ \
typedef Matrix<Type, Size, Dynamic> Matrix##Size##X##TypeSuffix; \
/** \ingroup matrixtypedefs */ \
typedef Matrix<Type, Dynamic, Size> Matrix##X##Size##TypeSuffix;
如上的定义,则有:
// 定义一个浮点型的4X4的方阵类型。
typedef Matrix<float, 4, 4> Matrix4f;// 定义一个浮点型的3行的列向量类型。
typedef Matrix<float, 3, 1> Vector3f;// 定义一个整形的长度为2的行向量类型。
typedef Matrix<int, 1, 2> RowVector2i;
特殊值 Dynamic
上面都是固定大小的矩阵或者向量。Eigen不仅支持在编译时指定了维度的矩阵Matrix,而且支持使用一个特殊值Dynamic
来指定Rows或(和)Columns,指示编译时大小并不知道。而在运行时,才会真正地处理其大小尺寸。
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Matrix: public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
就如上面固定大小的矩阵,有其简化定义形式。Dynamic指示的非固定的Matrix也有简化定义形式。如:
// 定义一个double型的,行数和列数均编译时未知的Matrix。
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;// 定义一个向量,但编译时还不知道其长度。
typedef Matrix<int, Dynamic, 1> VectorXi;
当然行数或者列数可以知道其中之一。如下:
Matrix<float, 3, Dynamic> matrixA;Matrix<float, Dynamic, 4> matrixB;
示例
如下示例,使用构造器定义一下Matrix
使用默认构造器
这时,不会执行内存分配,也不会初始化矩阵参数,仅定义了一个Matrix变量。
Matrix3f a;
MatrixXf b;
构造器指定大小尺寸
此时,指定了大小,将分配内存空间,但是并不初始化各个矩阵或者向量参数。
MatrixXf a(8,15);VectorXf b(30);
Eigen中提到,为统一固定大小或者Dynamic类型的Matrix的定义,可以在构造器参数中指定大小值,但这些值可能并不需要,也没有用处。比如:
// 这里构造器上的rows =3, columns = 3并不需要
Matrix3f a(3,3);
指定Matrix系数的构造器
对具有较少系数的Matrix,可以在构造时指定这些系数。比如:
// 定义具有长度为2的整形向量
Vector2i a(5, 6);// 定义具有长度为3的double型向量
Vector3d b(5.0, 6.0, 7.0);// 定义具有长度为4的浮点向量
Vector4f c(5.0, 6.0, 7.0, 8.0);
对Matrix的系数访问
在使用Matrix或者Vector时,一定要有系数Coefficient。如何操作/访问这些系数呢?
Matrix类重载了括号操作符()
,提供对系数的访问。针对矩阵,参数为(row, column)
,而针对Vector,则只有一个参数index了。这些参数都是以0作为起始的整数。
注意:
对矩阵访问,单个参数也是允许的,但其操作是按照矩阵的系数数组来进行操作的。而这会有个内存存储顺序的问题,Eigen按照Column为主的顺序进行存储,但可以更改设置,变为以Row为主序。
如有有源程序 matrix_1.cpp:
#include <iostream>
#include <Eigen/Dense>using namespace Eigen;int main()
{// 定义matrixMatrixXd 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 << "The matrix m:\n" << m << std::endl;std::cout << "The matrix m(1):\n" << m(1) << std::endl;// 定义vectorVectorXd v(2);v(0) = 4;v(1) = v(0) - 1;std::cout << "The vector v:\n" << v << std::endl;
}
编译:
$ g++ matrix_1.cpp -o matrix_1 -I /usr/local/include/eigen3
$
输出:
$ ls matrix_1
The matrix m:3 -1
2.5 1.5
The matrix m(1):
2.5
The vector v:
4
3
初始化: Comma_initializtion
在Eigen内,使用comma-initializer
的语法来进行matrix、vector的初始化。
**注意:**使用comma-initializer
来初始化matrix时,是以row为主序来进行输入的。这和上面提到的访问时的顺序可能不一致。
如下的示例:
// matrix_2.cpp
#include <iostream>
#include <Eigen/Dense>using namespace Eigen;int main()
{// 定义matrixMatrix3f m;m << 1, 2, 3,4, 5, 6,7, 8, 9;std::cout << "The matrix m:\n" << m << std::endl;// 定义vectorVectorXd v(2);v<< 1,2;std::cout << "The vector v:\n" << v << std::endl;
}
编译一下,执行后,可以看到结果。
$ g++ matrix_2.cpp -o matrix_2 -I /usr/local/include/eigen3
$ ./matrix_2
The matrix m:
1 2 3
4 5 6
7 8 9
The vector v:
1
2
size及赋值
对一个matrix的row,column数量的访问,Eigen中的Matrix提供了row(), columns(), size()
函数。
Matrix<double, 4, 3> m;
std::cout << "rows: " << m.rows() ; // rows: 4
std::cout << "columns: " << m.cols() << std::endl; // columns: 3std::cout << "It has " << m.size() << " coefficients" << std::endl; // It has 12 coefficients
对一个Matrix的大小可以使用resize(int rows,int columns)
来修改其大小。
Matrix<double, 4, 3> m;
可以把一个Matrix/Vector变量赋值给另一个对应的变量,而对他们的Size并没有限制,如:
Matrix4d md4;
Matrix2f mf2;mf2 = md4;
mf2.size();
resize & conservativeResize
只有Dynamic类型的Matrix可以改变大小。固定大小的matrix调用resize,执行时也会出错。
MatrixXf a(2,2);a.resize(5,5);
在resize()
一个matrix,可以想象,其系数可能会发生变化,所以此函数是有破坏性的。Eigen中还提供了conservativeResize()
函数,用于保护其系数。
对比 fixed、Dynamic对matrix的大小影响
有这样一个问题: 我们应该使用固定大小的matrix、还是选择使用不固定的Dynamic大小的matrix呢?Eigen官方对此问题的答案是: 如果你的matrix尺寸大小很小,不超过16,就使用固定尺寸的,否则使用浮动的不固定尺寸的matrix。固定大小尺寸的matrix有性能上的极大优势。因为在内部实现上,固定尺寸大小的matrix简单地使用了数组Array来管理系数。而使用Dynamic的matrix,会使用动态内存分配,而且存在系数访问时的展开位计算。
比如:Matrix4f mymatrix;
就相当于float mymatrix[16];
;而MatrixXf mymatrix(rows,columns);
相当于float *mymatrix = new float[rows*columns];
。
可选构造器参数
模板类Matrix,保护了6个参数,后3个参数具有缺省的参数,如下:
Matrix<typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime,int Options = 0,int MaxRowsAtCompileTime = RowsAtCompileTime,int MaxColsAtCompileTime = ColsAtCompileTime>
- Options参数
这个参数使用使用bit为标识的一些选项。这里只介绍一下最重要的RowMajor
,其标识Matrix使用行优先策略来存储系数数据。缺省下,其值为0,为列优先(column-major)策略。 - MaxRowsAtCompileTime 和 MaxColsAtCompileTime
在你不知道matrix具体大小时,但知道你大小的最大尺寸,使用此参数来指定编译时其最大值。如果合适,Eigen会创建固定尺寸大小的Matrix来替代。
简化Matrix类名
在第一篇中,介绍了使用Macro
定义了一些简化Matrix类型和类名。
- MatrixNt --> Matrix<type, N, N>. 比如: MatrixXi 即为 Matrix<int, Dynamic, Dynamic>.
- VectorNt --> Matrix<type, N, 1>. 比如: Vector2f 即为 Matrix<float, 2, 1>.
- RowVectorNt --> Matrix<type, 1, N>. 比如: RowVector3d 即为 Matrix<double, 1, 3>.
这里的
- N 表示数量,可以1,2,3……,或者代表Dynamic的不固定大小的X
- t 表示系数的数据类型,可以是 i(int), f(float), d(double), cf(complex) cd(complex)
Eigen入门之密集矩阵 1 -- 类Matrix介绍相关推荐
- Eigen入门之密集矩阵 7 - Map class:连接Eigen与C++的数据
简介 本文介绍一下Dense Matrix如何与c/C++的数组进行交互操作,这在引入其他的库中的vector向量和矩阵到Eigen中时要使用到的技术. 有时,你有一些定义好的数据,可能是数组,你需要 ...
- Eigen入门之密集矩阵 6 - Reductions, visitors and broadcasting
简介 本文介绍一下Dense Matrix的3中操作: reduction, visitor, broadcasting. 归约计算reduction. Eigen的归约计算是这样的一类计算,它是对矩 ...
- Eigen入门之密集矩阵 5 - 再谈Matrix初始化
简介 这里将讨论一下高级些的矩阵初始化方法. comma-initializer 逗号初始化器 comma-initializer方法很简单,可以一下把矩阵/向量的系数全部设置完.语法很简单,使用逗号 ...
- Eigen入门之密集矩阵 10 - 矩阵的行优先及列优先存储
简介 本篇介绍Eigen中矩阵及二维数组的系数存储顺序–行优先及列优先,已经如何指定优先顺序. 行优先(row-majoe). 列优先(column-majoe) 矩阵的系数条目组成了一个二维的结构, ...
- Eigen入门之密集矩阵 8 - resharp slicing切片
简介 Eigen还没有提供resharp或者slicing的处理函数,但是,可以使用Map 类来实现这些功能. 实现resharp 操作Resharp及修改Matrix的维度大小,而其系数保持不变.R ...
- Eigen入门之密集矩阵 3 - Array操作
简介 在Eigen内,有Matrix,vector进行线性代数的相关运算,但也需要执行对矩阵内的系数的相关操作时,这是正常的功能需求.Eigen中的Array类就是满足此需求的. Array 定义 和 ...
- Eigen入门之密集矩阵 2-- Matrix及Vector的计算方法
简介 Eigen内的Matrix和Vector提供了类似C++的运算符,如+,-,*:也提供了编程的函数方法,如点乘和叉乘的dot(), cross(),如此等等. 在Eigen的Matrix类,代表 ...
- Eigen入门之密集矩阵 9 - 别名混乱Aliasing
简介 别名混乱Aliasing是指在赋值表达式中,一个Eigen对象(矩阵.数组.向量)同时出现在左值和右值表达式中,比如v = v*2; m = m.transpose();; 别名混乱会引起错误, ...
- Eigen入门之密集矩阵 4 - 块操作
简介 Eigen 中Matrix/Array提供了.block()来进行block区块操作,这是面向系数提供的操作功能. 语法 Eigen中提供了2种语法,针对产生的结果是一致的.但存在性能上的不同, ...
最新文章
- Scrollview+ListView冲突解决
- 全国计算机一级wps网络,全国计算机一级《WPS》考试试题及答案
- Visual Studio 15 Preview 5 发布 大幅提升性能
- 文件读写的“二进制模式”和“文本模式”
- [HNOI2015] 亚瑟王
- 谷粒商城:07. pms_catelog.sql
- c#文件流读取编码问题(转)新增加一个方法解决不带BOM的问题
- 如何记才能不搞混绝对路径和相对路径
- 一个求整系数多项式的全部有理根的方法
- css半透明渐变过渡效果
- c语言获取ip地址,如何用C语言获得本机IP地址
- 基于USB数据采集卡(DAQ)与IO模块的热电偶温度采集
- Microsoft Visual Studio 2005中使用水晶报表详细说明
- 【基于Centos】驱动安装
- 注册Apple ID
- 第6章第6节:颜色搭配:配色万金油之色相配色方案 [PowerPoint精美幻灯片实战教程]
- 计算机组成原理之原码一位乘法过程
- 使用Git将本地文件提交到远程仓库
- 实用的vue插件大汇总
- long long整型
热门文章
- 最稳定的Nginx绿色环境,可无限自定义PHP和mysql版本、同时运行N个版本
- \Grokking Algorithms\简介与作者采访
- 20145240 《Java程序设计》第四次实验报告
- 教你怎么屏蔽掉在移动端的宽带运营商的流量劫持,屏蔽无耻的广告
- c#中去掉字符串空格方法
- 微信小程序前端支付代码
- WAP2.0开发规范及原则
- Android监听WIFI信号,这可能是Android上monitore Wifi信号强度的最佳方法
- linux u盘分区 mdev 卸载问题,嵌入式linux 实现mdev SD卡和U盘自动挂载和卸载的方法 mdev.conf...
- 支付宝异步回调返回success_深入解决异步编程Promise对象的学习