Skip to main content

ruvector_solver/
error.rs

1//! Error types for the solver crate.
2//!
3//! Provides structured error variants for convergence failures, numerical
4//! instabilities, budget overruns, and invalid inputs. All errors implement
5//! `std::error::Error` via `thiserror`.
6
7use std::time::Duration;
8
9use crate::types::Algorithm;
10
11/// Primary error type for solver operations.
12#[derive(Debug, thiserror::Error)]
13pub enum SolverError {
14    /// The iterative solver did not converge within the allowed iteration budget.
15    #[error(
16        "solver did not converge after {iterations} iterations (residual={residual:.2e}, tol={tolerance:.2e})"
17    )]
18    NonConvergence {
19        /// Number of iterations completed before the budget was exhausted.
20        iterations: usize,
21        /// Final residual norm at termination.
22        residual: f64,
23        /// Target tolerance that was not reached.
24        tolerance: f64,
25    },
26
27    /// A numerical instability was detected (NaN, Inf, or loss of precision).
28    #[error("numerical instability at iteration {iteration}: {detail}")]
29    NumericalInstability {
30        /// Iteration at which the instability was detected.
31        iteration: usize,
32        /// Human-readable explanation.
33        detail: String,
34    },
35
36    /// The compute budget (wall-time, iterations, or memory) was exhausted.
37    #[error("compute budget exhausted: {reason}")]
38    BudgetExhausted {
39        /// Which budget limit was hit.
40        reason: String,
41        /// Wall-clock time elapsed before the budget was hit.
42        elapsed: Duration,
43    },
44
45    /// The caller supplied invalid input (dimensions, parameters, etc.).
46    #[error("invalid input: {0}")]
47    InvalidInput(#[from] ValidationError),
48
49    /// The matrix spectral radius exceeds the threshold required by the algorithm.
50    #[error(
51        "spectral radius {spectral_radius:.4} exceeds limit {limit:.4} for algorithm {algorithm}"
52    )]
53    SpectralRadiusExceeded {
54        /// Estimated spectral radius of the iteration matrix.
55        spectral_radius: f64,
56        /// Maximum spectral radius the algorithm tolerates.
57        limit: f64,
58        /// Algorithm that detected the violation.
59        algorithm: Algorithm,
60    },
61
62    /// A backend-specific error (e.g. nalgebra or BLAS).
63    #[error("backend error: {0}")]
64    BackendError(String),
65}
66
67/// Validation errors for solver inputs.
68///
69/// These are raised eagerly before any computation begins so that callers get
70/// clear diagnostics rather than mysterious numerical failures.
71#[derive(Debug, thiserror::Error)]
72pub enum ValidationError {
73    /// Matrix dimensions are inconsistent (e.g. row_ptrs length vs rows).
74    #[error("dimension mismatch: {0}")]
75    DimensionMismatch(String),
76
77    /// A value is NaN or infinite where a finite number is required.
78    #[error("non-finite value detected: {0}")]
79    NonFiniteValue(String),
80
81    /// A column index is out of bounds for the declared number of columns.
82    #[error("column index {index} out of bounds for {cols} columns (row {row})")]
83    IndexOutOfBounds {
84        /// Offending column index.
85        index: u32,
86        /// Row containing the offending entry.
87        row: usize,
88        /// Declared column count.
89        cols: usize,
90    },
91
92    /// The `row_ptrs` array is not monotonically non-decreasing.
93    #[error("row_ptrs is not monotonically non-decreasing at position {position}")]
94    NonMonotonicRowPtrs {
95        /// Position in `row_ptrs` where the violation was detected.
96        position: usize,
97    },
98
99    /// A parameter is outside its valid range.
100    #[error("parameter out of range: {name} = {value} (expected {expected})")]
101    ParameterOutOfRange {
102        /// Name of the parameter.
103        name: String,
104        /// The invalid value (as a string for flexibility).
105        value: String,
106        /// Human-readable description of the valid range.
107        expected: String,
108    },
109
110    /// Matrix size exceeds the implementation limit.
111    #[error("matrix size {rows}x{cols} exceeds maximum supported {max_dim}x{max_dim}")]
112    MatrixTooLarge {
113        /// Number of rows.
114        rows: usize,
115        /// Number of columns.
116        cols: usize,
117        /// Maximum supported dimension.
118        max_dim: usize,
119    },
120}