pub enum CoefficientCoordinate {
Spanning,
Structural,
}Expand description
What a parameter block’s COEFFICIENT COORDINATE is, as opposed to what its column space is (#2748).
§The distinction, and why one bit is needed to state it
For most blocks the coefficients are an arbitrary basis: any V with
X V spanning range(X) gives the same model, so the identifiability
canonicaliser is free to reparameterise β ↦ Vᵀβ, pull the penalties back
as VᵀSV, and let crate::Gauge lift the answer home. That freedom is
what lets it remove a cross-block structural confound EXACTLY instead of
ridging it away.
Some blocks are not like that. The monotone link-wiggle warp is the
canonical case: its family imposes β_w ≥ 0 componentwise on those very
coefficients, because an I-spline with non-negative coefficients is what
makes the learned link monotone. β ↦ Vᵀβ maps that cone to
{A V β̃ ≥ 0}, and the hook that produces it
(CustomFamily::block_linear_constraints) is a function of the block’s
WIDTH — it cannot express A V, so after a reparameterisation it would
return a cone in rotated coordinates that means nothing, and the
coordinatewise projection beside it (post_update_block_beta) would enforce
that nothing. The model would silently stop being monotone.
So “may this block be reparameterised?” is a property of the block’s
coordinate, and it is NOT the question ParameterBlockSpec::gauge_priority
answers. A priority answers “if a shared direction must be given up, whose
is it?” — an ordering AMONG blocks. Reading an ordering as a licence to
rotate is how gam#2748 broke: giving the warp a strictly lower priority
(correctly, so a cross-block alias stops being unfittable) also lifted the
canonicaliser’s equal-priority guard and authorised rotating the one block
that cannot be rotated.
§Fail-closed
Spanning is the default because it is the common case,
but every DERIVATION of this value must resolve doubt toward
Structural: declining a reparameterisation always
preserves the model (the canonicaliser falls through to the audit gate,
which is where it lived before the orthogonalisation pass existed), while
performing one on a structural coordinate silently changes it.
Variants§
Spanning
Only the block’s column SPACE is model content. Any basis of it is the
same model, so a reparameterisation β ↦ Vᵀβ with the penalties and the
warm start pulled back is exact.
Structural
The coordinate ITSELF is model content — a componentwise sign cone, a monotonicity ordering, a box the family projects onto, or a geometry the family rebuilds at this exact width. No change of basis preserves the model, and no change of width preserves the family’s own rebuild.
Implementations§
Source§impl CoefficientCoordinate
impl CoefficientCoordinate
Sourcepub fn is_structural(self) -> bool
pub fn is_structural(self) -> bool
Does this coordinate carry model structure a reparameterisation would destroy?
Trait Implementations§
Source§impl Clone for CoefficientCoordinate
impl Clone for CoefficientCoordinate
Source§fn clone(&self) -> CoefficientCoordinate
fn clone(&self) -> CoefficientCoordinate
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for CoefficientCoordinate
Source§impl Debug for CoefficientCoordinate
impl Debug for CoefficientCoordinate
Source§impl Default for CoefficientCoordinate
impl Default for CoefficientCoordinate
Source§fn default() -> CoefficientCoordinate
fn default() -> CoefficientCoordinate
impl Eq for CoefficientCoordinate
Source§impl PartialEq for CoefficientCoordinate
impl PartialEq for CoefficientCoordinate
impl StructuralPartialEq for CoefficientCoordinate
Auto Trait Implementations§
impl Freeze for CoefficientCoordinate
impl RefUnwindSafe for CoefficientCoordinate
impl Send for CoefficientCoordinate
impl Sync for CoefficientCoordinate
impl Unpin for CoefficientCoordinate
impl UnsafeUnpin for CoefficientCoordinate
impl UnwindSafe for CoefficientCoordinate
Blanket Implementations§
impl<T> Boilerplate for T
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,
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.