Eigen入门之密集矩阵 1 -- 类Matrix介绍
簡介
本篇介紹Eigen中的Matrix類。在Eigen中,矩陣和向量的類型都用Matrix來表示。向量是一種特殊的矩陣,其只有一行或者一列。
Matrix構造
在Matrix.h中,定義了Matrix類,
其中的構造器包括如下的5個,可以看到定義Vector也是使用Matrix。
簡化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為主序來進行輸入的。這和上面提到的訪問時的順序可能不一致。
如下的示例:
編譯一下,執行后,可以看到結果。
$ 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 2size及賦值
對一個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介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 双厨狂喜!一加官宣:与《原神》达成三年战
- 下一篇: 小米平板6系列最新爆料:120/144H