rustebra
Linear algebra for embedded systems, microcontrollers, and real-time applications.
A hybrid no_std/alloc library. Stack-first by default. Scales to sparse matrices and Krylov subspace solvers when a heap is available.
Documentation · API Reference · Design Decisions · Contributing
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 design decisions for architecture details.
Why this exists
Embedded systems, microcontrollers, and real-time applications need linear algebra without
assuming a heap. Rust currently lacks a library that is simultaneously serious about no_std
support and complete enough to cover sparse matrices and iterative solvers. Existing options
either assume a heap is always available or only provide a partial set of operations for
constrained environments. rustebra aims to close that gap.
Design principles
- No allocator required by default. The core of the library works entirely on the stack, using const generics to fix sizes at compile time.
- Allocation is opt-in. Dynamic, heap-backed data structures and algorithms are available
behind the
allocfeature flag, for use in environments with an operating system. - Generic over numeric precision. Operations are written to work with different floating-point types, reflecting the range of hardware this library targets — from microcontrollers without double-precision floating-point units to desktop and server systems.
- Explicit error handling. Recoverable failures are reported through
Result, not panics, since an uncontrolled abort is often unacceptable in embedded contexts.
When to use rustebra
- Embedded systems (ARM Cortex-M, RISC-V) where allocation is unavailable
- Real-time systems that need predictable stack-only memory
- Microcontrollers with tight RAM (STM32, nRF, etc.)
- Edge devices (Raspberry Pi Zero)
- Any system needing linear algebra without dynamic allocators
When NOT to use rustebra
- Desktop/server apps with heap → use ndarray
- Graphics/game engines → use nalgebra
- Systems where allocation is not a constraint
- Need LAPACK-level routines → ndarray
How rustebra compares
| Feature | rustebra | ndarray | nalgebra |
|---|---|---|---|
| no_std support | ✅ Full | ⚠️ Optional (std feature can be disabled) | ⚠️ Optional (requires feature flags) |
| 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 |
| 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 |
| Large matrices (100k+) | ⚠️ With sparse | ✅ Optimized | ⚠️ Fixed-size limits |
| Embedded systems | ✅ Best choice | ❌ Poor fit | ⚠️ For fixed-size only |
When to use each
rustebra — Use if:
- You need linear algebra without dynamic allocation (embedded, real-time, microcontroller)
- You're working with sparse matrices in an embedded context
- You want no_std + optional alloc (best of both worlds for OS environments)
- Predictable stack-only memory is a requirement
ndarray — Use if:
- You need production-strength BLAS/LAPACK routines (scientific computing, data science)
- You're comfortable with heap allocation and want optimal performance
- You need large matrices with sophisticated solvers and decompositions
- Building NumPy-like workflows in Rust
nalgebra — Use if:
- You need 3D graphics, robotics, or game engine math (Points, Isometries, Rotations)
- You want optional no_std support with fixed-size matrices
- Building low-level geometric transformations
- Working with transformation matrices up to ~6×6
Usage
[]
= "0.4.0"
# Optional: heap-backed structures and Krylov solvers
= { = "0.4.0", = ["alloc"] }
Build and test locally:
# no_std build (default)
# with alloc feature
Running Examples
Host Examples
Run any of the host examples with:
# Requires alloc feature (uses dynamic sparse matrices)
Firmware Examples
For bare-metal embedded targets, see the tests/firmware/ workspace. This keeps device-specific dependencies isolated from the main library.
ARM Cortex-M3 (via QEMU):
The binary will be at target/thumbv7m-none-eabi/release/cortex-m3-lm3s6965evb.
To run in QEMU, you need qemu-system-arm installed and in your PATH:
The firmware workspace includes:
- Linker scripts for memory layout
- Panic handlers for no_std environments
- Semihosting I/O for debugging
- Stack-only operation (no heap allocation)
Documentation
- API reference — generated from
cargo doc, hosted on GitHub Pages. - Design decisions — records of the key design choices made during development.
- GitHub Pages site — full project documentation.
To generate and browse the API docs locally:
Contributing
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request.
Contributors
Want to appear here? See CONTRIBUTING.md.
License
Licensed under the Apache License 2.0.