# Hybrid Memory Allocation Strategy
## Summary
The library is built around two tiers of memory use: a strict, allocation-free core that
is the default build, and an optional feature flag that unlocks heap-backed dynamic data
structures and algorithms for callers who have an allocator available.
## Scope
Applies to every data layout and elementary operation in the crate. The baseline tier
covers fixed-size vectors, buffers, and matrices whose dimensions are known at compile
time. The optional tier covers growable, `Vec`-backed matrices and vectors, and any
algorithm whose workspace size cannot be known until runtime — sparse matrix formats and
iterative solvers being the primary examples.
## Decision
By default, the crate builds against no allocator at all. Baseline types use const
generics (`<const N: usize>`) to fix the size of every vector, buffer, and matrix at
compile time, and live entirely on the stack.
A single conditional-compilation feature unlocks a second tier: dynamic, `Vec`-backed
data structures and the algorithms that need a workspace whose size depends on runtime
input rather than a compile-time constant. Enabling this feature is opt-in and additive —
it does not change the behavior or requirements of the baseline tier.
Static (compile-time-sized) and dynamic (heap-backed) types are kept as distinct, separate
type families rather than unified behind one shared public API. How much internal
behavior the two families share at the implementation level is treated as its own,
separate design question, not settled by this decision.
## Constraints
- The baseline build must run unmodified on microcontrollers with only a few kilobytes of
RAM and no global memory allocator — this is the floor the strict tier is designed
against, not an aspirational target.
- In the baseline tier, internal memory overflow and heap-fragmentation failures must be
impossible by construction (no allocator exists to fragment or exhaust), not merely
avoided by discipline or testing.
- Baseline, stack-allocated operations must have deterministic, bounded latency, with no
allocator-dependent jitter — this rules out any hidden heap use inside the default
build.
- Some algorithms — sparse matrix multiplication and iterative solvers among them —
fundamentally need a workspace whose size is not known until runtime; a purely
stack-only design cannot express them, which is why the optional tier exists rather
than trying to force every algorithm into the const-generic model.
## Status
Implemented (Revised). The baseline crate remains allocator-free with const-generic,
stack-only storage; the optional feature gates every `Vec`-backed dynamic type and every
workspace-heavy algorithm. The accepted trade-offs are additional signature complexity in
the baseline tier from const generics, and the maintenance of static and dynamic types as
two separate, non-unified families.