1use thiserror::Error;
4
5pub type MathResult<T> = Result<T, MathError>;
7
8#[derive(Error, Debug, Clone)]
10pub enum MathError {
11 #[error("Convergence failed after {iterations} iterations (residual: {residual:.2e})")]
13 ConvergenceFailed {
14 iterations: u32,
16 residual: f64,
18 },
19
20 #[error("Invalid bracket: f({a}) = {fa:.2e} and f({b}) = {fb:.2e} have same sign")]
22 InvalidBracket {
23 a: f64,
25 b: f64,
27 fa: f64,
29 fb: f64,
31 },
32
33 #[error("Division by zero or near-zero value: {value:.2e}")]
35 DivisionByZero {
36 value: f64,
38 },
39
40 #[error("Singular matrix: cannot invert")]
42 SingularMatrix,
43
44 #[error("Incompatible matrix dimensions: ({rows1}x{cols1}) and ({rows2}x{cols2})")]
46 DimensionMismatch {
47 rows1: usize,
49 cols1: usize,
51 rows2: usize,
53 cols2: usize,
55 },
56
57 #[error("Extrapolation not allowed: {x} is outside [{min}, {max}]")]
59 ExtrapolationNotAllowed {
60 x: f64,
62 min: f64,
64 max: f64,
66 },
67
68 #[error("Insufficient data: need at least {required}, got {actual}")]
70 InsufficientData {
71 required: usize,
73 actual: usize,
75 },
76
77 #[error("Invalid input: {reason}")]
79 InvalidInput {
80 reason: String,
82 },
83
84 #[error("Numerical overflow in {operation}")]
86 Overflow {
87 operation: String,
89 },
90
91 #[error("Numerical underflow in {operation}")]
93 Underflow {
94 operation: String,
96 },
97}
98
99impl MathError {
100 #[must_use]
102 pub fn convergence_failed(iterations: u32, residual: f64) -> Self {
103 Self::ConvergenceFailed {
104 iterations,
105 residual,
106 }
107 }
108
109 #[must_use]
111 pub fn invalid_input(reason: impl Into<String>) -> Self {
112 Self::InvalidInput {
113 reason: reason.into(),
114 }
115 }
116
117 #[must_use]
119 pub fn insufficient_data(required: usize, actual: usize) -> Self {
120 Self::InsufficientData { required, actual }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_error_display() {
130 let err = MathError::convergence_failed(100, 1e-6);
131 assert!(err.to_string().contains("100 iterations"));
132 }
133}