Skip to main content

GlmLikelihoodSpec

Struct GlmLikelihoodSpec 

Source
pub struct GlmLikelihoodSpec {
    pub spec: LikelihoodSpec,
    pub scale: LikelihoodScaleMetadata,
}
Expand description

Explicit GLM likelihood specification: response/link spec plus scale semantics.

spec is the canonical (ResponseFamily, InverseLink) selector. scale records how the scale parameter is handled (profiled Gaussian sigma, fixed dispersion, fixed/estimated Gamma shape). The Gamma shape is mutated in place during PIRLS via with_gamma_shape; preserving that field on this struct is what lets the inner solver thread the estimated shape into deviance / log-likelihood / weight evaluation without a separate side channel.

Fields§

§spec: LikelihoodSpec§scale: LikelihoodScaleMetadata

Implementations§

Source§

impl GlmLikelihoodSpec

Source

pub fn canonical(spec: LikelihoodSpec) -> GlmLikelihoodSpec

Build a GlmLikelihoodSpec from a LikelihoodSpec, deriving the canonical default scale metadata for the response family.

Source

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

Source

pub fn coefficient_covariance_scale(&self, profiled_gaussian_phi: f64) -> f64

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

§Invariant

Vb is the inverse of the Hessian of the actual penalized objective the inner solver minimizes. The stored Hessian is always assembled as H = XᵀWX + S_λ, with the penalty S_λ added unscaled (see pirls::penalty::add_to_hessian). Whether H is already that true objective Hessian — and hence whether any post-hoc dispersion multiply is warranted — is decided entirely by what the IRLS working weight W carries:

  • Working weight already carries the reciprocal dispersion / full Fisher information. Then H = Xᵀ(W_sf/φ)X + S_λ already equals the true penalized Hessian (e.g. mgcv’s XᵀW_sfX/φ + S_λ for Gamma), so Vb = H⁻¹ and the scale is exactly 1.0. This is the case for Gamma (W = prior·shape = prior/φ), Tweedie (W = prior·μ^{2−p}/φ), Beta and Negative-Binomial (the working weight is the complete fixed-scale Fisher information), and the fixed-scale exponential families Poisson/Binomial (φ ≡ 1). Multiplying H⁻¹ by the dispersion again for any of these double-counts it and shrinks every SE by √dispersion.

  • Working weight is scale-free (W = priorweights, the profiled Gaussian convention). Then the data term carries an implicit unit scale and H = XᵀPX + S_λ is the Hessian of ½·(scaled deviance)·σ²⁻¹ without the σ². The correct covariance restores it: Vb = H⁻¹ · σ̂². Only this branch returns a non-unit scale.

profiled_gaussian_phi is the profiled residual variance σ̂² and is consulted only for the scale-free profiled-Gaussian branch; every other family ignores it. This deliberately does NOT touch dispersion() / dispersion_from_likelihood, which still report the response-level observation noise (1/shape for Gamma, 1/(1+φ) for Beta, …) used by predictive-interval construction — a distinct quantity from the coefficient-covariance scale defined here.

Source

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

Source

pub fn with_gamma_shape(self, shape: f64) -> GlmLikelihoodSpec

Mutate the Gamma shape parameter in place while preserving the rest of the spec. The shape only takes effect for Gamma families; for other families the scale metadata is left untouched.

Source

pub fn beta_phi_is_estimated(&self) -> bool

Whether the Beta-regression precision phi is estimated from data.

Source

pub fn with_beta_phi(self, phi: f64) -> GlmLikelihoodSpec

