CODE: Eigen Library — High-Performance Linear Algebra for C++

Eigen is a powerful, header-only C++ library for linear algebra. It provides fast, reliable matrix and vector operations used in robotics, computer vision, scientific computing, and machine learning. Understanding how to set up and use Eigen is the foundation for any numerical computing work in C++.

Linear algebra is at the heart of a vast range of engineering and scientific computing tasks: robotics transformations, computer vision algorithms, machine learning models, finite element simulations, and signal processing. Eigen is the go-to C++ library for all of these, providing an expressive, template-based API with performance that rivals hand-optimized BLAS routines.


What Is Eigen?

Eigen is a header-only C++ template library for linear algebra. It provides:

  • Matrices (dense and sparse)
  • Vectors (fixed-size and dynamic)
  • Array types for coefficient-wise operations
  • Decompositions (LU, QR, SVD, Cholesky, Eigenvalues)
  • Geometry types (quaternions, affine transforms, rotations)

The key advantage of a header-only library is that there is nothing to compile separately — you simply point your compiler at the Eigen include directory and everything is available.

Eigen achieves high performance through:

  • Compile-time optimization: Sizes known at compile time enable maximum optimization
  • Expression templates: Avoid redundant temporaries through lazy evaluation
  • SIMD vectorization: Automatically uses SSE, AVX, NEON instructions
  • Cache efficiency: Memory access patterns optimized for modern CPUs

Downloading and Setting Up Eigen

Eigen is available from its official website: https://eigen.tuxfamily.org/

Since it is header-only, setup requires only pointing your compiler to the include directory:

bash
# Download and extract Eigen
wget https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
tar xzf eigen-3.4.0.tar.gz

Compile with Eigen:

bash
# Basic compilation
g++ -std=c++11 -I <path-to-eigen> my_program.cpp -o my_program

# Practical example with extracted directory
g++ -std=c++11 -I lib/eigen-3.4.0/ my_program.cpp -o my_program

CMake Integration

cmake
cmake_minimum_required(VERSION 3.14)
project(EigenDemo CXX)

# Option 1: System-installed Eigen
find_package(Eigen3 3.4 REQUIRED NO_MODULE)
target_link_libraries(my_program PRIVATE Eigen3::Eigen)

# Option 2: FetchContent (downloads Eigen automatically)
include(FetchContent)
FetchContent_Declare(
    eigen
    GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
    GIT_TAG        3.4.0)
FetchContent_MakeAvailable(eigen)
target_link_libraries(my_program PRIVATE Eigen3::Eigen)


Eigen Modules

Eigen is organized into modules. The two most commonly used header files provide access to groups of modules:

cpp
// Include only the dense matrix/vector module (most common)
#include <Eigen/Dense>

// Include everything including sparse matrices
#include <Eigen>

HeaderIncludes
<Eigen/Core>Matrix and Array classes, basic operations
<Eigen/Dense>Core, Geometry, LU, Cholesky, SVD, QR, Eigenvalues
<Eigen/Sparse>Sparse matrix types
<Eigen>Dense + Sparse (entire library)

For most applications, #include <Eigen/Dense> is sufficient.


Matrices in Eigen

Eigen provides two versions of matrix types:

Dynamic Matrices (size known at runtime)

cpp
#include <Eigen/Dense>
#include <iostream>

int main() {
    // Create a 2x3 dynamic matrix of doubles
    Eigen::MatrixXd m1(2, 3);

    // Initialize with comma-initializer
    m1 << 1, 2, 3,
          4, 5, 6;

    std::cout << "m1 =\n" << m1 << std::endl;
    std::cout << "rows: " << m1.rows() << ", cols: " << m1.cols() << std::endl;
    return 0;
}

Output:

bash
m1 =
1 2 3
4 5 6
rows: 2, cols: 3

Static Matrices (size known at compile time)

cpp
// Fixed-size matrices (more efficient: no heap allocation)
Eigen::Matrix2d m2;  // 2x2 double matrix
Eigen::Matrix3d m3;  // 3x3 double matrix
Eigen::Matrix4d m4;  // 4x4 double matrix

m2 << 1, 2,
      3, 4;

Static matrices are stored on the stack and benefit from compile-time size information for maximum optimization.


Vectors in Eigen

Vectors are a special case of matrices (a matrix with one column):

cpp
// Dynamic vector
Eigen::VectorXd v1(3);
v1 << 2, 1, 2;

std::cout << "v1 =\n" << v1 << std::endl;
// v1 =
// 2
// 1
// 2

std::cout << "rows: " << v1.rows() << ", cols: " << v1.cols() << std::endl;
// rows: 3, cols: 1


Arrays in Eigen

The Array class provides coefficient-wise operations. Unlike Matrix (which follows linear algebra rules), Array operations are applied element by element:

cpp
Eigen::ArrayXd a1(3);
a1 << 2, 1, 2;

// Coefficient-wise multiplication (not matrix multiplication)
Eigen::ArrayXd a2 = a1 * a1;  // [4, 1, 4]

// Add a constant to every element
Eigen::ArrayXd a3 = a1 + 10;  // [12, 11, 12]

2D arrays:

cpp
Eigen::ArrayXXd b1(2, 3);
b1 << 1, 2, 3,
      4, 5, 6;

std::cout << "b1 =\n" << b1 << std::endl;
// b1 =
// 1 2 3
// 4 5 6


Matrix Multiplication

Matrix multiplication uses the * operator, which is overloaded to perform proper linear algebra multiplication (not coefficient-wise):

cpp
#include <Eigen/Dense>
#include <iostream>

int main() {
    Eigen::MatrixXd m1(2, 3);
    m1 << 1, 2, 3,
          4, 5, 6;

    Eigen::VectorXd v1(3);
    v1 << 2, 1, 2;

    // Matrix-vector multiplication: (2x3) * (3x1) = (2x1)
    Eigen::MatrixXd p1 = m1 * v1;

    std::cout << "m1 * v1 =\n" << p1 << std::endl;
    // m1 * v1 =
    // 10   (1*2 + 2*1 + 3*2)
    // 25   (4*2 + 5*1 + 6*2)

    std::cout << "result rows: " << p1.rows() << ", cols: " << p1.cols() << std::endl;
    // rows: 2, cols: 1
    return 0;
}


Eigen Type Naming Convention

Eigen type names follow a consistent pattern:

text
Eigen::<Type><Size><Scalar>

Types:    Matrix, Vector, Array
Sizes:    2, 3, 4 (fixed), X (dynamic)
Scalars:  d (double), f (float), i (int), cf (complex<float>), cd (complex<double>)

TypeDescription
Eigen::Matrix2d2x2 matrix of doubles
Eigen::Matrix3f3x3 matrix of floats
Eigen::MatrixXdDynamic matrix of doubles
Eigen::Vector3d3-element column vector of doubles
Eigen::VectorXfDynamic column vector of floats
Eigen::ArrayXXd2D array of doubles (coefficient-wise ops)
Eigen::ArrayXd1D array of doubles

Conclusion

Eigen is the standard choice for linear algebra in C++ for good reason: it is header-only (zero build complexity), expressive (clean API), and fast (expression templates and SIMD). Whether you are implementing a Kalman filter, a 3D graphics transformation pipeline, or a machine learning algorithm, Eigen provides the matrix and vector types to do it correctly and efficiently.

The subsequent posts in this series cover Eigen vectors in detail and Eigen matrices with advanced operations like initialization patterns, coefficient accessors, and conversions to and from standard library types.