pub enum ResponseFamily {
Gaussian,
Binomial,
Poisson,
Tweedie {
p: f64,
},
NegativeBinomial {
theta: f64,
theta_fixed: bool,
},
Beta {
phi: f64,
},
Gamma,
RoystonParmar,
}Expand description
Pure response distribution selector — no link information.
Variants§
Gaussian
Binomial
Poisson
Tweedie
NegativeBinomial
Fields
theta_fixed: booltrue when theta was supplied by the user as a held-fixed value
(--negative-binomial-theta, issue #983): the fit must use exactly
this overdispersion — Var(y) = μ + μ²/θ, IRLS weight
W = μθ/(θ+μ), coefficients/covariance/SEs all reflect it — and
the inner solver must never overwrite it. false means theta is
the running seed/estimate refined from the data each inner solve
(the #802 default). Carried on the family variant — the canonical
theta store — so the estimated-vs-fixed contract can never desync
from the value itself; default_scale_metadata derives the
matching scale variant.
Beta
Gamma
RoystonParmar
Implementations§
Source§impl ResponseFamily
impl ResponseFamily
pub const fn name(&self) -> &'static str
Sourcepub fn mean_clamp_bounds(&self) -> Option<(f64, f64)>
pub fn mean_clamp_bounds(&self) -> Option<(f64, f64)>
Closed-interval bounds for the mean (response-scale) of this family.
Used by predict-side CI clamps that need to keep transformed bounds
within the support of the response. Beta uses strict-open (1e-10, 1 − 1e-10)
to avoid logit singularities; Binomial / Royston-Parmar use the closed
[0, 1] since they are evaluated post-transformation. Unbounded
(continuous-real or non-negative-real) families return None — the
caller should not clamp.
Sourcepub fn response_support_bounds(&self) -> Option<(f64, f64)>
pub fn response_support_bounds(&self) -> Option<(f64, f64)>
Closed numeric bounds of the response support — the closure of the
set of values a single observation Y can take — used to clamp the
observation (prediction) interval so a predictive band never reports
values the response can never attain.
This is deliberately distinct from Self::mean_clamp_bounds, which
governs the mean (confidence) interval. mean_clamp_bounds returns
None for the non-negative-real families (Poisson / Tweedie /
NegativeBinomial / Gamma) because their default mean interval is built
by transforming the η endpoints through a positive inverse link, which
cannot escape the support. The observation interval, by contrast, is the
symmetric response-scale band μ ± z·σ_pred; for a small fitted mean its
lower endpoint crosses below the support floor (e.g. a Poisson count band
going negative), so it must be floored at the response support here.
The lower edge is the infimum of the support (0 for every non-negative
family, including the open-at-zero Gamma, whose predictive lower bound is
reported at the boundary 0). The upper edge is +∞ where the response
is unbounded above, which leaves the upper band untouched, or 1 for the
[0, 1]-valued families. None means the response is supported on the
whole real line (Gaussian) or has its support enforced downstream
(Royston–Parmar), and the predictive band is passed through unclamped.
The match arms mirror Self::response_support_contains: a new family
must update both together so the support a value is validated against and
the support a predictive band is clamped to stay consistent.
Sourcepub fn response_support_requirement(&self) -> Option<&'static str>
pub fn response_support_requirement(&self) -> Option<&'static str>
Per-family textual description of the response-support requirement.
None means the family is supported on the entire real line at the
validation layer (Gaussian) or has its support enforced by a downstream
pathway (RoystonParmar via the survival pipeline).
Binomial is the scalar Bernoulli-logit family: with no per-row trial
count mᵢ, the log-likelihood is ℓ(η) = y·η − log(1 + eη), which is
unbounded above for y ∉ {0, 1} (as η → ∞, ℓ ~ (y − 1)·η), and the
binomial deviance term (1 − y)·log((1 − y)/(1 − μ)) leaves its domain
for y > 1. The family is therefore only well-posed for y ∈ {0, 1},
which the support check enforces up front rather than deferring to the
downstream binarity heuristic.
Sourcepub fn validate_response_support(
&self,
y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>,
) -> Result<(), ResponseSupportViolation>
pub fn validate_response_support( &self, y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>, ) -> Result<(), ResponseSupportViolation>
Validate that every element of y lies in this family’s response
support. The check is the upfront, fit-blocking enforcement of the
family’s distributional support — e.g. Gamma rejects y ≤ 0 because
the log-likelihood contains log(y), Poisson rejects y < 0 because
the log-mass contains log(y!).
Returns Ok(()) for families whose support is the entire real line at
this layer (Gaussian) or whose support is enforced by a downstream
pathway (RoystonParmar via the survival pipeline). Binomial is
enforced here: only y ∈ {0, 1} keeps the scalar Bernoulli-logit
likelihood bounded.
Up to ResponseSupportViolation::MAX_REPORTED offending row indices
are returned in the violation so the message stays bounded on large
datasets while still identifying offending rows.
Sourcepub fn validate_response_degeneracy(
&self,
y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>,
) -> Result<(), ResponseDegeneracy>
pub fn validate_response_degeneracy( &self, y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>, ) -> Result<(), ResponseDegeneracy>
Detect a degenerate response: one whose value distribution makes the
family’s REML log-likelihood non-finite even though every individual
y_i lies inside the family’s distributional support.
Symmetric counterpart to Self::validate_response_support: support
rejects out-of-domain values (e.g. a negative Poisson count); this
rejects distributions that send the saturated MLE to a boundary at
which the score diverges. Each family answers the question for itself
— adding a new family does not require touching workflow.rs.
Concretely:
Binomial— refuses an all-zero or all-one response: the saturated logit is ±∞ and the REML score is +∞ (issue #331).- Every other family currently returns
Ok(())at this layer — the support check already guarantees enough variation to make the log-likelihood finite.
Sourcepub fn infer_from_response(
y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>,
y_kind: ResponseColumnKind,
) -> Result<ResponseFamily, ResponseInferenceRefusal>
pub fn infer_from_response( y: ArrayBase<ViewRepr<&f64>, Dim<[usize; 1]>>, y_kind: ResponseColumnKind, ) -> Result<ResponseFamily, ResponseInferenceRefusal>
Auto-infer a likelihood family when the user did not specify one.
Policy:
- A string-valued (
Categorical) response column is refused — numeric-encoded level indices (e.g."yes"/"no"→0.0/1.0) would otherwise be silently interpreted as a binary outcome, producing a probability model the user never asked for. - A strictly-binary numeric response (
Binarykind, orNumericwith only{0, 1}values) maps toBinomial. - A non-negative integer-valued count response (every value finite,
>= 0, and withinCOUNT_INTEGER_TOLof an integer) that reaches beyond the binary{0, 1}window (i.e. carries at least one value>= 2) maps toPoisson(log link). This is the “magic-by-default” count detection: mgcv/statsmodels users expect0,1,2,3,...to fit a Poisson GLM, not an identity-link Gaussian. - Anything else (any fractional or negative value) maps to
Gaussian.
The fallback to is_binary_response inside the Numeric arm is what
historically lived directly inside resolve_family; centralising the
policy here means every entry point (formula API, CLI, future bindings)
gets the same default-inference behaviour.
Trait Implementations§
Source§impl Clone for ResponseFamily
impl Clone for ResponseFamily
Source§fn clone(&self) -> ResponseFamily
fn clone(&self) -> ResponseFamily
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ResponseFamily
impl Debug for ResponseFamily
Source§impl<'de> Deserialize<'de> for ResponseFamily
impl<'de> Deserialize<'de> for ResponseFamily
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<ResponseFamily, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<ResponseFamily, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for ResponseFamily
impl PartialEq for ResponseFamily
Source§fn eq(&self, other: &ResponseFamily) -> bool
fn eq(&self, other: &ResponseFamily) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for ResponseFamily
impl Serialize for ResponseFamily
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for ResponseFamily
Auto Trait Implementations§
impl Freeze for ResponseFamily
impl RefUnwindSafe for ResponseFamily
impl Send for ResponseFamily
impl Sync for ResponseFamily
impl Unpin for ResponseFamily
impl UnsafeUnpin for ResponseFamily
impl UnwindSafe for ResponseFamily
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.