Complex numbers, first-class, all the way through ndarray.
Today we released OxiBLAS 0.1.2 — a focused update that extends the ndarray integration with complex-aware LAPACK and relaxes trait bounds so the high-level solvers accept complex types.
No C. No Fortran. No external shared libraries. No FFI overhead. No build hell. Just clean, memory-safe linear algebra that compiles to a single static binary and runs everywhere.
Why 0.1.2 matters
OxiBLAS has supported Complex32 and Complex64 in its core BLAS/LAPACK since 0.1.0. But the ergonomic oxiblas-ndarray layer — the one most users reach for when they already have Array2 data — was still real-centric for several decompositions. If your matrices were complex and you lived in ndarray, you had to drop down to lower-level APIs.
0.1.2 closes that gap. It adds complex-specific decomposition functions to oxiblas-ndarray and removes an unnecessary Real trait bound that had been blocking complex types from the generic solve path. The result: spectral methods, complex least-squares setups, and Hermitian eigenproblems now flow through the same convenient ndarray API as their real counterparts.
Technical Deep Dive: complex in the ndarray layer
The new functions live in oxiblas-ndarray, built on the complex routines already present in oxiblas-lapack:
svd_complex_ndarray— SVD for complex matrices via a one-sided Jacobi algorithm, returning aComplexSvdResult<T>.qr_complex_ndarray— QR for complex matrices with a unitary Q.cholesky_hermitian_ndarray— Cholesky for Hermitian positive-definite matrices.eig_hermitian_ndarray— eigendecomposition for Hermitian matrices: real eigenvalues (ascending) with complex eigenvectors, returned as(Array1<T::Real>, Array2<T>). AHermitianEvdResult<T>type is also provided for structured results.
Alongside these, the generic solve and solve_multiple functions in both oxiblas-lapack and oxiblas-ndarray had an over-restrictive Real bound. For Hermitian and unitary structure, a complex matrix is perfectly well-conditioned to factor and solve — so the bound was removed, enabling Complex<f32> and Complex<f64> to use the same solver entry points as f32/f64.
Getting Started
cargo add oxiblas --features ndarray
A Hermitian eigenproblem, straight from Array2:
use ndarray::array;
use num_complex::Complex64;
use oxiblas_ndarray::eig_hermitian_ndarray;
// A 2x2 Hermitian matrix (A == conjugate transpose of A)
let a = array![
[Complex64::new(2.0, 0.0), Complex64::new(0.0, -1.0)],
[Complex64::new(0.0, 1.0), Complex64::new(2.0, 0.0)],
];
// Real eigenvalues (ascending), complex eigenvectors
let (eigenvalues, eigenvectors) = eig_hermitian_ndarray(&a).expect("EVD failed");
println!("eigenvalues = {:?}", eigenvalues); // [1.0, 3.0]
Complex SVD and QR follow the same shape:
use oxiblas_ndarray::{svd_complex_ndarray, qr_complex_ndarray};
let svd = svd_complex_ndarray(&a).expect("SVD failed");
let qr = qr_complex_ndarray(&a).expect("QR failed");
What’s New in 0.1.2
- Complex LAPACK for ndarray —
svd_complex_ndarray(one-sided Jacobi SVD),qr_complex_ndarray(unitary Q),cholesky_hermitian_ndarray(Hermitian positive-definite), andeig_hermitian_ndarray(real eigenvalues, complex eigenvectors), plus theComplexSvdResultandHermitianEvdResultresult types. - Relaxed trait bounds — the unnecessary
Realbound was removed fromsolveandsolve_multiplein bothoxiblas-lapackandoxiblas-ndarray, soComplex<f32>andComplex<f64>are now supported through the generic solver API. - Fixed — minor code-formatting cleanups in the symmetric eigenvalue decomposition tests.
Tips
- Hermitian eigenvalues are real.
eig_hermitian_ndarrayreturns the eigenvalues asArray1<T::Real>in ascending order; only the upper triangle of the input is read, so you don’t need to pre-symmetrize. - Pick the right complex decomposition. Use
cholesky_hermitian_ndarrayfor Hermitian positive-definite systems,eig_hermitian_ndarrayfor the spectrum, andqr_complex_ndarray/svd_complex_ndarrayfor general complex factorizations. - One solver, both domains. With the relaxed bounds,
solveandsolve_multiplenow acceptComplex<f32>/Complex<f64>directly — no separate real and complex code paths in your own generics. - Enable the feature. The complex ndarray functions live behind the
ndarrayfeature, so add--features ndarray(or list it inCargo.toml). - Drop-in patch. 0.1.2 is API-compatible with 0.1.x; bump the version and rebuild.
This is the foundation
OxiBLAS is the pure Rust linear algebra backend of the COOLJAPAN scientific stack, and the ecosystem around it is filling in fast. SciRS2 launched yesterday on top of OxiBLAS, and today brings a wave of siblings — NumRS2 for n-dimensional arrays, OptiRS for optimization, and PandRS for dataframes — all part of the same C/C++/Fortran-free vision alongside earlier projects like VoiRS, TenRSo, TensorLogic, Spintronics, and Oxicode. First-class complex support in the ndarray layer is exactly what those higher-level libraries need to handle signal processing, spectral analysis, and quantum-adjacent workloads.
Repository: https://github.com/cool-japan/oxiblas
Star the repo if you want high-performance scientific computing without the traditional toolchain headaches.
Pure Rust numerical linear algebra is here — fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ December 30, 2025