Skip to main content

CustomFamilyError

Enum CustomFamilyError 

Source
pub enum CustomFamilyError {
    InvalidInput {
        context: &'static str,
        reason: String,
    },
    Optimization {
        context: &'static str,
        reason: String,
    },
    DimensionMismatch {
        reason: String,
    },
    NumericalFailure {
        reason: String,
    },
    ConstraintViolation {
        reason: String,
    },
    UnsupportedConfiguration {
        reason: String,
    },
    InnerSolveNotConverged {
        cycles: usize,
        terminal: Option<InnerConvergenceTerminalState>,
        kkt_residual: Option<f64>,
        kkt_tol: Option<f64>,
        theta_dim: usize,
        rho_dim: usize,
        psi_dim: usize,
    },
    BasisDecompositionFailed {
        reason: String,
    },
    IdentifiabilityFailure {
        audit: IdentifiabilityAudit,
    },
    MapUniquenessFailure {
        error: MapUniquenessError,
    },
    TrialPointRefused {
        reason: String,
    },
}

Variants§

§

InvalidInput

Fields

§context: &'static str
§reason: String
§

Optimization

Fields

§context: &'static str
§reason: String
§

DimensionMismatch

Fields

§reason: String
§

NumericalFailure

Fields

§reason: String
§

ConstraintViolation

Fields

§reason: String
§

UnsupportedConfiguration

Fields

§reason: String
§

InnerSolveNotConverged

The inner solve did not reach its KKT condition at THIS trial point, so the analytic outer gradient/Hessian cannot be exposed (they require F_beta(beta, theta) = 0).

This is a statement about one theta, not about the problem: the outer search should treat the trial as infeasible, back off, and continue. It previously travelled as UnsupportedConfiguration — a variant that means the configuration is structurally unsupported, i.e. fatal — with the real distinction encoded only in the message text. Downstream then had to recover it by substring-matching that text, and two call sites reached opposite verdicts on the same error (#2553). Choosing the variant that says what happened removes the need to guess.

Fields

§cycles: usize
§terminal: Option<InnerConvergenceTerminalState>

The decision variables the inner loop’s verdict was taken on. See InnerConvergenceTerminalState — a cycle count alone cannot say which conjunct of the convergence test failed.

§kkt_residual: Option<f64>

Sup-norm of the projected KKT residual at the terminal inner iterate, i.e. the quantity this refusal was decided against. A cycle count alone cannot distinguish a solve that ran out of budget one order from its tolerance — where the budget is the thing to look at — from one sitting many orders away, which is a stalled or diverging solve and a different defect entirely. None when the producing solver path emits no typed KKT diagnostic (blockwise NR fallback, eager-stop), which is itself worth seeing in the refusal.

§kkt_tol: Option<f64>

The stationarity tolerance kkt_residual was compared against.

§theta_dim: usize
§rho_dim: usize
§psi_dim: usize
§

BasisDecompositionFailed

Fields

§reason: String
§

IdentifiabilityFailure

Pre-fit cross-block identifiability audit refused the fit. The joint design across ParameterBlockSpecs carries a rank deficiency that the post-joint_null_rotation absorption did not resolve: two or more blocks contribute the same direction, or a structural >2-way alias was detected without per-pair attribution. The full IdentifiabilityAudit is held so consumers (logs, structured-error sinks, the seed driver’s classifier) can extract the alias pairs and the summary string without reparsing.

§

MapUniquenessFailure

MAP estimate uniqueness condition ker(J^T W J) ∩ ker(S) = {0} is violated. A null direction of J^T W J carries zero penalty curvature, so the posterior is flat along that direction and the MAP is non-unique. The structured MapUniquenessError names the dominant block so the caller can add the missing penalty or remove the unpenalised direction.

§

TrialPointRefused

A numerical verdict the inner solve reached AT ONE TRIAL POINT: no Laplace mode here, this active face’s curvature refuses certification here, this quadratic subproblem is degenerate here.

Like Self::InnerSolveNotConverged this is a statement about one theta, not about the problem — an indefinite coefficient point at one rho is an ordinary Laplace mode at another — so the outer search should reject the trial and step away, which is what the inner solver’s own logs say should happen. It is a separate variant because InnerSolveNotConverged carries a fixed cycles/theta_dim/rho_dim/psi_dim shape and a message specifically about refusing to expose profile derivatives; reusing it for a curvature refusal would state something untrue.

Fields

§reason: String

Implementations§

Source§

impl CustomFamilyError

Source

pub fn trial_point(reason: impl Into<String>) -> CustomFamilyError

A numerical refusal raised while evaluating at one trial point.

The named constructor exists so a boundary that knows it is reporting a rho-local failure can say so, rather than leaning on the blanket From<String> below and hoping its default is right.

Source

pub fn into_trial_point(self) -> CustomFamilyError

Grade an already-typed error rho-local WITHOUT re-wrapping one that already says so.

A boundary whose whole contract is “evaluate at this rho” answers the trial-point question for everything that crosses it (see the From<String> rationale below and gam#2590). Doing that with Self::trial_point on a value that is already a Self::TrialPointRefused renders the inner error to text and prefixes it a second time, which is how

inner solve refused this trial point: inner solve refused this trial
  point: synthetic outer objective failure: block[0] evaluate()

reached a user (gam#2667). The doubled prefix was cosmetic; the loss it made visible is not, because rendering to String discards the variant and only From<String>’s default put a classification back.

So: keep the error untouched when it already answers the question (is_trial_point_infeasible()), and only render one that does not – which is the single case where the classification is genuinely being changed rather than restated.

Source§

impl CustomFamilyError

Source

pub fn is_trial_point_infeasible(&self) -> bool

Whether a failure of this kind invalidates the whole outer run or only the trial point it was produced at.

The producer’s judgement, made once against the variant. It replaces a downstream substring match on the rendered message that classified one variant two different ways depending on which call site it crossed (#2553).

The match is deliberately exhaustive with no wildcard arm: a new variant must be classified when it is added, rather than defaulting to whichever answer happens to be listed last.

Trait Implementations§

Source§

impl Clone for CustomFamilyError

Source§

fn clone(&self) -> CustomFamilyError

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CustomFamilyError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for CustomFamilyError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for CustomFamilyError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<CustomFamilyError> for EstimationError

Source§

fn from(source: CustomFamilyError) -> EstimationError

Converts to this type from the input type.
Source§

impl From<String> for CustomFamilyError

Source§

fn from(value: String) -> CustomFamilyError

§Why this lands on TrialPointRefused and not InvalidInput

A String cannot carry the one bit the outer smoothing search needs — is this failure a property of the trial point, or of the problem? — so any conversion from it must answer by default. This one used to answer InvalidInput, the variant Self::is_trial_point_infeasible returns false for, and gam-custom-family’s inner solver reports every refusal as Err(String). So “there is no Laplace mode at this rho”, a verdict about one rho, was graded fatal and killed the whole fit at the first probe, at an optimizer whose seed loop has the correct branch one line above the one it took (gam#2590).

The default is not a coin flip, because the two mistakes are not comparable:

  • A structural failure graded rho-local recurs at every probed rho. The seed loop exhausts, the run still fails, and it fails quoting this same reason — after a bounded number of cheap, identical inner failures.
  • A rho-local refusal graded structural aborts a fit that was perfectly fittable one rho away. Measured twice: #2553, #2590.

So where the type system forces a guess, the guess must be “trial point”. Where a caller knows better in either direction, it should construct the variant it means — Self::trial_point or the structural variant — instead of routing through here.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V