# Matrices, vectors, arrays and Linear Algebra: MRPT and Eigen classes

MRPT uses the powerful Eigen C++ library (version 3 of the API) for managing numerical matrices and vectors, so if you are familiar with Eigen, you already understand a large part of MRPT classes, interfaces and methods!

If you don’t know Eigen, these are good starting points:

The main difference with the standard Eigen API is that MRPT extends `Eigen::Matrix<>` with many new typedefs and methods that extend the number of operations readily available for any vector or matrix, and by the way, provides a smooth transition for code relying on the former non-Eigen MRPT matrix APIs.

You can check out the documentation for Eigen::MatrixBase, which contains both the original Eigen methods plus those provided by MRPT (look for the sections named “MRPT plugin: …”) via a plugin mechanism.

## 2. MRPT-specific classes

For new code, it’s probably a good idea to directly use Eigen::Matrix<> (or any Eigen typedef: MatrixXd, MatrixXf, etc.) instead of MRPT types, since the latter allare `Eigen::Matrix<>`instances (in the Object Programming sense of “being derived from”) with different template arguments, as summarized in this table:

 MRPT type Inherits from… Memory layout `mrpt::dynamicsize_vector < T >` Base class for: `mrpt::vector_float` `mrpt::vector_double` `Eigen::Matrix<>< T,Dynamic,1 >` Auto (→ ColMajor) `mrpt::math::CArrayNumeric < T,LEN >` `Eigen::Matrix<>< T,N,1 >` Auto (→ ColMajor) `mrpt::math::CMatrixTemplateNumeric < T >` With `typedef`‘s: `mrpt::math::CMatrixDouble` `mrpt::math::CMatrixFloat` And with derived classes capable of binary serialization: `mrpt::math::CMatrix`  (`float `elements) `mrpt::math::CMatrixD` (`double `elements) `Eigen::Matrix<>< T,Dynamic,Dynamic >` RowMajor `mrpt::math::CMatrixFixedNumeric < T, NROWS, NCOLS >` `Eigen::Matrix<>< T,NROWS, NCOLS >` ColMajor only if NCOLS=1, RowMajor otherwise. `mrpt::vector_signed_byte` `mrpt::vector_signed_word` `mrpt::vector_int` `mrpt::vector_long` `mrpt::vector_size_t` `mrpt::vector_byte` `mrpt::vector_word` `mrpt::vector_uint` These classes are not based on Eigen, but inherit from STL `std::vector<>` Elements contiguous in memory, as in any `std::vector<>` `mrpt::math::CArray` Not based on Eigen, designed to hold numeric or non-numeric elements. Elements contiguous in memory.

MRPT classes inherit from Eigen::Matrix, but there a few more differences, which are enumerated below.

## 3. Differences between MRPT matrix classes and Eigen classes

• Note in the table above that memory layout is significative since former MRPT classes all were RowMajor, while Eigen’s default is ColMajor. In general, users can’t notice the difference, except for some special situations, for example, the following code expect the matrix constructor to read the numbers from the array in RowMajor order (so “2” ends up in the first row, second column, etc.):
• MRPT matrices’ default constructors set all entries to zero, while in Eigen the default values are undefined. Both approaches are useful in different cases.
• Dumping an MRPT matrix to `std::cout` will append a final line feed, while with Eigen classes the cursor will remain at the end of the last printed line. So, these two print commands will produce exactly the same output:

## 4. Common errors (and their solutions!)

### 4.1. Alignment compile-time issues

Fixed-size vectorizable Eigen objects have special memory alignment requirements for efficiency. To refer to those classes plus any other class or struct that contains such matrices (at any depth down in the hierarchy!), I’ll use the name “problematic classes” (“problematic” standing for “needing special care for their alignment”).

There are plenty of affected classes in MRPT (`CMatrixFixedNumeric``CPose3D`, etc.), and there are good chances that your own classes are affected too, since just a single fixed-size matrix anywhere within a class marks it as “problematic”.

Normally the compiler handles the alignment requirements automatically, but there are some cases where it doesn’t, and you’ll find the following errors.

4.1.2. STL containers

If you have errors like:

around a STL container, then it means that you must use Eigen’s special aligned memory allocator for the container. This Eigen’s webpage explains this problem in detail.

But, in short these are the required changes:

Notice that MRPT provides mrpt::aligned_containers to ease the declaration of such STL containers.

4.1.3. The “parameter won’t be aligned” error:

If you have an error like:

and it wasn’t around an STL container, then you are trying to pass the “problematic” type as an argument by value. Read this page in Eigen’s website explaining the situation.

In short, the solution is to convert it to passing by reference:

### 4.2. Alignment run-time issues

If you find runtime errors like:

while accessing data members in a class that contains “problematic” types, and the instantiation of that class was created dynamically (with `new`), that is:

then, (first read the page cited in the error!) the problem will be most likely solved adding the `EIGEN_MAKE_ALIGNED_OPERATOR_NEW` macro to your class declaration:

When you create an instance of your class with `new CoolStuff(); `a custom memory allocator will be invoked that always returns aligned memory.

Important note: All MRPT classes inheriting from `mrpt::utils::CObject` already have this specialized new operators, so if your custom classes also inhirit from`CObject` or `CSerializable`, you don’t have to use that macro.

### 4.3. Mixing numeric types: explicit casting

In order to avoid unintended conversions from matrices/vectors of one type to the other (e.g. double <->float), which cost time, Eigen raises the following error at runtime:

if you try something as:

The solution is to use the cast() explicit converter, that is:

### 4.4. `resize()` vs. `setSize()`

Notice that `resize()` is a native Eigen method that doesn’t preserve the old contents of the matrix, while `setSize()` is an MRPT method that pads with zerosthe new elements and keep the old values unchanged.

Refer to the documentation of `Eigen::MatrixBase` (which includes the plugin methods from MRPT).

## 5. Issues porting MRPT code from ≤ 0.9.2

Apart from finding the build or runtime errors mentioned above (which apply to either new or old Eigen and MRPT-based code), there are some important points to keep in mind if your code intensively used old (non-Eigen) MRPT vectors and matrices:

### 5.1. Issues with `mrpt::vector_float` and `mrpt::vector_double`

The types mrpt::vector_float and std::vector<float> (or the `double` versions) are not interchangeable any more.

### 5.2. Matrices constructors from poses (`TPose2D`,…) are now explicit

Example: Previous code “CMatrixDouble31 m = myPose2D;” won’t build now, should be: “CMatrixDouble31 m = CMatrixDouble31(myPose2D);”

### 5.3. Iterators to matrix elements

Iterators to vectors and matrices, which were implemented with a uniform interface with former MRPT classes, are not available anymore, since they are not provided by Eigen. Read about their reasons in this thread.

### 5.4. `CVectorFloat` and `CVectorDouble`

The use of these types is discouraged in new code. They are now synonymous with `mrpt::vector_float` and `mrpt::vector_double`.

### 5.5. The matrix method `unit()`

The method `unit()`, which sets a matrix to an identity matrix, had an inconsistent signature between fixed and dynamic sized matrices. It’s now unified in Eigen::MatrixBase::unit(), although you can always directly invoke Eigen’s `setIdentity()`.