pub enum RhoPrior {
Flat,
Normal {
mean: f64,
sd: f64,
},
GammaPrecision {
shape: f64,
rate: f64,
},
PenalizedComplexity {
upper: f64,
tail_prob: f64,
},
Independent(Vec<RhoPrior>),
}Expand description
Fixed prior family for smoothing parameters in joint HMC refinement.
Variants§
Flat
Normal
GammaPrecision
Gamma(shape, rate) conjugate hyperprior on the precision lambda = exp(rho).
The deterministic REML/LAML objective uses the MAP-in-lambda convention
and is minimized, so this contributes rate * exp(rho) - (shape - 1) * rho
up to an additive constant. Samplers over rho include the +rho Jacobian
from lambda = exp(rho), so their log-density contribution is
shape * rho - rate * exp(rho). For a block with effective dimension n_p
and centered quadratic
(beta - mu)'S_p(beta - mu), the conditional posterior is
Gamma(shape + n_p/2, rate + quadratic/2) and the closed-form MAP
precision is (shape + n_p/2 - 1) / (rate + quadratic/2).
Gamma(1, 0) is the explicit flat/default case and reproduces the
current MacKay/Tipping fixed point.
PenalizedComplexity
Penalized-complexity (PC) prior on the smoothing parameter (Simpson, Rue, Riebler, Martins, Sørbye, Statistical Science 2017).
A PC prior fixes a base model (here the infinitely-smooth limit, where
the penalized component collapses to its null space) and puts an
exponential prior on the distance away from it. For a Gaussian smooth
with precision λ = exp(ρ) the relevant distance is the marginal
standard-deviation scale d = λ^{-1/2} = exp(-ρ/2), and a constant-rate
penalization p(d) = θ exp(-θ d) induces the closed-form log-prior
log p(ρ) = ln(θ/2) − ρ/2 − θ exp(−ρ/2).The rate θ is calibrated by the single interpretable tail statement
P(d > upper) = tail_prob, i.e. θ = −ln(tail_prob) / upper. The prior
is reparameterization-invariant and shrinks toward the simpler model
(an exponential wall against under-smoothing, only a gentle linear pull
toward over-smoothing), which is exactly the Occam behaviour wanted for
high-variance flexible components. The REML/LAML objective is minimized,
so this contributes ρ/2 + θ exp(−ρ/2) (up to an additive constant) to
the cost, with gradient 1/2 − (θ/2) exp(−ρ/2) and (always positive)
curvature (θ/4) exp(−ρ/2).
Fields
Independent(Vec<RhoPrior>)
Coordinate-specific priors for models whose smoothing parameters do not share one prior family, such as nested coefficient groups.
Implementations§
Source§impl RhoPrior
impl RhoPrior
Sourcepub fn upper_tail_gradient_vanishes(&self, coordinate: usize) -> bool
pub fn upper_tail_gradient_vanishes(&self, coordinate: usize) -> bool
Does this prior contribute nothing to ∂V/∂ρ_k in the λ→∞
(ρ_k → +∞) tail?
Every rail-reasoning path in the outer certificate — the analytic λ=∞ face form and the measured-tail probe alike — decides by the law
ĉ = −e^{ρ} ∂V/∂ρ is CONSTANT along the tail,which is a statement about a REML/LAML criterion, whose λ=∞ face gives
∂V/∂ρ = O(e^{−ρ}). It holds only when the criterion really is that
one. Any ρ-prior whose own gradient survives into the tail adds a term
the law does not model, ĉ diverges, and there is no λ=∞ face to
certify at any box width (#2450: under Normal { 0, 3 } the measured
∂V/∂ρ → ρ/9 and ĉ → −ρe^{ρ}/9).
Carrying the answer here rather than re-deriving it at each consumer is
the point: the previous consumer-side test was matches!(prior, Flat),
which silently misclassifies the two other spellings of a flat
coordinate.
True exactly for the families whose ρ-gradient is identically zero on the identified upper tail:
Flat— the REML runtime evaluates unset coordinates through the SELF-GATED, one-sided firth-default barrier, which is byte-identically flat aboveρ = −2 ln(upper). The wall it does carry is on the other side, against theλ → 0under-smoothing degeneracy.GammaPrecision { shape: 1, rate: 0 }— exactly flat under the MAP-in-λ convention (cost, gradient and Hessian all vanish); the same “unset” coordinate asFlat, spelled differently.
False for every other family, each for a nameable reason: Normal
leaves (ρ − mean)/sd² → ∞; PenalizedComplexity leaves its persistent
+1/2 Occam pull; a GammaPrecision with rate > 0 leaves
rate·e^{ρ}, which diverges faster than the law’s own scale.
coordinate indexes the ρ vector, so an Independent prior answers per
coordinate — a face can be certifiable on one coordinate and not on
another. A nested Independent is structurally invalid and answers
false rather than pretending to know.
Sourcepub fn upper_tail_gradient_vanishes_everywhere(&self, rho_dim: usize) -> bool
pub fn upper_tail_gradient_vanishes_everywhere(&self, rho_dim: usize) -> bool
Does the upper-tail law hold on every coordinate of a ρ of length
rho_dim? An Independent prior shorter than rho_dim is malformed
and answers false.
Sourcepub fn is_unset(&self) -> bool
pub fn is_unset(&self) -> bool
Did the caller leave this prior UNSET, or did they configure it?
RhoPrior::default() is Flat, so “unset” and “explicitly asked for a
flat coordinate” are the same value and deliberately indistinguishable —
both mean the criterion is pure REML/LAML here, which is what any
consumer of this predicate actually wants to know. What is NOT the same
is a configured Normal / PenalizedComplexity / non-trivial
GammaPrecision: that value is a modelling choice someone wrote down,
and a subsystem that rewrites it is discarding an instruction (#2463).
Unset has more than one spelling. GammaPrecision { shape: 1, rate: 0 }
is “the explicit flat/default case” by this enum’s own documentation —
its cost, gradient and Hessian all vanish under the MAP-in-λ convention —
so a matches!(prior, Flat) test silently misclassifies it as
configured. Carrying the answer here rather than re-deriving it at each
consumer is the point (#2427): the same question asked in three places
must not get three answers.
An Independent prior is unset only when EVERY coordinate is, since a
single configured coordinate is still an instruction. An empty
Independent carries no instruction and is therefore unset.
Trait Implementations§
Source§impl Default for RhoPrior
Flat, because the deterministic criterion is REML/LAML by contract.
impl Default for RhoPrior
Flat, because the deterministic criterion is REML/LAML by contract.
SPEC: “REML (or LAML) always used for fitting, never GCV” and “posterior
mean must always be the default (never MAP)”. A Default that installs a
proper prior on ρ makes the shipped deterministic criterion
REML + Σ_k ρ_k²/(2 sd²) — MAP in ρ — which is a different estimator,
not a stabilised version of the same one. gam-custom-family has always
passed Flat explicitly at its entry point for exactly this reason; the
gam-models / CLI / Python path reached the same solver through
FitOptions::default() and inherited a prior the enum’s own doc comment
scopes to joint HMC refinement (#2450).
The sampler does not lose its prior by this. A flat prior on ρ gives
an IMPROPER joint posterior — as ρ → ∞ the REML criterion tends to the
finite λ=∞ face value, so exp(−V) does not decay and ∫dρ diverges — and
that is precisely why joint HMC needs a proper one. The runtime already
separates the two: resolve_effective_rho_prior fills unset (Flat)
coordinates with the weakly-informative penalized-complexity default for
consumers that need a distribution (serialization, joint-HMC refinement),
while the REML/LAML objective evaluates those same coordinates through the
self-gated one-sided barrier, which is byte-identically flat on the
identified side. One default cannot serve both questions; Flat is the
answer to “what criterion am I minimizing”, and the sampler’s answer is
derived from it rather than shared with it.