gam_models/survival/marginal_slope/error.rs
1//! Error and preflight-block enums for survival marginal-slope fitting,
2//! with their `Display`/`Error`/`From` conversions. Self-contained: no
3//! dependency on the fitting machinery.
4
5#[derive(Debug, Clone)]
6pub enum SurvivalMarginalSlopeError {
7 /// Spec, data, or runtime configuration failed input validation
8 /// (finite/non-negative weights, derivative_guard > 0, supported
9 /// base_link, frailty constraints, missing block state, etc.).
10 InvalidInput { reason: String },
11 /// Lengths, row/column counts, basis widths, or coefficient block
12 /// sizes do not agree (covariance dim vs z, design rows vs n,
13 /// basis/beta length mismatch, post-update beta length, time
14 /// constraints A vs b, hessian_matvec dim mismatch, ...).
15 IncompatibleDimensions { reason: String },
16 /// A row's transformed time derivative or structural slack fell
17 /// below `derivative_guard` (`qd1 < guard`), violating the
18 /// monotonicity contract.
19 MonotonicityViolation { reason: String },
20 /// A numerical step produced a non-finite, non-positive, or
21 /// internally inconsistent quantity that downstream code cannot
22 /// consume (e.g. non-positive `D`, non-positive `chi1`, calibration
23 /// derivative disagrees with the direct evaluation, transformed
24 /// derivative not strictly positive).
25 NumericalFailure { reason: String },
26 /// An integration / outer-optimization step failed to converge to
27 /// the requested tolerance (intercept residual, REML outer loop).
28 IntegrationFailed { reason: String },
29 /// The requested combination of options is not implemented (non-
30 /// probit base link, flexible row calculus with K > 1, spatial psi
31 /// for unsupported block roles, ...).
32 UnsupportedConfiguration { reason: String },
33}
34
35/// Block tag used by the joint training-row preflight diagnostic.
36/// Names a single block in the joint design layout
37/// `[time | marginal | logslope | score_warp? | link_dev?]`.
38#[derive(Copy, Clone, Debug, PartialEq, Eq)]
39pub enum JointPreflightBlock {
40 Time,
41 Marginal,
42 Logslope,
43 ScoreWarp,
44 LinkDev,
45}
46
47impl std::fmt::Display for JointPreflightBlock {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 let name = match self {
50 JointPreflightBlock::Time => "time",
51 JointPreflightBlock::Marginal => "marginal",
52 JointPreflightBlock::Logslope => "logslope",
53 JointPreflightBlock::ScoreWarp => "score_warp",
54 JointPreflightBlock::LinkDev => "link_dev",
55 };
56 f.write_str(name)
57 }
58}
59
60impl_reason_error_boilerplate! {
61 SurvivalMarginalSlopeError {
62 InvalidInput,
63 IncompatibleDimensions,
64 MonotonicityViolation,
65 NumericalFailure,
66 IntegrationFailed,
67 UnsupportedConfiguration,
68 }
69}
70
71impl From<String> for SurvivalMarginalSlopeError {
72 /// Inbound conversion from helpers in this module (and adjacent
73 /// families) that still surface `Result<_, String>`. The text is
74 /// preserved verbatim; `InvalidInput` is the catch-all category for
75 /// strings produced outside this module.
76 fn from(reason: String) -> SurvivalMarginalSlopeError {
77 SurvivalMarginalSlopeError::InvalidInput { reason }
78 }
79}