Skip to main content

UnifiedFitResult

Struct UnifiedFitResult 

Source
pub struct UnifiedFitResult {
Show 30 fields pub blocks: Vec<FittedBlock>, pub log_lambdas: Array1<f64>, pub lambdas: Array1<f64>, pub likelihood_family: Option<LikelihoodSpec>, pub likelihood_scale: LikelihoodScaleMetadata, pub log_likelihood_normalization: LogLikelihoodNormalization, pub log_likelihood: f64, pub deviance: f64, pub reml_score: f64, pub stable_penalty_term: f64, pub penalized_objective: f64, pub used_device: bool, pub outer_iterations: usize, pub outer_converged: bool, pub outer_gradient_norm: Option<f64>, pub standard_deviation: f64, pub covariance_conditional: Option<Array2<f64>>, pub covariance_corrected: Option<Array2<f64>>, pub inference: Option<FitInference>, pub fitted_link: FittedLinkState, pub geometry: Option<FitGeometry>, pub block_states: Vec<ParameterBlockState>, pub beta: Array1<f64>, pub pirls_status: PirlsStatus, pub max_abs_eta: f64, pub constraint_kkt: Option<ConstraintKktDiagnostics>, pub artifacts: FitArtifacts, pub inner_cycles: usize, pub outer_cost_evals: usize, pub inner_pirls_solves: usize,
}
Expand description

Unified fit result for all model types (standard GAM, GAMLSS, survival).

Standard models have a single block; GAMLSS and survival models have multiple blocks with different roles.

Fields§

§blocks: Vec<FittedBlock>

Coefficient blocks (1 for standard GAM, N for GAMLSS/survival).

§log_lambdas: Array1<f64>

Log-smoothing parameters (all blocks concatenated in block order).

§lambdas: Array1<f64>

Smoothing parameters (exp of log_lambdas).

§likelihood_family: Option<LikelihoodSpec>

Explicit engine-level family, when the fit uses a built-in family.

§likelihood_scale: LikelihoodScaleMetadata

Fixed-scale metadata for the fitted likelihood.

§log_likelihood_normalization: LogLikelihoodNormalization

Whether log_likelihood includes response-only normalization constants.

§log_likelihood: f64

Log-likelihood at the converged mode.

§deviance: f64

Explicit deviance reported by the fitting path.

§reml_score: f64

Complete REML/LAML objective value used for smoothing selection.

§stable_penalty_term: f64

Stable quadratic penalty term βᵀSβ, including any solver ridge quadratic.

§penalized_objective: f64

Public objective value reported for the fit. For REML/LAML fits this is the same complete objective as reml_score, not -ℓ + penalty + reml_score.

§used_device: bool

Whether the converged fit used a GPU execution path for its final inner solve.

§outer_iterations: usize

Number of outer (smoothing parameter) iterations.

§outer_converged: bool

Whether the outer optimization converged.

§outer_gradient_norm: Option<f64>

Final gradient norm of the outer optimization. None when no gradient was measured at termination — cache-hit short-circuit (the prior fit’s converged ρ was loaded from disk), gradient-free solver, or a degenerate early-exit path where no outer ran. outer_converged is the authoritative convergence signal.

§standard_deviation: f64

Residual scale on the response scale.

Contract: Gaussian identity models store residual standard deviation sigma here. Non-Gaussian families keep the response-scale summary used by their explicit likelihood-scale metadata.

§covariance_conditional: Option<Array2<f64>>

Vb: Bayesian/conditional covariance Var(β | λ) = H⁻¹ * φ̂ for the joint coefficient vector.

§covariance_corrected: Option<Array2<f64>>

Vp: Bayesian covariance with smoothing-parameter uncertainty correction.

§inference: Option<FitInference>

Inference quantities from the inner solver (EDF, Hessian, etc.).

§fitted_link: FittedLinkState

Fitted link parameters (SAS, BetaLogistic, Mixture).

§geometry: Option<FitGeometry>

Working-set geometry at convergence (for ALO diagnostics and saved-model covariance reconstruction).

§block_states: Vec<ParameterBlockState>

Internal block states from custom-family paths.

§beta: Array1<f64>

Joint coefficient vector (first block for standard GAMs, concatenated for multi-block).

§pirls_status: PirlsStatus

Inner solver convergence status. Required at decode time: a missing field on an older-schema or corrupted saved model previously decoded as Converged via a default, silently promoting non-converged β̂ through warm-start propagation, predict-time confidence intervals, and outer-loop convergence semantics. With the MODEL_PAYLOAD_VERSION gate in place, older schemas are rejected before this field is read, so requiring the field here is safe and strictly removes the silent default.

§max_abs_eta: f64

Maximum absolute linear predictor value at convergence.

§constraint_kkt: Option<ConstraintKktDiagnostics>

Constraint KKT diagnostics (monotone-constrained fits).

§artifacts: FitArtifacts

Solver artifacts (e.g. cached PIRLS result for ALO).

§inner_cycles: usize

Inner cycle count (blockwise path).

