Matrix computations are at the heart of many quantitative finance models, from Monte Carlo simulations to risk matrix evaluations. In C++, selecting the right library can dramatically affect performance, readability, and numerical stability. Fortunately, there are several powerful options designed for high-speed computation and scientific accuracy. Whether you need dense, sparse, or banded matrix support, the C++ ecosystem has you covered. Some libraries prioritize speed, others emphasize syntax clarity or Python compatibility. What are the best C++ libraries for matrix computations?
Choosing between Eigen, Armadillo, or Blaze depends on your project goals. If you’re building a derivatives engine or a backtesting framework, using the wrong matrix abstraction can slow you down. In this article, we’ll compare the top C++ matrix libraries, focusing on performance, ease of use, and finance-specific suitability. By the end, you’ll know exactly which one to use for your next quant project. Let’s dive into the best C++ libraries for matrix computations.
1. Eigen
Website: eigen.tuxfamily.org
License: MPL2
Key Features:
- Header-only: No linking required
- Fast: Competes with BLAS performance
- Clean API: Ideal for prototyping and production
- Supports: Dense, sparse, and fixed-size matrices
- Thread-safe: As long as each thread uses its own objects
Use Case: General-purpose, widely used in finance for risk models and curve fitting.
Eigen is a header-only C++ template library for linear algebra, supporting vectors, matrices, and related algorithms. Known for its performance through expression templates, it’s widely used in quant finance, computer vision, and machine learning.
Here is a snippet example:
#include <iostream>
#include <Eigen/Dense>
int main() {
// Define 2x2 matrices
Eigen::Matrix2d A;
Eigen::Matrix2d B;
// Initialize matrices
A << 1, 2,
3, 4;
B << 2, 0,
1, 2;
// Matrix addition
Eigen::Matrix2d C = A + B;
// Matrix multiplication
Eigen::Matrix2d D = A * B;
// Print results
std::cout << "Matrix A + B:\n" << C << "\n\n";
std::cout << "Matrix A * B:\n" << D << "\n";
return 0;
}
This is probably one of the best C++ libraries for matrix computations.
2. Armadillo
Website: arma.sourceforge.net
License: MPL2
Key Features:
- Readable syntax: Ideal for research and prototyping
- Performance-boosted: Uses LAPACK/BLAS when available
- Supports: Dense, sparse, banded matrices
- Integrates with: OpenMP, ARPACK, SuperLU
- Actively maintained: Trusted in academia and finance
Use Case: Quant researchers prototyping algorithms with familiar syntax.
Armadillo is a high-level C++ linear algebra library that offers Matlab-like syntax, making it exceptionally easy to read and write. Under the hood, it can link to BLAS and LAPACK for high-performance computations, especially when paired with libraries like Intel MKL or OpenBLAS.
Here’s a quant finance-style example using Armadillo to perform a Cholesky decomposition on a covariance matrix, which is a common operation in portfolio risk modeling, Monte Carlo simulations, and factor models.
#include <iostream>
#include <armadillo>
int main() {
using namespace arma;
// Simulated 3-asset covariance matrix (symmetric and positive-definite)
mat cov = {
{0.10, 0.02, 0.04},
{0.02, 0.08, 0.01},
{0.04, 0.01, 0.09}
};
// Perform Cholesky decomposition: cov = L * L.t()
mat L;
bool success = chol(L, cov, "lower");
if (success) {
std::cout << "Cholesky factor L:\n";
L.print();
// Simulate a standard normal vector for 3 assets
vec z = randn<vec>(3);
// Generate correlated returns: r = L * z
vec returns = L * z;
std::cout << "\nSimulated correlated return vector:\n";
returns.print();
} else {
std::cerr << "Covariance matrix is not positive-definite.\n";
}
return 0;
}
3. Blaze
Website: blaze.mathjs.org
License: BSD
Key Features:
- Highly optimized: Expression templates + SIMD
- Parallel execution: Supports OpenMP, HPX, and pthreads
- BLAS backend optional
- Supports: Dense/sparse matrices, vectors, custom allocators
- Flexible integration: Can plug into existing quant platforms
Use Case: Performance-critical applications like Monte Carlo engines.
Blaze is a high-performance C++ math library that emphasizes speed and scalability. It uses expression templates like Eigen but leans further into parallelism, making it ideal for latency-sensitive finance applications such as pricing engines, curve fitting, or Monte Carlo simulations.
Imagine you simulate 1,000 paths for a European call option across 3 assets. Here’s how you could compute portfolio payoffs using Blaze:
#include <iostream>
#include <blaze/Math.h>
int main() {
using namespace blaze;
constexpr size_t numPaths = 1000;
constexpr size_t numAssets = 3;
// Simulated terminal prices (rows = paths, cols = assets)
DynamicMatrix<double> terminalPrices(numPaths, numAssets);
randomize(terminalPrices); // Random values between 0 and 1
// Portfolio weights (e.g., long 1.0 in asset 0, short 0.5 in asset 1, flat in asset 2)
StaticVector<double, numAssets> weights{1.0, -0.5, 0.0};
// Compute payoffs: each row dot weights
DynamicVector<double> payoffs = terminalPrices * weights;
std::cout << "First 5 simulated portfolio payoffs:\n";
for (size_t i = 0; i < 5; ++i)
std::cout << payoffs[i] << "\n";
return 0;
}
4. xtensor
Website: xtensor.readthedocs.io
License: BSD
Key Features:
- Numpy-like multidimensional arrays
- Integrates well with Python via
xtensor-python
- Supports broadcasting and lazy evaluation
Use Case: Interfacing with Python or for higher-dimensional data structures.
xtensor is a C++ library for numerical computing, offering multi-dimensional arrays with NumPy-style syntax. It supports broadcasting, lazy evaluation, and is especially handy for developers needing interoperability with Python (via xtensor-python
) or high-dimensional operations in quant research.
- Python interop through
xtensor-python
- Header-only, modern C++17+
- Syntax close to NumPy
- Fast and memory-efficient
- Broadcasting, slicing, views supported
Here is an example for moving average calculation:
#include <iostream>
#include <xtensor/xarray.hpp>
#include <xtensor/xview.hpp>
#include <xtensor/xadapt.hpp>
#include <xtensor/xio.hpp>
int main() {
using namespace xt;
// Simulated closing prices (1D tensor)
xarray<double> prices = {100.0, 101.5, 103.2, 102.0, 104.1, 106.3, 107.5};
// Window size for moving average
std::size_t window = 3;
// Compute moving averages
std::vector<double> ma_values;
for (std::size_t i = 0; i <= prices.size() - window; ++i) {
auto window_view = view(prices, range(i, i + window));
double avg = mean(window_view)();
ma_values.push_back(avg);
}
// Print result
std::cout << "Rolling 3-period moving averages:\n";
for (auto val : ma_values)
std::cout << val << "\n";
return 0;
}
Ready for the last entries for our article on the best C++ libraries for matrix computations?
5. FLENS (Flexible Library for Efficient Numerical Solutions)
Website: github.com/michael-lehn/FLENS
License: BSD
Key Features:
- Thin wrapper over BLAS/LAPACK for speed
- Supports banded and triangular matrices
- Good for structured systems in quant PDEs
- Integrates well with Fortran-style scientific computing
Use Case: Structured financial models involving PDE solvers.
FLENS is a C++ wrapper around BLAS and LAPACK designed for clear object-oriented syntax and high numerical performance. It provides clean abstractions over dense, sparse, and banded matrices, making it a good fit for quant applications involving curve fitting, linear systems, or differential equations.Object-oriented, math-friendly syntax
Let’s solve a system representing a regression problem (e.g., estimating betas in a factor model):
#include <flens/flens.cxx>
#include <iostream>
using namespace flens;
int main() {
typedef GeMatrix<FullStorage<double> > Matrix;
typedef DenseVector<Array<double> > Vector;
// Create matrix A (3x3) and vector b
Matrix A(3, 3);
Vector b(3);
A = 1.0, 0.5, 0.2,
0.5, 2.0, 0.3,
0.2, 0.3, 1.0;
b = 1.0, 2.0, 3.0;
// Solve Ax = b using LAPACK
Vector x(b); // solution vector
lapack::gesv(A, x); // modifies A and x
std::cout << "Solution x:\n" << x << "\n";
return 0;
}