Expand description
Worked examples and contracts for choosing and combining APIs.
Start with prelude for common imports. The crate’s
generated reference lists the complete public surface; these examples
demonstrate how the pieces fit together.
Explore the topic guides for more workflows:
- LDLT determinants and symmetry
- Compile-time determinants
- Outward-rounded interval determinants
- Overflow-safe Euclidean norms
- Certified dot products and affine differences
- Adaptive determinant filtering
Enabling exact also adds the exact-arithmetic guide to the module list.
§Solving and reusing factors
Matrix::lu computes a partially pivoted
factorization. Keep the resulting Lu to solve multiple
right-hand sides without repeating factorization. This 5×5 system has a
zero leading entry, so the first elimination step requires pivoting.
use la_stack::prelude::*;
let a = Matrix::<5>::try_from_rows([
[0.0, 2.0, -1.0, 1.0, 3.0],
[4.0, -1.0, 2.0, 0.0, 1.0],
[1.0, 3.0, 5.0, -2.0, 0.0],
[2.0, 0.0, -1.0, 4.0, 1.0],
[-1.0, 2.0, 0.0, 1.0, 6.0],
])?;
let lu = a.lu(DEFAULT_SINGULAR_TOL)?;
let systems = [
([20.0, 13.0, 14.0, 20.0, 37.0], [1.0, 2.0, 3.0, 4.0, 5.0]),
([5.0, 6.0, 7.0, 6.0, 8.0], [1.0; 5]),
];
for (rhs, expected) in systems {
let solution = lu.solve(Vector::try_new(rhs)?)?;
for (&actual, expected) in solution.as_array().iter().zip(expected) {
assert!((actual - expected).abs() <= 1e-12);
}
}The assertions use a tolerance suitable for this known fixture; they do
not establish a general error bound for LU. Factorization tolerances
reject small pivots and are not accuracy guarantees.
Ldlt offers the same solve/determinant workflow for
exactly symmetric positive-definite input, without pivoting. Approximate
symmetry from Matrix::is_symmetric or
Matrix::first_asymmetry does not prove
the exact symmetry required by Matrix::ldlt.
§Gram matrices
gram_matrix accepts M vectors of dimension N
and returns a Matrix<M> of pairwise inner products. Here five vectors
in six dimensions produce a 5×5 matrix. Each dot product is computed once
and mirrored, so the result is bit-for-bit symmetric.
use la_stack::prelude::*;
let vectors = [
Vector::try_new([1.0, 1.0, 0.0, 0.0, 0.0, 0.0])?,
Vector::try_new([0.0, 1.0, 1.0, 0.0, 0.0, 0.0])?,
Vector::try_new([0.0, 0.0, 1.0, 1.0, 0.0, 0.0])?,
Vector::try_new([0.0, 0.0, 0.0, 1.0, 1.0, 0.0])?,
Vector::try_new([0.0, 0.0, 0.0, 0.0, 1.0, 1.0])?,
];
let gram = gram_matrix(&vectors)?;
assert_eq!(gram.norm_inf()?, 4.0);
assert!(gram.is_symmetric(Tolerance::try_new(0.0)?)?);
// This fixture's exact Gram matrix is tridiagonal: 2 on the diagonal,
// 1 immediately above/below it. Its 5×5 determinant is 6.
let determinant = gram.ldlt(DEFAULT_SINGULAR_TOL)?.det()?;
assert!((determinant - 6.0).abs() <= 1e-12);Gram construction provides no certified rounding-error bound and does not prove rank or positive definiteness. The generated function documentation explains its conditioning and geometric interpretation.
§Dimension dispatch
try_with_stack_matrix! selects a
concrete Matrix<N> for runtime dimensions 0 through
MAX_STACK_MATRIX_DISPATCH_DIM
(7). The closure receives a zero matrix and returns its declared result.
use core::assert_matches;
use la_stack::prelude::*;
let requested = 5usize;
let determinant = try_with_stack_matrix!(requested, |mut matrix| -> Result<f64, LaError> {
for row in 0..requested {
matrix.set(row, row, 2.0)?;
if row + 1 < requested {
matrix.set(row, row + 1, 1.0)?;
matrix.set(row + 1, row, 1.0)?;
}
}
matrix.det()
})?;
assert!((determinant - 6.0).abs() <= 1e-12);
let unsupported = try_with_stack_matrix!(8, |matrix| -> Result<f64, LaError> {
matrix.det()
});
assert_matches!(
unsupported,
Err(LaError::UnsupportedDimension { requested: 8, max: 7, .. })
);try_with_interval_matrix! similarly
dispatches dimensions 0 through
MAX_INTERVAL_MATRIX_DIM (7) to an
IntervalMatrix. These macros are useful when
stable Rust cannot express a derived const dimension such as D + 1.
Larger dimensions produce LaError::UnsupportedDimension,
converted through From<LaError> into the closure’s declared error type.
Dispatch preserves const-generic storage; it does not create a dynamically
sized matrix representation or limit dimensions chosen directly at compile time.
§Storage, access, and errors
Matrix<D> and Vector<D> store
[[f64; D]; D] and [f64; D] inline. Constructors validate non-finite
inputs, and the types preserve that finite-storage invariant. Factorization
kernels therefore avoid a repeated O(D²) input scan; computed factor
matrices are still checked before becoming observable results.
Matrix::as_rows and
Vector::as_array borrow validated backing
arrays. Matrix::into_rows and
Vector::into_array consume the value and
return owned fixed-size arrays.
Matrix::get returns None for invalid coordinates;
Matrix::try_get preserves them in a typed error.
Matrix::set checks coordinates and finiteness
before mutation. Matrix::norm_inf computes
the maximum absolute row sum.
Vector::dot, Vector::norm,
and Vector::norm_squared provide ordinary
vector reductions. ScalarWithErrorBound
is the opaque result of the certified dot and affine-difference methods;
it exposes the estimate, absolute bound, and outward-rounded endpoints.
DeterminantWithErrorBound pairs a
direct determinant with its certified absolute bound. Use
Matrix::det_errbound for the bound alone.
Interval stores two finite ordered bounds and supports
point construction, outward-rounded subtraction, addition, multiplication,
negation, and square. IntervalMatrix stores
[[Interval; D]; D] inline and uses a fixed 128-entry stack workspace for
supported determinant dimensions. IntervalDeterminantSign
distinguishes positive, negative, exact zero, and inconclusive evidence.
Parse numerical thresholds through Tolerance::try_new.
LaError and its reason/location enums are non-exhaustive;
use wildcard match arms and .. for struct-style variants. In particular:
SingularityReasonseparates exact singularity from numerical rejection, retaining theFactorizationKind, observed pivot magnitude, and tolerance for the latter.NonFiniteOrigin,NonFiniteLocation, andArithmeticOperationdistinguish invalid inputs from computed non-finite values.LaError::InvertedIntervalpreserves rejected finite endpoints;LaError::IntervalRangeExhausteddistinguishes finite-input interval range loss from a non-finite value.InvalidToleranceReasondistinguishes negative and non-finite tolerances.PositiveSemidefiniteViolationdistinguishes a negative LDLT pivot from a zero pivot with nonzero coupling.
Modules§
- adaptive
- Adaptive determinant filtering with certified bounds.
- certified
- Certified dot products and affine differences.
- compile_
time - Compile-time determinants and dimension dispatch.
- exact
exact - Exact arithmetic over stored binary64 and rational inputs.
- intervals
- Outward-rounded interval expressions and determinant signs.
- ldlt
- LDLT determinants and exact symmetry.
- norms
- Overflow-safe Euclidean norms and squared norms.