* This project honors the British philosopher and mathematician Bertrand Russell.
- Introduction
- Installation
- 🌟 Examples
- (lab) Numerical integration (quadrature)
- (lab) Solution of PDEs using spectral collocation
- (lab) Matrix visualization
- (lab) Singular value decomposition
- (lab) Cholesky factorization
- (lab) Solution of a (dense) linear system
- (lab) Reading table-formatted data files
- (lab) Line search for optimization
- (nonlin) Numerical continuation of a B-spline curve
- (sparse) Solution of a sparse linear system
- (sparse) Solution of a complex sparse linear system
- (ode) Solution of the Brusselator ODE
- (ode) Solution of the Brusselator PDE
- (pde) Spectral collocation in 2D with transfinite mapping
- (stat) Generate the Frechet distribution
- (tensor) Allocate second-order tensors
- Roadmap
- For developers
Russell (Rust Scientific Library) helps develop high-performance computations involving linear algebra, sparse linear systems, numerical mathematics (continuation), differential equations, statistics, and continuum mechanics using the Rust programming language. While applications built with Russell mainly focus on computational mechanics, its foundation in fundamental mathematics and numerics makes it useful for other disciplines as well.
This project aims to deliver efficient, reliable, and easy-to-maintain code. To support this, Russell includes unit and integration tests, with test coverage required to be over 95%. For better code maintenance, Russell avoids overly complex Rust constructions. However, it still makes use of Rust features such as generics, traits, enums, options, and results. Another goal of Russell is to provide examples of all computations in the documentation to assist users and developers.
This project is split into the following crates:
-
russell_lab — Core mathematical and linear algebra laboratory:
- Data structures: NumVector, NumMatrix (column-major layout for direct BLAS/LAPACK interoperability), and stack-allocated SmallVector/SmallMatrix.
- Linear Algebra: BLAS 1/2/3 and LAPACK routines (dense solves, SVD, Cholesky, symmetric and general eigenvalues/eigenvectors for real and complex numbers).
- Numerics & Special Functions: Bessel, modified Bessel, Beta, Gamma, Erf, Elliptic integrals, Chebyshev/Legendre polynomials, Lagrange interpolation, B-splines, quadrature, Brent's root-finding, Newton solver, cubic solver, and numerical derivatives/Jacobians.
- Backends: OpenBLAS / Netlib LAPACK or Intel oneAPI MKL (via intel_mkl feature).
-
russell_tensor — Tensor calculus and continuum mechanics:
- Tensor types: Tensor1 (3D vectors), Tensor2 (2nd-order), Tensor3 (3rd-order), Tensor4 (4th-order).
- Kelvin-Mandel representation: Maps tensors to vector/matrix spaces preserving Euclidean norms.
- Operations & Calculus: Dot/ddot contractions, dyadic products, polar decompositions, principal/deviatoric/octahedral invariants, Lode invariant, first and second derivatives of invariants and tensor functions, linear elasticity / Hooke's law.
-
russell_sparse — Sparse matrix structures and direct solvers:
- Formats: CooMatrix, CscMatrix, CsrMatrix (both real f64 and Complex64).
- Direct Solvers: UMFPACK (SuiteSparse), MUMPS (local_sparse), and NVIDIA cuDSS (cudss).
- Utilities: Matrix Market I/O, vismatrix exporter, numerical Jacobian assembly, linear system verification.
-
russell_ode — ODE and Index-1 DAE solvers:
- Explicit Runge-Kutta (DoPri5, DoPri8, Forward Euler) with stiffness detection and dense output.
- Implicit solvers: Backward Euler and Radau5 (supports mass matrices, DAEs, and concurrent real/complex linear solves).
-
russell_pde — Partial differential equation tools:
- 1D/2D Finite Difference Methods (FDM) and Spectral Collocation (SPC) on Chebyshev/Legendre-Lobatto nodes.
- Transfinite mappings for deformed/curved domains.
- Essential boundary conditions via System Partitioning (SPS) or Lagrange Multipliers (LMM).
-
russell_nonlin — Continuation methods for parameterized nonlinear systems
$G(u, \lambda) = 0$ :- Predictor-corrector continuation: Natural continuation and Pseudo-arclength continuation (handling folds/limit points).
-
russell_stat — Engineering statistics and extreme value distributions
- Frechet, Gumbel, Lognormal, Normal, Uniform, quantiles, IQR, ASCII histogram generation.
Below is a summary of internal dependencies:
| Crate | Key dependencies |
|---|---|
russell_lab |
num-complex, serde |
russell_sparse |
russell_lab |
russell_stat |
russell_lab, rand |
russell_tensor |
russell_lab, serde |
russell_pde |
russell_lab, russell_sparse |
russell_ode |
russell_lab, russell_sparse, russell_pde |
russell_nonlin |
russell_lab, russell_sparse, russell_stat |
russell_lab
├── russell_stat
├── russell_tensor
├── russell_sparse
│ ├── russell_pde
│ │ └── russell_ode
│ └── russell_nonlin
The following crates are not part of russell but are associated with it and recommended:
- plotpy Plotting tools using Python3/Matplotlib as an engine (for quality graphics)
- tritet Triangle and tetrahedron mesh generators (with Triangle and Tetgen)
- gemlab Geometry, meshes, and numerical integration for finite element analyses
- benchmark-russell Performance benchmarks for this project
This project employs OpenBLAS (or Intel MKL) for linear algebra computations and SuiteSparse (or MUMPS) for the solution of large (sparse) linear systems of equations. See the Installation section for instructions on how to install these libraries on different platforms.
To use Intel MKL, the intel_mkl feature must be selected. There is also an option to compile SuiteSparse and MUMPS locally, which may yield better performance. When local compilation is used, the local_sparse feature is selected.
Some crates in this project can also use NVIDIA cuDSS, a direct sparse solver for NVIDIA GPUs. This feature can be enabled by the cudss flag. Note that cuDSS is in Preview Mode 🚧.
The table below summarizes the features of each crate:
intel_mkl |
local_sparse |
cudss |
|
|---|---|---|---|
russell_lab |
✓ | ||
russell_nonlin |
✓ | ✓ | ✓ |
russell_ode |
✓ | ✓ | ✓ |
russell_pde |
✓ | ✓ | ✓ |
russell_sparse |
✓ | ✓ | ✓ |
russell_stat |
✓ | ||
russell_tensor |
✓ |
Below is an example of how to enable the intel_mkl and local_sparse features with the russell_sparse crate in the Cargo.toml file:
[dependencies]
russell_lab = { version = "*", features = ["intel_mkl"] }
russell_sparse = { version = "*", features = ["intel_mkl", "local_sparse"] }Replace "*" with the desired version. Note that russell_sparse (and all other crates in this project) require russell_lab as a dependency.
Russell requires some non-Rust libraries (OpenBLAS and SuiteSparse) to achieve the maximum performance. These libraries can be installed as explained in each subsection next. Alternatively, Intel MKL may be used instead of OpenBLAS. In this case, the feature named intel_mkl must be enabled.
In addition to SuiteSparse (UMFPACK), the MUMPS solver may be used as an optional feature. In this case, MUMPS must be locally compiled and installed and the feature named local_sparse must be enabled. Note that we could possibly use MUMPS from the package manager of your Linux distribution, however, MUMPS is typically only available as an extra package and often outdated. Moreover, the distributions do not always provide the sequential version (without OpenMPI) of MUMPS which is leaner than the parallel version (not used in this project). Thus, we recommend compiling MUMPS locally.
It is important to highlight that, when MUMPS is enabled, SuiteSparse must also be compiled locally. This requirement is mostly for convenience and does not cause many problems since the build tools will be required for MUMPS anyway. Furthermore, there is an advantage of having consistency since the linear algebra library (OpenBLAS or Intel MKL) will be the same for both MUMPS and SuiteSparse.
Note that, while it is possible to use Intel MKL with russell_lab and OpenBLAS with russell_sparse, this is not advantageous since Intel MKL is slightly more performant than OpenBLAS (see this article). Thus, if you have already installed Intel MKL, it is easy to compile SuiteSparse and MUMPS (Option 3 below). Thus, we do not consider a fourth option with MKL for russell_lab and OpenBLAS for russell_sparse.
The direct sparse solver based on NVIDIA's CUDA platform for GPUs is also available in russell_sparse. The solver, named cuDSS, can be installed as explained in nvidia-cudss.md or by running the commands in debian-compile-cudss.bash (Debian/Ubuntu) or arch-compile-cudss.bash (Arch) or UNTESTED-windows-compile-cudss.bash.
Run the following command to install OpenBLAS and SuiteSparse:
pacman -Syu rust blas-openblas suitesparse(no feature flags required in Cargo.toml)
Run the following commands to compile and install SuiteSparse and MUMPS with OpenBLAS (use these scripts at your own risk; carefully check the scripts before running them):
bash zscripts/arch-compile-mumps.bash
bash zscripts/arch-compile-suitesparse.bash Set Cargo.toml as follows:
russell_sparse = { version = "*", features = ["local_sparse"] }Run the following commands to compile and install SuiteSparse and MUMPS with Intel MKL (use these scripts at your own risk; carefully check the scripts before running them):
bash zscripts/arch-install-intel-toolkit.bash
bash zscripts/arch-compile-mumps.bash 1
bash zscripts/arch-compile-suitesparse.bash 1Set Cargo.toml as follows:
russell_sparse = { version = "*", features = ["intel_mkl", "local_sparse"] }Run the following command to install OpenBLAS and SuiteSparse:
sudo apt-get install -y --no-install-recommends \
liblapacke-dev \
libopenblas-dev \
libsuitesparse-dev(no feature flags required in Cargo.toml)
Run the following commands to compile and install SuiteSparse and MUMPS with OpenBLAS (use these scripts at your own risk; carefully check the scripts before running them):
bash zscripts/debian-compile-mumps.bash
bash zscripts/debian-compile-suitesparse.bash Set Cargo.toml as follows:
russell_sparse = { version = "*", features = ["local_sparse"] }Run the following commands to compile and install SuiteSparse and MUMPS with Intel MKL (use these scripts at your own risk; carefully check the scripts before running them):
bash zscripts/debian-install-intel-toolkit.bash
bash zscripts/debian-compile-mumps.bash 1
bash zscripts/debian-compile-suitesparse.bash 1Set Cargo.toml as follows:
russell_sparse = { version = "*", features = ["intel_mkl", "local_sparse"] }dnf update -y
dnf install epel-release -y
crb enable
dnf install -y \
lapack-devel \
openblas-devel \
suitesparse-develThe other options have not been tested yet.
First, install Homebrew.
brew install lapack openblas suite-sparseThe other options have not been tested yet.
The installation process on Windows requires the MSYS2 environment, which provides a Unix-like terminal and package manager. After installing MSYS2, you can use the pacman package manager to install the necessary libraries.
See windows.md for detailed instructions on how to set up the MSYS2 environment and install the required libraries on Windows.
By default, OpenBLAS will use all available threads, including Hyper-Threads that may worsen the performance. Thus, it is recommended to set the following environment variable:
export OPENBLAS_NUM_THREADS=<real-core-number>Substitute <real-core-number> with the correct value from your system.
Furthermore, if working on a multi-threaded application where the solver should not be multi-threaded on its own (e.g., running parallel calculations in an optimization tool), you may set:
export OPENBLAS_NUM_THREADS=1See also:
- russell_lab/examples
- russell_nonlin/examples
- russell_ode/examples
- russell_pde/examples
- russell_sparse/examples
- russell_stat/examples
- russell_tensor/examples
The code below determines the perimeter P of an ellipse of length 2 and width 1:
2π
⌠ ____________________
P = │ \╱ ¼ sin²(θ) + cos²(θ) dθ
⌡
0
See the code: algo_quadrature_integrate_1d.rs
This example illustrates the solution of a 1D PDE using the spectral collocation method. It employs the InterpLagrange struct.
d²u du x
——— - 4 —— + 4 u = e + C
dx² dx
-4 e
C = ——————
1 + e²
x ∈ [-1, 1]
Boundary conditions:
u(-1) = 0 and u(1) = 0
Reference solution:
x sinh(1) 2x C
u(x) = e - ——————— e + —
sinh(2) 4
See the code: algo_lorene_1d_pde_spectral_collocation.rs
Results:
We can use the fantastic tool named vismatrix to visualize the pattern of non-zero values of a matrix. With vismatrix, we can click on each circle and investigate the numeric values as well.
The function mat_write_vismatrix writes the input data file for vismatrix.
See the code: matrix_visualization.rs
After generating the "dot-smat" file, run the following command:
vismatrix /tmp/russell_lab/matrix_visualization.smatOutput:
See the code: matrix_singular_value_decomposition.rs
See the code: matrix_cholesky_4x4.rs
See the code: matvec_solve_linear_system.rs
The goal is to read the following file (clay-data.txt):
# Fujinomori clay test results
sr ea er # header
1.00000 -6.00000 0.10000
2.00000 7.00000 0.20000
3.00000 8.00000 0.20000 # << look at this line
# comments plus new lines are OK
4.00000 9.00000 0.40000
5.00000 10.00000 0.50000
# bye
Each column (sr, ea, er) is accessible via the get method of the [HashMap].
See the code: base_read_table.rs
Alternatively, we can use the simpler read_data function:
See the code: base_read_data.rs
Line search is used in gradient-based optimization methods to find an appropriate step size.
See the code: algo_line_search.rs
This example traces a B-spline curve defined by G(u, λ) = 0 using the Pseudo-arclength continuation method.
The nonlinear problem is defined as follows:
G(u, λ) = u - C(λ)
where C(λ) is a point on a 2D B-spline curve parametrized by λ ∈ [0,1].
See the code: arclength_bspline.rs
The plot looks like this:
See the code: doc_umfpack_quickstart_coo.rs
See the code: doc_complex_umfpack_tiny.rs
The system is:
y0' = 1 - 4 y0 + y0² y1
y1' = 3 y0 - y0² y1
with y0(x=0) = 3/2 and y1(x=0) = 3
Solving with DoPri8 -- 8(5,3):
See the code: brusselator_ode_dopri8.rs
A plot of the (dense) solution is shown below:
This example solves the Brusselator PDE described in (Hairer E, Wanner G (2002) Solving Ordinary Differential Equations II Stiff and Differential-Algebraic Problems. Second Revised Edition. Corrected 2nd printing 2002. Springer Series in Computational Mathematics, 614p).
See the code: brusselator_pde_radau5_2nd.rs.
The results are shown below for the U field:
And below for the V field:
See the code: brusselator_pde_2nd_comparison.rs compares russell results with Mathematica results.
The figure below shows the russell (black dashed lines) and Mathematica (red solid lines) results for the U field:
The figure below shows the russell (black dashed lines) and Mathematica (red solid lines) results for the V field:
Example: Solving a 2D Poisson equation on a rotated square domain
This example employs spectral collocation with transfinite mapping to solve the Poisson equation:
-k · ∇²u = f on a unit square rotated by angle α
u = g on the boundary (Dirichlet conditions)
The analytical solution used for verification is:
u(x,y) = sin(π·x·cos(α) + π·y·sin(α)) · exp(π·y·cos(α) - π·x·sin(α))
The domain is mapped from the reference square (r,s) ∈ [-1,1]×[-1,1] to the physical rotated square via transfinite interpolation.
See the code: doc_example_spc_map.rs
The plot looks like this:
See the code: distribution_frechet.rs
Sample output:
min = 0.11845731988882305
max = 26248.036672205748
mean = 12.268212841918867
std_dev = 312.7131690782321
[ 0,0.5) | 1370 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
[0.5, 1) | 2313 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
[ 1,1.5) | 1451 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
[1.5, 2) | 971 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦
[ 2,2.5) | 659 🟦🟦🟦🟦🟦🟦🟦🟦
[2.5, 3) | 460 🟦🟦🟦🟦🟦
[ 3,3.5) | 345 🟦🟦🟦🟦
[3.5, 4) | 244 🟦🟦🟦
[ 4,4.5) | 216 🟦🟦
[4.5, 5) | 184 🟦🟦
[ 5,5.5) | 133 🟦
[5.5, 6) | 130 🟦
[ 6,6.5) | 115 🟦
[6.5, 7) | 108 🟦
[ 7,7.5) | 70
[7.5, 8) | 75
[ 8,8.5) | 57
[8.5, 9) | 48
[ 9,9.5) | 59
sum = 9008
See the code: allocating_second_order_tensors.rs
- Improve
russell_lab- Implement more integration tests for linear algebra
- Implement more examples
- Implement more performance benchmarks
- Wrap more BLAS/LAPACK functions
- Implement dggev, zggev, zheev, and zgeev
- Wrap Intel MKL (alternative to OpenBLAS)
- Add more complex number functions
- Add fundamental functions to
russell_lab- Implement the Bessel functions
- Implement the modified Bessel functions
- Implement the elliptical integral functions
- Implement Beta, Gamma and Erf functions (and associated)
- Implement orthogonal polynomial functions
- Implement some numerical methods in
russell_lab- Implement Brent's solver
- Implement a solver for the cubic equation
- Implement numerical derivation
- Implement numerical Jacobian function
- Implement line search
- Implement Newton's method for nonlinear systems
- Implement numerical quadrature
- Implement multidimensional data interpolation
- Add interpolation and polynomials to
russell_lab- Implement Chebyshev polynomials
- Implement Chebyshev interpolation
- Implement Orthogonal polynomials
- Implement Lagrange interpolation
- Implement Legendre polynomials
- Implement Fourier interpolation
- Improve
russell_sparse- Wrap the cuDSS solver (NVIDIA GPUs)
- Implement support for complex numbers
- Implement the Compressed Sparse Column format (CSC)
- Implement the Compressed Sparse Row format (CSR)
- Improve the C-interface to UMFPACK and MUMPS
- Write the conversion from COO to CSC in Rust
- Improve
russell_ode- Implement explicit Runge-Kutta solvers
- Implement Radau5 for DAEs
- Implement extrapolation methods
- Implement multi-step methods
- Implement general linear methods
- Implement
russell_pde- Implement 1D and 2D spectral collocation methods
- Implement 1D and 2D finite difference methods
- Implement
russell_nonlin- Implement natural continuation for nonlinear systems
- Implement pseudo-arc-length continuation for nonlinear systems
- Study better methods for step size control in continuation methods
- Improve
russell_stat- Add probability distribution functions
- Implement drawing of ASCII histograms
- Implement FORM (first-order reliability method)
- Add more examples
- Improve
russell_tensor- Implement functions to calculate invariants
- Implement first and second-order derivatives of invariants
- Implement some high-order derivatives
- Implement standard continuum mechanics tensors
- General improvements
- Compile on Linux (Arch, Debian/Ubuntu, Rocky)
- Compile on macOS
- Compile on Windows
- Study the compilation of MUMPS on Windows
- Write scripts to compile on Windows
This section summarizes the build.rs files, which compile and link the non-Rust C (and CUDA) dependencies at build time.
The code adopts the convention that double lower-case letters denote a single capital letter, matching the symbols used in the documentation and the mathematical formulas:
aa⇔Abb⇔Bpp⇔Pii⇔Ijj⇔J
For example, the scalar coefficients A, B, and C in the second-derivative formulas of the invariants are coded as aa, bb, and cc.
russell_lab/build.rs compiles a single C shim (c_code/interface_blas.c) that wraps BLAS/LAPACK, selecting one of two paths via feature flags:
intel_mkl— builds against Intel oneAPI MKL: resolvesMKL_VERSION(env var, defaultlatest), adds/opt/intel/oneapi/mkl/{version}to the include path, definesUSE_INTEL_MKL, and linksmkl_intel_lp64,mkl_intel_thread,mkl_core,pthread,m,dl,iomp5.- OpenBLAS (default) — split by OS:
- Windows: locates headers/libraries via the
MSYS2_PREFIXenvironment variable. - Other OS: probes
pkg-config(probe_blas_lapack), tryingopenblasfirst and then thecblas+lapackpair (Nix). Before trusting a probe, it verifies the headers (cblas.h,lapack.h) actually exist — this avoids the RHEL/Rocky case wherelapack.pcexists but ships nolapack.h. It falls back to hardcoded Homebrew/system paths (filtered viaexisting_dirsto drop non-existent directories) and links theopenblasandlapackshared libraries.
- Windows: locates headers/libraries via the
Build-dependencies: cc, pkg-config.
russell_sparse/build.rs compiles the C (and CUDA) shims for the sparse solvers. The build is additive: UMFPACK is always compiled and linked, MUMPS when local_sparse is enabled, and cuDSS when cudss is enabled:
- Windows: uses
MSYS2_PREFIX; thecudssfeature has no effect here (cuDSS is only built on non-Windows platforms). Whenlocal_sparseis enabled, the static MUMPS libraries are linked (dmumps_cpmech,zmumps_cpmech,mumps_common_cpmech,mpiseq_cpmech,pord_cpmech,metis,gfortran,gomp). - Other OS:
- Computes fallback include/library directories with
existing_dirs(drops nonexistent paths to avoid shadowing, e.g., a Nix devShell). - The
cudsspaths usedetect_cuda_arch(envCUDSS_CUDA_ARCH→nvidia-smi→ defaultsm_89) anddetect_cxx(envGCC_VERSION→gcc -dumpversion→g++, org++-15when gcc > 15), compiling the.cufiles withcc::Build::cuda(true)and linkingcudartandcudss. - The default path (no
cudss, nolocal_sparse) probespkg-configfor UMFPACK (trying bothUMFPACKandumfpackspellings) before falling back.
- Computes fallback include/library directories with
Build-dependencies: cc, pkg-config.




