Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]
## [Released]

## [0.5.0] - 2026-08-03

### Added

- **Lanczos iteration.** `krylov::lanczos` tridiagonalizes a real symmetric matrix over a compile-time-sized Krylov
subspace, returning the projection as a new `TridiagonalMatrix<T, K>` and filling an orthonormal basis. Uses full
reorthogonalization, so the basis stays orthonormal to working precision.
- **Arnoldi iteration.** `krylov::arnoldi` reduces a general, possibly non-symmetric matrix to upper Hessenberg form
over a compile-time-sized Krylov subspace, returning the projection as a new `HessenbergMatrix<T, K>` and filling an
orthonormal basis. Unlike Lanczos, there's no three-term recurrence to exploit, so every step orthogonalizes
(via modified Gram-Schmidt) against the entire basis built so far, not just the two previous vectors.
- **Conjugate Gradient.** `krylov::conjugate_gradient` solves a symmetric positive-definite (SPD) linear system
`A x = b` iteratively, without factorizing `A`, converging in at most `n` steps in exact arithmetic. Detects
non-SPD input operationally — a search direction whose curvature `p · (A p)` isn't positive — rather than assuming
the caller already validated it.
- **GMRES(m), restarted.** `krylov::gmres`, gated behind the `alloc` feature, solves a general (possibly
non-symmetric) linear system `A x = b`: Arnoldi builds an `M`-dimensional Krylov basis from the current residual,
the resulting least-squares problem is solved via Givens rotations, and the cycle restarts from the improved
iterate until the residual meets tolerance or the restart budget runs out. Takes `A` as a `SparseLinearOp` so
restart cycles reuse the same workspace instead of allocating on every application.
- `storage::Basis<T, K>`, a const-generic view over caller-provided memory holding the `K` basis vectors a Krylov
method builds up — the storage-layer piece Arnoldi and GMRES(m) will reuse.
method builds up — the storage-layer piece Arnoldi and GMRES(m) reuse.
- `ConvergenceError::Breakdown`, reported when the Krylov subspace turns out to be invariant before reaching the
requested dimension (e.g. a repeated eigenvalue, or a starting vector inside a small invariant subspace).
requested dimension (e.g. a repeated eigenvalue, or a starting vector inside a small invariant subspace). For
Arnoldi and GMRES specifically, this is instead reported as a successful, smaller-than-requested basis, since the
invariant subspace found is still exact and useful.
- Property tests for `qr`, `cholesky_decompose`, and `svd` that check each decomposition's defining mathematical
invariants directly (orthogonality, triangularity, reconstruction, positive-definiteness) instead of comparing
against nalgebra, so they also cover shapes nalgebra wouldn't be a fair oracle for.
- Edge-case tests for dimension extremes — degenerate `0xn`/`nx0`/`0x0` shapes, the smallest nontrivial shape
(`1x1`), and very rectangular shapes — across the dense decompositions and sparse matrix construction.

## [Released]

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustebra"
version = "0.4.0"
version = "0.5.0"
edition = "2024"
rust-version = "1.85"
license = "Apache-2.0"
Expand All @@ -11,6 +11,17 @@ keywords = ["linear-algebra", "matrix", "vector", "no-std", "numerical"]
categories = ["algorithms", "mathematics", "no-std"]
documentation = "https://docs.rs/rustebra"
readme = "README.md"
exclude = [
".all-contributorsrc",
".claudeignore",
".github/",
"CLAUDE.md",
"CONTEXT.md",
"book.toml",
"docs/",
"sonar-project.properties",
"theme/",
]

[dependencies]

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ A hybrid `no_std`/`alloc` library. Stack-first by default. Scales to sparse matr

## Status

Early development (v0.4.0). Core features implemented: static/dynamic vectors and matrices, matrix decompositions (LU, QR, SVD, Cholesky), sparse matrix support (COO, CSR, CSC), and Krylov eigenvalue solvers (power iteration, inverse power iteration). See
Early development (v0.5.0). Core features implemented: static/dynamic vectors and matrices, matrix decompositions (LU, QR, SVD, Cholesky), sparse matrix support (COO, CSR, CSC), Krylov eigenvalue solvers (power iteration, inverse power iteration, Lanczos, Arnoldi), and Krylov linear solvers (Conjugate Gradient, GMRES(m)). See
[specs](docs/specs/) for architecture details.

## Why this exists
Expand Down Expand Up @@ -75,10 +75,10 @@ constrained environments. rustebra aims to close that gap.
| **Stack-only (no heap required)** | ✅ Default | ❌ No | ✅ For fixed-size |
| **Sparse matrices** | ✅ v0.3.0+ (COO, CSR, CSC) | ❌ Separate `sprs` crate | ⚠️ Limited (optional feature) |
| **GPU/SIMD acceleration** | ❌ Not planned | ⚠️ Limited SIMD | ⚠️ SIMD support available |
| **Krylov solvers** | ✅ v0.4.0+ (power iteration, inverse power iteration) | ⚠️ Via `ndarray-linalg` | ❌ Not in core |
| **Krylov solvers** | ✅ v0.5.0+ (power iteration, inverse power iteration, Lanczos, Arnoldi, CG, GMRES(m)) | ⚠️ Via `ndarray-linalg` | ❌ Not in core |
| **3D math/graphics primitives** | ❌ Not focused | ❌ Not provided | ✅ Excellent (Isometry, Rotation, etc.) |
| **BLAS/LAPACK integration** | ❌ No | ✅ Excellent bindings | ❌ Pure Rust |
| **Maturity & stability** | 🟡 Early (v0.4.0) | ✅ Mature & stable | ✅ Mature & stable |
| **Maturity & stability** | 🟡 Early (v0.5.0) | ✅ Mature & stable | ✅ Mature & stable |
| **Large matrices (100k+)** | ⚠️ With sparse | ✅ Optimized | ⚠️ Fixed-size limits |
| **Embedded systems** | ✅ Best choice | ❌ Poor fit | ⚠️ For fixed-size only |

Expand Down Expand Up @@ -106,10 +106,10 @@ constrained environments. rustebra aims to close that gap.

```toml
[dependencies]
rustebra = "0.4.0"
rustebra = "0.5.0"

# Optional: heap-backed structures and Krylov solvers
rustebra = { version = "0.4.0", features = ["alloc"] }
rustebra = { version = "0.5.0", features = ["alloc"] }
```

Build and test locally:
Expand Down
2 changes: 1 addition & 1 deletion tests/firmware/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading