brief introduction
This article introduces the Matrix class in Eigen. In Eigen, the types of Matrix and vector are represented by Matrix. A vector is a special Matrix, which has only one row or one column.
Matrix structure
In Matrix.h, the Matrix class is defined,
The constructors include the following five. You can see that Vector is also defined by Matrix.
/** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */ EIGEN_DEVICE_FUNC explicit 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_FUNC Matrix(Index rows, Index cols); /** \brief Constructs an initialized 2D vector with given coefficients */ Matrix(const Scalar& x, const Scalar& y); //......
Simplify Matrix and Vector definitions
There are also some simplified class name definitions defined by macro, which are used to fix the square matrix of column or Row, and vectors. For example, Matrix3f, Matrix4i, Vector4f... Seen in some projects.
These macro s are as follows:
#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;
As defined above, there are:
// Define a floating-point 4X4 array type. typedef Matrix<float, 4, 4> Matrix4f; // Defines the column vector type for 3 rows of a floating-point type. typedef Matrix<float, 3, 1> Vector3f; // Defines a row vector type with an integer length of 2. typedef Matrix<int, 1, 2> RowVector2i;
Special value Dynamic
All of them are fixed size matrices or vectors. Eigen not only supports the Matrix matrix with dimensions specified at compile time, but also supports the use of a special value Dynamic to specify Rows or (and) Columns, indicating that the compile time size is unknown. At run time, it really deals with its size.
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> class Matrix : public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
Just like the fixed size Matrix above, it has a simplified definition form. The non fixed Matrix indicated by Dynamic also has a simplified definition form. Such as:
// Define a double Matrix whose number of rows and columns are unknown at compile time. typedef Matrix<double, Dynamic, Dynamic> MatrixXd; // A vector is defined, but its length is not known at compile time. typedef Matrix<int, Dynamic, 1> VectorXi;
Of course, you can know one of them by the number of rows or columns. As follows:
Matrix<float, 3, Dynamic> matrixA; Matrix<float, Dynamic, 4> matrixB;
Example
In the following example, use the constructor to define the Matrix
Use default constructor
At this time, memory allocation will not be performed and Matrix parameters will not be initialized. Only a Matrix variable is defined.
Matrix3f a; MatrixXf b;
Constructor specified size
At this point, if the size is specified, the memory space will be allocated, but the matrix or vector parameters will not be initialized.
MatrixXf a(8,15); VectorXf b(30);
According to Eigen, to unify the definition of fixed size or Dynamic Matrix, you can specify size values in constructor parameters, but these values may not be needed or useful. For example:
// Here rows =3 and columns = 3 on the constructor are not required Matrix3f a(3,3);
Constructor for specifying Matrix coefficients
For matrices with fewer coefficients, you can specify them at construction time. For example:
// Define a shape vector with a length of 2 Vector2i a(5, 6); // Define a vector of double type with length 3 Vector3d b(5.0, 6.0, 7.0); // Define a floating-point vector with a length of 4 Vector4f c(5.0, 6.0, 7.0, 8.0);
Coefficient access to Matrix
When using Matrix or Vector, be sure to have Coefficient coefficient. How do I operate / access these coefficients?
The Matrix class overloads the bracket operator (), which provides access to the coefficients. For a Matrix, the parameter is (row, column), while for a Vector, there is only one parameter, index. These parameters are integers starting with 0.
Be careful:
For matrix access, a single parameter is also allowed, but its operation is based on the matrix coefficient array. There is a problem of memory storage order. Eigen stores in Column based order, but you can change the setting to Row based order.
If there is active program matrix? 1.cpp:
#include <iostream> #include <Eigen/Dense> using namespace Eigen; int main() { // Define matrix 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 << "The matrix m:\n" << m << std::endl; std::cout << "The matrix m(1):\n" << m(1) << std::endl; // Define vector VectorXd v(2); v(0) = 4; v(1) = v(0) - 1; std::cout << "The vector v:\n" << v << std::endl; }
Compile:
$ g++ matrix_1.cpp -o matrix_1 -I /usr/local/include/eigen3 $
Output:
$ ls matrix_1 The matrix m: 3 -1 2.5 1.5 The matrix m(1): 2.5 The vector v: 4 3
Initialization: comma initialization
In Eigen, the syntax of comma initializer is used to initialize matrix and vector.
**Note: * * when using comma initializer to initialize matrix, row is the main order for input. This may not be in the same order as the access mentioned above.
Here is an example:
// matrix_2.cpp #include <iostream> #include <Eigen/Dense> using namespace Eigen; int main() { // Define matrix Matrix3f m; m << 1, 2, 3, 4, 5, 6, 7, 8, 9; std::cout << "The matrix m:\n" << m << std::endl; // Define vector VectorXd v(2); v<< 1,2; std::cout << "The vector v:\n" << v << std::endl; }
After compiling, you can see the result.
$ 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 and assignment
For access to row and column number of a matrix, matrix in Eigen provides row(), columns(), size() function.
Matrix<double, 4, 3> m; std::cout << "rows: " << m.rows() ; // rows: 4 std::cout << "columns: " << m.cols() << std::endl; // columns: 3 std::cout << "It has " << m.size() << " coefficients" << std::endl; // It has 12 coefficients
You can use resize(int rows,int columns) to change the size of a Matrix.
Matrix<double, 4, 3> m;
You can assign a Matrix/Vector variable to another corresponding variable, but there is no limit to their Size, such as:
Matrix4d md4; Matrix2f mf2; mf2 = md4; mf2.size();
resize & conservativeResize
Only Dynamic type matrices can be resized. When a fixed size matrix calls resize, there will also be errors during execution.
MatrixXf a(2,2); a.resize(5,5);
In resize() a matrix, you can imagine that its coefficient may change, so this function is destructive. The conserveresize() function is also provided in Eigen to protect its coefficients.
Compare the size effect of fixed and Dynamic on matrix
There is a question: should we use a fixed size matrix, or choose to use a non fixed Dynamic size matrix? Eigen's official answer to this question is: if your matrix size is very small, no more than 16, use fixed size, otherwise use floating unfixed size matrix. Matrix with fixed size has great advantages in performance. Because in the internal implementation, fixed size matrix simply uses Array to manage coefficients. Using Dynamic matrix will use Dynamic memory allocation, and there will be expansion bit calculation when coefficient access.
For example, matrix 4f mymatrix; is equivalent to float mymatrix[16];; matrix XF mymatrix (rows, columns); is equivalent to float *mymatrix = new float[rows*columns];.
Optional constructor parameters
Template class Matrix protects 6 parameters, and the last 3 parameters have default parameters, as follows:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options = 0, int MaxRowsAtCompileTime = RowsAtCompileTime, int MaxColsAtCompileTime = ColsAtCompileTime>
- Options parameter
This parameter uses some options identified by bit. Here is just the most important RowMajor, which identifies that the Matrix uses a row first policy to store coefficient data. By default, its value is 0, which is the column major policy. - MaxRowsAtCompileTime and MaxColsAtCompileTime
When you don't know the specific size of the matrix, but you know the maximum size of your size, use this parameter to specify the maximum value at compile time. If appropriate, Eigen creates a fixed size matrix to replace it.
Simplify Matrix class names
In the first article, we introduced the use of Macro to define some simplified Matrix types and class names.
- Matrix < type, N, n >. For example, matrix < int, dynamic, dynamic >
- Vectornt -- > matrix < type, N, 1 >. For example, Vector2f is matrix < float, 2, 1 >
- Rowvectornt -- > matrix < type, 1, n >. For example: RowVector3d is matrix < double, 1, 3 >
There
- N stands for quantity, which can be 1, 2, 3 , or X representing Dynamic with an unfixed size
- t represents the data type of coefficient, which can be i(int), f(float), d(double), cf(complex) cd(complex)