Skip to main content

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}