# Getting started with Eigen - Introduction to Matrix 2

## 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:

\$ ./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)
Published 106 original articles, won praise 108, visited 670000+

Added by Leveler on Tue, 18 Feb 2020 07:33:40 +0200