Eigen — Linear Algebra Backend

← Back to Language Guide

Eigen is the C++ template library that powers Eta’s dense linear algebra. It is a backend, not a user-facing module: there is no (import std.eigen) form. Instead, the runtime uses Eigen internally for the numerics in:

ModuleWhat Eigen does
std.statsOLS / GLS regression, PCA, covariance, descriptive statistics
std.torchLight-weight tensor ops on the CPU path
std.clprLP / QP solver workspace
std.aadVector primal / adjoint storage

This page documents what that means in practice, what guarantees the backend gives, and how to read the relevant performance trade-offs.


Why a backend, not a module

Eta values are NaN-boxed; double-precision matrices are not. Surfacing Eigen’s Matrix<double> directly would force every cell access through a boxing/unboxing trampoline. Instead the runtime keeps Eigen objects behind opaque handles (stats:matrix, torch:tensor) and exposes a high-level operation surface that batches work on the C++ side.

Result: the user-facing modules feel like Eta values, while the heavy lifting (BLAS-level loops, vectorised intrinsics, multi-threading) happens in compiled C++.


Where Eigen shows up

std.stats

Regression, decompositions, and projections all return Eta values (numbers, lists, vectors) but compute on Eigen matrices internally:

(import std.stats)
(stats:ols y X)            ; least squares: returns coefficients + diagnostics
(stats:pca X 'k 3)         ; top-3 PCA via Eigen's SVD

See Stats for the full surface.

std.torch

CPU tensor operations route through Eigen for small / medium tensors; larger ones hand off to libtorch’s kernels. The choice is internal — user code is unchanged.

std.clpr

The LP / QP oracle uses Eigen for its inner-loop linear algebra (pivoting, projection, KKT solves). See CLP(R).

std.aad

Reverse-mode AD stores primal and adjoint vectors as Eigen::VectorXd so the tape’s BLAS-1 sweeps can be vectorised.


Build configuration

Eigen is fetched via CMake at configure time (see cmake/FetchEigen.cmake). There is no Eta-side configuration: the same binary uses Eigen for all subsystems.

Optional knobs surfaced through CMake:

VariableDefaultMeaning
EIGEN_USE_THREADSOFFEnable OpenMP threading inside Eigen
EIGEN_USE_BLASOFFDefer to a vendor BLAS (MKL, OpenBLAS)

For the standard release builds, neither is enabled — the workloads addressed by std.stats and std.clpr are typically too small to benefit from a vendor BLAS.


Performance notes


When to drop into libtorch instead

Use std.torch when you need:

Stay with the Eigen-backed modules (std.stats, std.clpr) when: