# Eigen

Very useful library for Transformations. First interacted through F1TENTH, getting better foundation through Visual SLAM project.

Eigen is a special library built with pure header files (this is the amazing part!). This means you can only locate its header files, not binary files like .so or .a. When you use it, you only need to import Eigenâs header file. You donât need to link the library file (because it doesnât have any library files). Now letâs write a piece of code below to actually practice the use of Eigen

Because the Eigen library only has header files, we donât need to link the program to the library with the target_link_libraries statement.

Resources

Fundamentally understanding how Eigen works

Installation

### CMake

In CMake:

Notice that we donât need `add_library`

nor `target_link_libraries`

. This is because Eigen only has header files (no `.cpp`

files), so we donât need to link the program. You can just run them in the include!!! ahh I see.

Eigen is ROW-major by default

This distinction is important to make once you get into the territory of storing large values in a particular dimension. Source

### Types of Matrices in Eigen

**Fixed-size matrices**: Dimensions determined at compile time. They allow for optimizations such as stack allocation and loop unrolling.

**Dynamic-size matrices**: Dimensions determined at runtime. These matrices offer flexibility, but with potential additional overhead due to heap allocation.

**Hybrid matrices**: One dimension is determined at compile time, the other at runtime. They offer a balance between the flexibility of dynamic-size matrices and the performance optimizations of fixed-size matrices.

Are Eigen matrices heap or stack allocated?

Found the answer in this stack overflow thread. Seems like dynamic-size matrices are always heap allocated. Fixed-size matrices are oftentimes stack allocated, but sometimes also heap allocated.

#### Matrices value types

`Matrix3`

- Matrix3
`d`

is a 3x3 of type`double`

(the`d`

stands for double) - Matrix3
`f`

is a 3x3 of type`float`

(the`f`

stands for float) - Matrix3
`i`

is a 3x3 of type`integer`

(the`i`

stands for integers)

You can apply the same logic for dynamic Matrices `MatrixX`

- MatrixX
`d`

is of type`double`

- MatrixX
`f`

is of type`float`

(the`f`

stands for float) - MatrixX
`i`

is of type`integer`

#### Vectors (theyâre just 1d matrices)

There also exists row vectors ($1Ăn$ instead of $nĂ1$)

- RowVector3d
- RowVectorXd

### Matrix Initialization

What is the preferred way to initialize Eigen matrices? Depends on what you need. Donât need to initialize matrix to 0 if you will overwrite it right after.

Rule of Thumb

As a general rule of thumb, if it is a dynamic matrix, you need the two extra arguments in front, which specify the dimensions of the matrix.

**Using Comma Initializer List**: Eigen provides a comma-initializer list feature to fill a matrix or vector with coefficients:

**Using Zero Method**: If you want to initialize a matrix to be filled with zeros:

**Using Constant Method**: To fill a matrix with a constant value:

**Using Identity Method**: To create an identity matrix:

**Using Random Method**: To fill a matrix with random values:

#### Const matrix

https://stackoverflow.com/questions/25999407/initialize-a-constant-eigen-matrix-in-a-header-file

There are at least two possibilities. The first one is using the comma initializer features of Eigen:

- This is row-wise

The second is using the Matrix3d(const double*) constructor which copies data from a raw pointer. In this case, the values must be provided in the same order than the storage order of the destination, so column-wise in most cases:

This is stored Column-Major!

This is because the default storage order is column first.

### More

Basic matrix operations

Make sure both matrices are of the SAME type!

In Eigen, for performance reasons, you must explicitly convert the matrix type. And if you forget to do this, Eigen will (not very friendly) prompt you with a very long âYOU MIXED DIFFERENT NUMERIC TYPES âŚâ compilation error.

Casting values

##### Solving

Solving things (covered in Visual SLAM book), I donât quite understand this yet. Okay I understand, itâs just solving $x$ for $Ax=b$

- There is a solution when $A$ is invertible, $x=A_{â1}b$

There are 3 ways to solve for x

- use the inverse (SLOW)

- QR Decomposition

- Cholesky decomposition (works for positive definite matrices)

#### CheatSheet

Taken from https://zhangboyi.gitlab.io/post/2018-06-28-eigen-cheat-sheet/

### Summary

- Rotation Matrix ( $3Ă3$ ):
`Eigen::Matrix3d`

- Rotation Vector ( $3Ă1$ ):
`Eigen::AngleAxisd`

- Euler Angle ( $3Ă1$ ):
`Eigen::Vector3d`

- Quaternion ( $4Ă1$ ):
`Eigen::Quaterniond`

- Euclidean Transformation ( $4Ă4$ ):
`Eigen::Isometry3d`

- Affine Transformation ( $4Ă4$ ):
`Eigen::Affine3d`

- Perspective Transformation ( $4Ă4$ ):
`Eigen::Projective3d`

### Common Issues

http://library.isr.ist.utl.pt/docs/roswiki/eigen(2f)Troubleshooting.html

When usingÂ fixed-size vectorizable Eigen typesÂ in STL containers, you must use an aligned allocator. Eigen provides one:

- umm, even this is not perfectly right?

http://library.isr.ist.utl.pt/docs/roswiki/eigen(2f)Troubleshooting.html