1use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
41
42use crate::iterative::IterativeError;
43use crate::jacobian::JacobianError;
44use crate::optimization::OptimizationError;
45use crate::pca::PCAError;
46use crate::regression::RegressionError;
47use crate::stats::StatsError;
48
49pub mod iterative;
50pub mod jacobian;
51pub mod optimization;
52pub mod pca;
53pub mod regression;
54pub mod stats;
55
56impl IntoNabledError for IterativeError {
57 fn into_nabled_error(self) -> NabledError {
58 match self {
59 IterativeError::EmptyMatrix => NabledError::Shape(ShapeError::EmptyInput),
60 IterativeError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
61 IterativeError::MaxIterationsExceeded | IterativeError::Breakdown => {
62 NabledError::ConvergenceFailed
63 }
64 IterativeError::NotPositiveDefinite => NabledError::NotPositiveDefinite,
65 }
66 }
67}
68
69impl IntoNabledError for JacobianError {
70 fn into_nabled_error(self) -> NabledError {
71 match self {
72 JacobianError::FunctionError(message) => {
73 NabledError::Other(format!("function error: {message}"))
74 }
75 JacobianError::InvalidDimensions(message) => NabledError::InvalidInput(message),
76 JacobianError::InvalidStepSize => {
77 NabledError::InvalidInput("invalid step size".to_string())
78 }
79 JacobianError::ConvergenceFailed => NabledError::ConvergenceFailed,
80 JacobianError::EmptyInput => NabledError::Shape(ShapeError::EmptyInput),
81 JacobianError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
82 }
83 }
84}
85
86impl IntoNabledError for OptimizationError {
87 fn into_nabled_error(self) -> NabledError {
88 match self {
89 OptimizationError::EmptyInput => NabledError::Shape(ShapeError::EmptyInput),
90 OptimizationError::DimensionMismatch => {
91 NabledError::Shape(ShapeError::DimensionMismatch)
92 }
93 OptimizationError::NonFiniteInput => NabledError::NumericalInstability,
94 OptimizationError::InvalidConfig => {
95 NabledError::InvalidInput("invalid optimizer configuration".to_string())
96 }
97 OptimizationError::MaxIterationsExceeded => NabledError::ConvergenceFailed,
98 }
99 }
100}
101
102impl IntoNabledError for PCAError {
103 fn into_nabled_error(self) -> NabledError {
104 match self {
105 PCAError::EmptyMatrix => NabledError::Shape(ShapeError::EmptyInput),
106 PCAError::InvalidInput(message) => NabledError::InvalidInput(message),
107 PCAError::DecompositionFailed => NabledError::ConvergenceFailed,
108 }
109 }
110}
111
112impl IntoNabledError for RegressionError {
113 fn into_nabled_error(self) -> NabledError {
114 match self {
115 RegressionError::EmptyInput => NabledError::Shape(ShapeError::EmptyInput),
116 RegressionError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
117 RegressionError::Singular => NabledError::SingularMatrix,
118 RegressionError::InvalidInput(message) => NabledError::InvalidInput(message),
119 }
120 }
121}
122
123impl IntoNabledError for StatsError {
124 fn into_nabled_error(self) -> NabledError {
125 match self {
126 StatsError::EmptyMatrix => NabledError::Shape(ShapeError::EmptyInput),
127 StatsError::InsufficientSamples => {
128 NabledError::InvalidInput("at least two observations are required".to_string())
129 }
130 StatsError::InvalidInput(message) => NabledError::InvalidInput(message),
131 StatsError::NumericalInstability => NabledError::NumericalInstability,
132 }
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
139
140 use super::*;
141
142 #[test]
143 fn ml_errors_map_to_shared_taxonomy() {
144 assert!(matches!(
145 IterativeError::EmptyMatrix.into_nabled_error(),
146 NabledError::Shape(ShapeError::EmptyInput)
147 ));
148 assert!(matches!(
149 IterativeError::DimensionMismatch.into_nabled_error(),
150 NabledError::Shape(ShapeError::DimensionMismatch)
151 ));
152 assert!(matches!(
153 IterativeError::MaxIterationsExceeded.into_nabled_error(),
154 NabledError::ConvergenceFailed
155 ));
156 assert!(matches!(
157 IterativeError::Breakdown.into_nabled_error(),
158 NabledError::ConvergenceFailed
159 ));
160 assert!(matches!(
161 IterativeError::NotPositiveDefinite.into_nabled_error(),
162 NabledError::NotPositiveDefinite
163 ));
164
165 assert!(matches!(
166 JacobianError::FunctionError("x".to_string()).into_nabled_error(),
167 NabledError::Other(_)
168 ));
169 assert!(matches!(
170 JacobianError::InvalidDimensions("x".to_string()).into_nabled_error(),
171 NabledError::InvalidInput(_)
172 ));
173 assert!(matches!(
174 JacobianError::InvalidStepSize.into_nabled_error(),
175 NabledError::InvalidInput(_)
176 ));
177 assert!(matches!(
178 JacobianError::ConvergenceFailed.into_nabled_error(),
179 NabledError::ConvergenceFailed
180 ));
181 assert!(matches!(
182 JacobianError::EmptyInput.into_nabled_error(),
183 NabledError::Shape(ShapeError::EmptyInput)
184 ));
185 assert!(matches!(
186 JacobianError::DimensionMismatch.into_nabled_error(),
187 NabledError::Shape(ShapeError::DimensionMismatch)
188 ));
189
190 assert!(matches!(
191 OptimizationError::NonFiniteInput.into_nabled_error(),
192 NabledError::NumericalInstability
193 ));
194 assert!(matches!(
195 OptimizationError::InvalidConfig.into_nabled_error(),
196 NabledError::InvalidInput(_)
197 ));
198 assert!(matches!(
199 OptimizationError::MaxIterationsExceeded.into_nabled_error(),
200 NabledError::ConvergenceFailed
201 ));
202
203 assert!(matches!(
204 PCAError::DecompositionFailed.into_nabled_error(),
205 NabledError::ConvergenceFailed
206 ));
207 assert!(matches!(
208 PCAError::InvalidInput("x".to_string()).into_nabled_error(),
209 NabledError::InvalidInput(_)
210 ));
211
212 assert!(matches!(
213 RegressionError::Singular.into_nabled_error(),
214 NabledError::SingularMatrix
215 ));
216
217 assert!(matches!(
218 StatsError::EmptyMatrix.into_nabled_error(),
219 NabledError::Shape(ShapeError::EmptyInput)
220 ));
221 assert!(matches!(
222 StatsError::InsufficientSamples.into_nabled_error(),
223 NabledError::InvalidInput(_)
224 ));
225 assert!(matches!(
226 StatsError::NumericalInstability.into_nabled_error(),
227 NabledError::NumericalInstability
228 ));
229 }
230}