pub fn polynomial_determinant<const D: usize>(
matrix: &[[SparsePolynomial; D]; D],
budget: PolynomialDeterminantBudget,
) -> Result<SparsePolynomial, LaError>exact only.Expand description
Compute the complete exact determinant polynomial of a borrowed square array.
Supports orders 0..=8; the empty determinant is the constant one. Singular
polynomial matrices return the zero polynomial successfully. All cancellation
terms are retained, so SparsePolynomial::leading_term is valid only after
the complete calculation succeeds. There is no early sign fallback, truncation,
division, rounding or conditioning-dependent numerical error.
The kernel allocates 2^D sparse states (at most 256) and consumes each partial
once all its predecessors have contributed. Inputs are neither cloned nor
changed. At most one new stored term is created per charged product, plus the
initial constant one. Rational sizes, allocator overhead, and caller-owned
inputs are outside these combinatorial bounds; allocation failure follows
Rust’s allocator behavior. Limits do not promise a byte or wall-clock bound.
§Errors
In order: LaError::UnsupportedDimension for D > 8,
LaError::PolynomialBudgetExceeded for insufficient structural transitions,
then product-budget or LaError::PolynomialExponentOverflow failures during
evaluation. An overflowing intermediate exponent is an error even if later
contributions could cancel it. Errors discard partial results and leave the
input reusable. Traversal is increasing subset mask, column, left exponent,
then right exponent, making budget accounting deterministic.
§Examples
use la_stack::prelude::*;
let one = SparsePolynomial::try_from_terms([(0, BigRational::from_integer(1.into()))])?;
let perturbed = SparsePolynomial::try_from_terms([
(0, BigRational::from_integer(1.into())),
(3, BigRational::new(1.into(), 2.into())),
])?;
let matrix = [[one.clone(), one.clone()], [one, perturbed]];
let determinant = polynomial_determinant(&matrix, PolynomialDeterminantBudget {
max_subset_transitions: 4,
max_term_products: 5,
})?;
assert_eq!(determinant.leading_term(), Some((3, &BigRational::new(1.into(), 2.into()))));