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 typedouble
(thed
stands for double) - Matrix3
f
is a 3x3 of typefloat
(thef
stands for float) - Matrix3
i
is a 3x3 of typeinteger
(thei
stands for integers)
You can apply the same logic for dynamic Matrices MatrixX
- MatrixX
d
is of typedouble
- MatrixX
f
is of typefloat
(thef
stands for float) - MatrixX
i
is of typeinteger
Vectors (theyâre just 1d matrices)
There also exists row vectors ( instead of )
- 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 for
- There is a solution when is invertible,
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 ( ):
Eigen::Matrix3d
- Rotation Vector ( ):
Eigen::AngleAxisd
- Euler Angle ( ):
Eigen::Vector3d
- Quaternion ( ):
Eigen::Quaterniond
- Euclidean Transformation ( ):
Eigen::Isometry3d
- Affine Transformation ( ):
Eigen::Affine3d
- Perspective Transformation ( ):
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