Spectra computes a few eigenvalues of a large matrix without touching its entries
A header-only C++ library for large scale eigenvalue problems
At a glance
- What is it?
- Spectra is a header-only C++ library for large scale eigenvalue problems, built on Eigen and reimplementing the ARPACK algorithm rather than porting its code. You supply a matrix operation and a solver, and it returns the k eigenvalues you care about, which is the case where a full decomposition would be wasted work.
- Who is it for?
- Adopt Spectra when your matrix is large enough that a full spectral decomposition is impractical, you need only the k extreme or otherwise selected eigenvalues, and your project already uses C++ with Eigen available. Do not adopt it when you need every eigenvalue, when your matrix is small enough for a direct solver, or when you cannot supply a matrix-vector product, because that product is the entire interface Spectra consumes.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 111 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A redesign of ARPACK in C++, not a port of it
Spectra stands for Sparse Eigenvalue Computation Toolkit as a Redesigned ARPACK. The README is precise about what that means and what it does not mean. The library implements the major algorithms in ARPACK, but it provides a completely different interface, and it does not depend on ARPACK.
The algorithm behind it is the one described in the ARPACK Users' Guide, the implicitly restarted Arnoldi and Lanczos method. What Spectra does not do is reuse ARPACK's code. ARPACK itself is a FORTRAN package, which means linking it into a modern C++ project means a Fortran toolchain in the build, a C or Fortran interface layer, and the overhead of a separate library boundary. Spectra removes all of that by being header-only C++.
Its only dependency is Eigen, which is itself header-only, so embedding Spectra is a matter of adding include paths. The project has a dedicated site at spectralib.org carrying the API documentation generated with Doxygen, and the repository carries a CMakeLists.txt, an include directory, a test directory and a benchmark directory.
The intended audience is numerical software developers and physicists who need a handful of eigenvalues from a matrix they cannot afford to decompose completely.
Two objects: the matrix operation and the solver
The usage model has two steps, and the first one is the part that changes how you write the code.
Instead of handing the library a matrix, you hand it an operation. You define a class implementing a specific operation, for example the matrix-vector multiplication y = A * x, or the shift-solve operation y = inv(A - sigma * I) * x. Spectra ships helper classes that wrap a matrix object into such an operation, among them DenseGenMatProd for the general case and DenseSymShiftSolve for a symmetric shift-solve.
Then you construct a solver object over that operation and call it. SymEigsSolver handles real symmetric matrices, GenEigsSolver handles general real and complex matrices. The solver exposes init, compute and the result accessors.
This design is what makes the library applicable to matrices that are too large to store densely. The README puts it plainly: if the matrix-vector product A * x can be computed efficiently, which is the case for sparse matrices, Spectra is efficient for large scale eigenvalue problems. You can wire a custom operation to an iterative solver or to an external code that computes the product, and the solver never needs the entries themselves.
The cost of that flexibility is that you own the operation class. Spectra gives you the iteration, not the linear algebra underneath.
Nine solvers, one selection rule
The solver list covers the common matrix families and the two ways to accelerate a solve.
For real symmetric matrices there is SymEigsSolver, and for general real and complex matrices GenEigsSolver. Shift-and-invert variants exist for both: SymEigsShiftSolver for symmetric matrices, GenEigsRealShiftSolver and GenEigsComplexShiftSolver for general real matrices with a real or a complex shift. Generalized problems are covered by SymGEigsSolver and SymGEigsShiftSolver. HermEigsSolver handles complex Hermitian matrices, and DavidsonSymEigsSolver is a Jacobi-Davidson solver for real symmetric matrices using the DPR correction method.
The selection of which eigenvalues you get is a separate parameter. Sort rules such as LargestAlge pick the largest k eigenvalues algebraically, and the README mentions rules for eigenvalues with the largest real parts among others. The number k is chosen by the caller, and the solver is constructed with it, together with a subspace size.
The design principle underneath is that k is normally much smaller than the size n of the matrix, so only a few eigenvalues and eigenvectors are computed. That is generally more efficient than calculating the whole spectral decomposition, and it is the reason to reach for a library like this at all.
Using the symmetric solver on a dense matrix
The README's first example builds a small symmetric matrix and asks for the largest three eigenvalues. The includes and the namespace are the whole setup:
#include <Eigen/Core>
#include <Spectra/SymEigsSolver.h>
#include <iostream>
using namespace Spectra;The operation wrapper and the solver are constructed next, with the count of wanted eigenvalues and the subspace size as the last two arguments:
DenseSymMatProd<double> op(M);
SymEigsSolver<DenseSymMatProd<double>> eigs(op, 3, 6);The solver is initialised, run with a sort rule, and the results are read only when the run reports success:
eigs.init();
int nconv = eigs.compute(SortRule::LargestAlge);
Eigen::VectorXd evalues;
if(eigs.info() == CompInfo::Successful)
evalues = eigs.eigenvalues();That last part is the pattern to copy. The computation returns the number of converged eigenvalues, and the eigenvalues and eigenvectors are only valid when info reports CompInfo::Successful. A caller that ignores the status can read unconverged results and believe they are the answer.
The second example in the README does the same for a sparse matrix, using SparseGenMatProd and SparseSymMatProd, which the README names as the sparse entry points. A CMakeLists.txt sits at the top of the repository, with a cmake folder and an examples folder holding DavidsonSymEigs_example.cpp and its accompanying markdown.
Where Spectra stops and a direct solver begins
The boundary of the library is worth being clear about, because it decides whether Spectra is the right tool at all.
It computes a specified number k of eigenvalues, not the full spectrum. If your problem needs every eigenvalue of a matrix, or the complete spectral decomposition, this is the wrong library and you want a direct solver instead. The README's own framing is that k is usually much smaller than n and that computing the whole decomposition is generally less efficient.
The second limit is convergence. These are iterative methods, so the number of converged eigenvalues is a runtime result rather than a guarantee. The example reads the count into nconv and checks the status, and a production pipeline has to do the same and decide what to do when the count falls short of k.
The third limit is what you must supply. Spectra does not know how to multiply your matrix by a vector. If your matrix is dense and small enough to multiply cheaply, the setup work of writing an operation class may exceed the saving. The library pays off when the product is cheap relative to the size of the matrix, which is the sparse case.
There is also no ARPACK to fall back on. Because Spectra does not link ARPACK, a workflow that needs ARPACK's exact numerical behaviour, or a Fortran build integration, is a different codebase.
Versioning, the 1.0 break and the MPL-2.0 licence
The README carries a prominent warning that Spectra 1.0.0 was released on 2021-07-01 with a lot of API-breaking changes, and it points at a MIGRATION.md file for a smooth transition. The release history shows version 1.0.1 on 2022-04-06, version 1.1.0 on 2025-01-01 and version 1.2.0 on 2025-06-29. The last push to the default branch was on 2026-07-04, and the repository is not archived.
So the pattern is a long-lived stable library with infrequent releases and a single large breaking version early in its life. Anyone upgrading from a pre-1.0 codebase should read MIGRATION.md rather than patching compile errors, and the CHANGELOG.md in the repository is the record of what changed between the tagged versions.
The licence is MPL-2.0, which is a file-level copyleft licence. The practical difference from MIT or Apache for a header-only library is that if you modify a covered file and distribute it, that modified file has to stay available under MPL-2.0. Using Spectra unmodified in your own application does not spread the obligation to your own source, and linking it into a larger C++ project is the normal case. This is a licensing fact rather than legal advice, and the licence text in the repository governs.
Development is tracked on GitHub with a basic CI workflow and a codecov configuration, and the project also maintains AUTHORS.md, a .clang-format configuration for consistent formatting and a doxygen folder for the documentation build.
Editorial conclusion
Adopt Spectra when your matrix is large enough that a full spectral decomposition is impractical, you need only the k extreme or otherwise selected eigenvalues, and your project already uses C++ with Eigen available. Do not adopt it when you need every eigenvalue, when your matrix is small enough for a direct solver, or when you cannot supply a matrix-vector product, because that product is the entire interface Spectra consumes. Before you build on it, check the MIGRATION.md file if your code targets the pre-1.0 API, since the README states that 1.0.0 arrived on 2021-07-01 with API-breaking changes, and confirm that the solver you need exists in the list of nine, from SymEigsSolver through DavidsonSymEigsSolver and HermEigsSolver.
Frequently asked questions
What is Spectra and what does it depend on?
Spectra is a header-only C++ library for large scale eigenvalue problems, built on Eigen. The README describes it as a redesign of ARPACK that implements the major ARPACK algorithms with a different interface and does not depend on ARPACK itself.
How do I compute the largest eigenvalues of a matrix with Spectra?
Wrap the matrix in an operation class such as DenseSymMatProd, construct a solver such as SymEigsSolver with the number of eigenvalues and the subspace size, then call init and compute with a sort rule like SortRule::LargestAlge. Read the results only after checking that info reports CompInfo::Successful.
Which eigen solvers does Spectra provide?
The list includes SymEigsSolver for real symmetric matrices, GenEigsSolver for general real and complex matrices, shift-and-invert variants SymEigsShiftSolver, GenEigsRealShiftSolver and GenEigsComplexShiftSolver, generalized solvers SymGEigsSolver and SymGEigsShiftSolver, DavidsonSymEigsSolver using the DPR correction method, and HermEigsSolver for complex Hermitian matrices.
How is Spectra different from ARPACK?
ARPACK is written in FORTRAN, while Spectra implements the same implicitly restarted Arnoldi and Lanczos algorithms in header-only C++ with a different interface and no ARPACK dependency. The README states that Spectra is not a clone of ARPACK for C++.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yixuan-spectra)