§outer_cost_evals: usize

Number of outer REML cost-only evaluations the fit executed (each trust-region / line-search probe drives one, paying an inner P-IRLS solve). Diagnostic only — guards regressions in outer work (#1575) and is not part of the statistical contract. Zero for paths that do not run the standard external REML optimizer.

§inner_pirls_solves: usize

Number of actual full-n inner P-IRLS solves the fit performed (the cache-missing solves across the seed-grid prepass, screening, multistart, and finalize). This is the true #1575 cost metric — distinct from, and typically ~2× larger than, outer_cost_evals, which counts outer requests including single-slot cache hits. Diagnostic only; not part of the statistical contract. Zero for paths that do not run the standard external REML optimizer.

Implementations§

Source§

impl UnifiedFitResult

Source§

impl UnifiedFitResult

Source§

impl UnifiedFitResult

Source

pub fn beta_covariance(&self) -> Option<&Array2<f64>>

Get the conditional Bayesian covariance matrix (Vb) if available.

Contract: Vb = H^{-1} * phi, scaled by the fitted dispersion. This is the Wood/mgcv Vb (Bayesian/conditional) covariance.

Source

pub fn beta_covariance_ve(&self) -> Option<&Array2<f64>>

Get the frequentist sandwich covariance (Ve) if available.

Wood/mgcv Ve = H⁻¹ X'WX H⁻¹ * φ̂.

Source

pub fn coefficient_influence(&self) -> Option<&Array2<f64>>

Get coefficient-space influence matrix F = H^{-1}X'WX if available.

Source

pub fn weighted_gram(&self) -> Option<&Array2<f64>>

Get the original-basis weighted Gram X'WX = H − S(λ) if available — the symmetric PSD matrix the Wood–Pya–Säfken corrected-EDF correction pairs with the smoothing-parameter uncertainty covariance (issue #1027).

Source

pub fn dispersion(&self) -> Option<Dispersion>

Dispersion used to scale covariance matrices.

Source

pub fn dispersion_phi(&self) -> f64

Canonical residual dispersion φ̂ — the response-level observation noise (Gaussian σ̂², Gamma 1/shape, Beta 1/(1+φ), fixed-scale families 1). This is the predictive observation-noise scale used to widen prediction observation intervals; it is NOT the coefficient-covariance scale (see Self::coefficient_covariance_scale). For families whose IRLS working weight already carries 1/φ, the two differ: the coefficient covariance is H⁻¹ (scale 1) while this dispersion stays 1/shape (#679).

Unlike Self::dispersion, which reads the cached inference block, this is computed from fields that always survive serialization (likelihood_family, likelihood_scale, standard_deviation). That matters for deployment-time consumers operating on a saved model whose inference block was dropped (e.g. core_saved_fit_result stores inference: None): the cached dispersion() is then None, but the scale is still recoverable and identical to the value used at fit time. When the cached block is present its dispersion is preferred verbatim so the two paths never diverge.

Source

pub fn coefficient_covariance_scale(&self) -> f64

Multiplier that turns the stored unscaled inverse penalized Hessian H⁻¹ into the reported coefficient covariance Vb = H⁻¹·scale.

This is the deployment-time / serialized-model counterpart of GlmLikelihoodSpec::coefficient_covariance_scale, used wherever the full stored beta_covariance() is unavailable and Vb must be reconstructed from the factorized Hessian (large-model predict path). It returns the profiled residual variance σ̂² for the scale-free profiled Gaussian and 1.0 for every family whose IRLS working weight already carries the dispersion / full Fisher information (Gamma, Tweedie, Beta, Negative-Binomial, Poisson, Binomial) — see #679. For custom/GAMLSS paths with no engine-level family it falls back to 1.0.

Source

pub fn beta_covariance_corrected(&self) -> Option<&Array2<f64>>

Get the smoothing-parameter-corrected beta covariance (Vp) if available.

Wood/mgcv name for the smoothing-parameter-corrected covariance Vp.

Source

pub fn beta_standard_errors(&self) -> Option<&Array1<f64>>

Get beta standard errors (conditional) if available.

Source

pub fn beta_standard_errors_corrected(&self) -> Option<&Array1<f64>>

Get smoothing-corrected beta standard errors if available.

Source

pub fn bias_correction_beta(&self) -> Option<&Array1<f64>>

Get the O(n⁻¹) bias-correction vector b̂ = H⁻¹ S(λ̂) β̂ in the original coefficient basis, if available.

Source

pub fn penalized_hessian(&self) -> Option<&Array2<f64>>

Get the penalized Hessian if available.

Boundary accessor: returns &Array2<f64> so out-of-scope consumers (CLI, GPU, families) keep their pre-newtype call shape. Use Self::penalized_hessian_unscaled when the caller wants the [UnscaledPrecision] newtype to enforce the dispersion-ownership invariant.

Source

pub fn penalized_hessian_unscaled(&self) -> Option<&UnscaledPrecision>

Get the penalized Hessian as the [UnscaledPrecision] newtype if available. Use this when constructing newtype-aware APIs (HMC whitening, sampling) so the dispersion convention is enforced at the type level.

Source

pub fn beta_covariance_phi_scaled(&self) -> Option<&PhiScaledCovariance>

Get the φ-scaled posterior covariance as the [PhiScaledCovariance] newtype if available, sourced from FitInference::beta_covariance.

Prefer this over Self::beta_covariance in inference-internal code so the φ-scaled invariant is type-enforced.

Source

pub fn working_weights(&self) -> Option<&Array1<f64>>

Get working weights if available.

Source

pub fn working_response(&self) -> Option<&Array1<f64>>

Get working response if available.

Source

pub fn smoothing_correction(&self) -> Option<&Array2<f64>>

Smoothing-parameter uncertainty covariance contribution J·Var(ρ)·Jᵀ in coefficient space, on the same dispersion scale as the conditional covariance Vb = φ·H⁻¹. This is the exact ρ-uncertainty term assembled from the IFT dβ̂/dρ and the outer Hessian at the fit optimum; the model-comparison machinery divides it by φ to recover the H⁻¹-scale ρ-covariance needed for the Wood–Pya–Säfken corrected EDF.

Source

pub fn edf_total(&self) -> Option<f64>

Total effective degrees of freedom.

Source

pub fn edf_by_block(&self) -> &[f64]

EDF by block.

Source

pub fn penalty_block_trace(&self) -> &[f64]

Raw per-penalty-block trace tr_kk = λ_kk·tr(H⁻¹ S_kk), aligned 1:1 with lambdas. Empty when the producing path did not record traces (issue #1219); callers must treat an empty slice as “unavailable”.

Source

pub fn per_term_edf( &self, coeff_range: Range<usize>, penalty_cursor: usize, k: usize, ) -> f64

Per-term effective degrees of freedom over a smooth/random-effect term’s coefficient block, defined as the trace of the linear-smoother influence matrix F = H⁻¹X'WX restricted to that block:

edf_term = Σ_{j ∈ coeff_range} F[j,j]
         = |coeff_range| − Σ_{kk ∈ term} tr_kk,   tr_kk = λ_kk·tr(H⁻¹ S_kk).

This is additive across terms and sums exactly to edf_total = p − Σ_all tr_kk, so a term’s EDF can never exceed the model total or the design column count. The legacy per-block EDF sum Σ_kk (rank(S_kk) − tr_kk) double-counts shared tensor coefficients for te/ti (and anisotropic / adaptive) smooths, where several penalty blocks span the same coefficient range and Σ_kk rank(S_kk) ≫ |coeff_range| (#1219, #1277).

penalty_cursor is the index of the term’s first penalty block in the flat lambdas / penalty_block_trace / edf_by_block layout, and k is the number of penalty blocks the term owns (0 for an unpenalised term).

Resolution order, each exact when available: the influence-matrix trace (the model’s own definition), then |coeff_range| − Σ tr_kk from the stored per-block traces (basis-invariant; exact even when F was never materialised for a large model), then — only when neither was recorded — the legacy block-sum as a last resort.

Source

pub fn block_by_role(&self, role: BlockRole) -> Option<&FittedBlock>

Find a block by role.

Source

pub fn beta_flat(&self) -> Array1<f64>

Flat coefficient vector (all blocks concatenated). This is equivalent to self.beta.clone().

Source

pub fn beta_time(&self) -> Array1<f64>

Time/baseline-hazard coefficients (survival location-scale).

Source

pub fn beta_threshold(&self) -> Array1<f64>

Threshold coefficients (survival location-scale).

Source

pub fn beta_log_sigma(&self) -> Array1<f64>

Log-sigma coefficients (survival location-scale).

Link-wiggle coefficients (survival location-scale, optional).

Source

pub fn lambdas_time(&self) -> Array1<f64>

Smoothing parameters for time block.

Source

pub fn lambdas_threshold(&self) -> Array1<f64>

Smoothing parameters for threshold block.

Source

pub fn lambdas_log_sigma(&self) -> Array1<f64>

Smoothing parameters for log-sigma block.

Source

pub fn lambdas_linkwiggle(&self) -> Option<Array1<f64>>

Smoothing parameters for link-wiggle block.

Source

pub fn n_blocks(&self) -> usize

Number of coefficient blocks.

Source

pub fn block_roles(&self) -> Vec<BlockRole>

Block roles.

Resolve the fitted link state for a given family.

For standard (non-adaptive) link families, no extra state is fitted, so this returns the bare FittedLinkState::Standard(None) payload — the concrete LinkFunction lives on the family/spec and is not duplicated into the fitted-link record. For adaptive links (SAS, BetaLogistic, Mixture, LatentCLogLog) it validates that the stored state matches the family and clones it out.

Trait Implementations§

Source§

impl Clone for UnifiedFitResult

Source§

fn clone(&self) -> UnifiedFitResult

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 UnifiedFitResult

Source§

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

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

impl<'de> Deserialize<'de> for UnifiedFitResult

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for UnifiedFitResult

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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