Mutate the Beta precision phi in place, on BOTH the family variant (where every PIRLS weight / deviance / log-likelihood expression reads it via ResponseFamily::Beta { phi }) and the scale metadata (the estimated-vs-fixed contract). No-op for non-Beta families. The inner solver calls this once per inner solve after a moment estimate of phi from the working residuals, so the IRLS weights Var(y)=mu(1-mu)/(1+phi) reflect the true precision rather than the phi=1 seed (issue #567).

Source

pub fn tweedie_phi_is_estimated(&self) -> bool

Whether the Tweedie exponential-dispersion phi is estimated from data.

Source

pub fn with_tweedie_phi(self, phi: f64) -> GlmLikelihoodSpec

Mutate the Tweedie dispersion phi in place. Unlike Beta, the Tweedie power p (not phi) is what is carried on the ResponseFamily::Tweedie variant; the dispersion lives purely in the scale metadata and is read by the IRLS weight (prior·μ^{2−p}/phi) through fixed_phi(). So updating the metadata here is sufficient to thread the estimated phi into every weight / covariance expression. No-op for non-Tweedie families (issue #771).

Source

pub fn negbin_theta_is_estimated(&self) -> bool

Whether the Negative-Binomial overdispersion theta is estimated from data (issue #802).

Source

pub fn with_negbin_theta(self, theta: f64) -> GlmLikelihoodSpec

Mutate the Negative-Binomial overdispersion theta in place, on BOTH the family variant (where every PIRLS weight / deviance / log-likelihood expression reads it via ResponseFamily::NegativeBinomial { theta }) and the scale metadata (the estimated-vs-fixed contract). No-op for non-NB families. The inner solver calls this once per inner solve after a maximum-likelihood estimate of theta from the working residuals, so the IRLS weight W = μθ/(θ+μ) and the variance Var(y)=mu+mu^2/theta reflect the data’s overdispersion rather than the seed theta (issue #802). This mirrors with_beta_phi exactly — both keep the family variant and the scale metadata as two synchronized views of one estimated parameter. No-op for a user-fixed theta (theta_fixed = true / FixedNegBinTheta, issue #983): the held value is the contract, and this mutator must never let an estimation path overwrite it — the PIRLS refresh gate (negbin_theta_is_estimated()) already skips the call, this enforces the same invariant at the data itself.

Source

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

The estimated Negative-Binomial theta, read from the family variant (the canonical store), or None for non-NB families.

Produce a copy of this spec with the Negative-Binomial overdispersion theta PINNED at theta for the duration of the smoothing-parameter (λ) search (#1082). Converts an EstimatedNegBinTheta spec into the statistically-identical FixedNegBinTheta form (theta_fixed = true), which gates off the per-inner-solve ML refresh in GamWorkingModel::update_with_curvature (its guard is negbin_theta_is_estimated()).

Rationale: with θ estimated, the inner solver re-derives θ from each outer iterate’s warm-start η, so θ — and hence the NB working response, deviance and penalty-logdet that feed the REML criterion — drifts every outer evaluation. The outer optimizer then chases a moving target and the projected-gradient convergence test never trips, grinding the loop to max_iter (the #1082 negative-binomial tensor timeout). Holding θ fixed across the λ-search makes the REML objective F(ρ) = REML(ρ, θ_frozen) a genuine stationary function of ρ, so the loop converges in a handful of iterations — and θ is still ML-refreshed at the single final, reported fit (the refine_dispersion_at_converged_eta = true accept-fit), exactly as the function-level docs require (“estimate the scale at the converged fit, not inside the λ search; mgcv likewise”). No-op for non-NB families and for an already user-fixed θ.

Trait Implementations§

Source§

impl Clone for GlmLikelihoodSpec

Source§

fn clone(&self) -> GlmLikelihoodSpec

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 GlmLikelihoodSpec

Source§

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

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

impl<'de> Deserialize<'de> for GlmLikelihoodSpec

Source§

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

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

impl PartialEq for GlmLikelihoodSpec

Source§

fn eq(&self, other: &GlmLikelihoodSpec) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for GlmLikelihoodSpec

Source§

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

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for GlmLikelihoodSpec

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<T> Scalar for T
where T: 'static + Clone + PartialEq + Debug,

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