pub enum SmoothBasisSpec {
Show 13 variants
ByVariable {
inner: Box<SmoothBasisSpec>,
by_col: usize,
kind: BySmoothKind,
by: ByVariableSpec,
},
FactorSumToZero {
inner: Box<SmoothBasisSpec>,
by_col: usize,
levels: Vec<u64>,
frozen_global_orthogonality: Option<Array2<f64>>,
},
BSpline1D {
feature_col: usize,
spec: BSplineBasisSpec,
},
BySmooth {
smooth: Box<SmoothBasisSpec>,
by_kind: ByVarKind,
},
FactorSmooth {
spec: FactorSmoothSpec,
},
ThinPlate {
feature_cols: Vec<usize>,
spec: ThinPlateBasisSpec,
input_scales: Option<Vec<f64>>,
},
Sphere {
feature_cols: Vec<usize>,
spec: SphericalSplineBasisSpec,
},
ConstantCurvature {
feature_cols: Vec<usize>,
spec: ConstantCurvatureBasisSpec,
},
Matern {
feature_cols: Vec<usize>,
spec: MaternBasisSpec,
input_scales: Option<Vec<f64>>,
},
MeasureJet {
feature_cols: Vec<usize>,
spec: MeasureJetBasisSpec,
input_scales: Option<Vec<f64>>,
},
Duchon {
feature_cols: Vec<usize>,
spec: DuchonBasisSpec,
input_scales: Option<Vec<f64>>,
},
Pca {
feature_cols: Vec<usize>,
basis_matrix: Array2<f64>,
centered: bool,
smooth_penalty: f64,
center_mean: Option<Array1<f64>>,
pca_basis_path: Option<PathBuf>,
chunk_size: usize,
},
TensorBSpline {
feature_cols: Vec<usize>,
spec: TensorBSplineSpec,
},
}Variants§
ByVariable
Row-gated wrapper used for mgcv-style by= smooths.
ByNumeric multiplies the inner smooth by a numeric column.
ByLevel keeps the inner smooth active only for rows whose encoded
categorical value has the stored bit pattern. Unordered factor-by
smooths are represented as one independent ByLevel term per level.
kind preserves the compact structural discriminator, while by
carries the full row-gating spec used to build the local design.
FactorSumToZero
Sum-to-zero factor smooth (bs="sz"): with L levels, estimate L-1
deviation coefficient blocks and use the final level as the negative
sum of the others, enforcing coefficient-wise zero sums across levels.
Fields
inner: Box<SmoothBasisSpec>frozen_global_orthogonality: Option<Array2<f64>>Global-orthogonality column map Z captured at fit time when this
term overlapped an owner smooth (s(x) + s(g, x, bs=sz), #978):
the hierarchical-ownership pass residualized this term’s realized
design as X ← X·Z, shrinking its coefficient block. Z depends
on the training-row owner designs, so prediction cannot rederive
it — it must be persisted and replayed
(apply_global_smooth_identifiability consumes it verbatim).
Chart convention: Z lives in the post-restack, post-joint-null-Q
coordinates — the raw sz rebuild reapplies Q deterministically
(#700), then Z applies on top. None for non-overlapping terms.
BSpline1D
BySmooth
A smooth modulated by a by= variable. Numeric by scales one inner
smooth; factor by replicates the inner smooth by level.
FactorSmooth
Factor-smooth interaction families (bs="fs", bs="sz") and
random slopes (bs="re").
Fields
spec: FactorSmoothSpecThinPlate
Fields
spec: ThinPlateBasisSpecSphere
ConstantCurvature
Constant-curvature (M_κ) geodesic-kernel smooth over κ-stereographic
chart coordinates (#944): one construction interpolating
S^d → ℝ^d → H^d through the spec’s fixed κ. The Wahba S² smooth is the
structural template; the geometry comes from
geometry::constant_curvature::ConstantCurvature.
Matern
MeasureJet
Measure-jet spline smooth: multiscale local-jet-residual energy of the empirical measure (centers as μ-quadrature, masses as μ-weights — no graph, mesh, or neighbor set inside the statistical object). The feature columns are ambient coordinates of data concentrated near an unknown low-dimensional, possibly stratified set.
Duchon
Pca
Fields
TensorBSpline
Tensor-product smooth built from 1D B-spline marginals.
This is the te()-style construction used when axes have different units/scales
(for example, space x time) and isotropic radial kernels are not appropriate.
Implementations§
Source§impl SmoothBasisSpec
impl SmoothBasisSpec
Sourcepub fn min_sample_rows(&self) -> usize
pub fn min_sample_rows(&self) -> usize
Conservative lower bound on the number of sample rows needed for this smooth basis to have a well-posed REML fit.
Each basis kind answers the question for itself, so the workflow does not have to know how many columns a B-spline, tensor product, PCA projection, or spatial kernel emits. The contract is a lower bound: returning too small a number is permitted (the inner solver will catch any genuine n-vs-rank failure that slips past); returning too large a number is a regression because it rejects legitimate fits.
Rationale: B-spline / tensor / PCA bases have a closed-form column
count, so we use the exact dimension. Radial bases (TPS, Matern,
Duchon, Sphere) and factor smooths choose their column count from the
data (heuristic_centers, unique_count); we fall back to a small
constant floor because a fit on fewer than five rows cannot stabilise
any radial smooth regardless of the configured kernel scale.
Sourcepub fn structural_kind(&self) -> &'static str
pub fn structural_kind(&self) -> &'static str
Stable structural discriminant for warm-start cache keying (#869).
Two smooths that produce different bases / penalty structures must map
to different strings here so they cannot collide on the persistent
warm-start cache_key (which is otherwise blind to topology: it hashes
only the raw input column count, so e.g. sphere vs torus vs
euclidean candidates fit on the same data would otherwise share one
key and cross-contaminate each other’s β/ρ seed). The string is the
topology identity, not the fitted coefficients, so same-topology refits
(the screen→full-refit cascade) still hit the same key and reuse work.
Sourcepub fn is_marginally_centered_tensor(&self) -> bool
pub fn is_marginally_centered_tensor(&self) -> bool
True for a tensor-product smooth that is only marginally centered
(ti(...), TensorBSplineIdentifiability::MarginalSumToZero): its
per-margin sum-to-zero reparameterization (B_xZ_x)⊗(B_zZ_z) has ALREADY
removed each axis’s main effect analytically (mgcv-identical), so its
main-effect removal is complete and it must take NO additional
owner-residualization block. Residualizing it a second time against the
realized main-effect designs is a grid-fragile no-op on an exact tensor
grid but eats genuine pure-interaction curvature off-grid (#1470).
Sourcepub fn structural_feature_cols(&self) -> Vec<usize>
pub fn structural_feature_cols(&self) -> Vec<usize>
Feature columns this basis consumes, used alongside [structural_kind]
to disambiguate two same-kind smooths on different axes. Wrapper
variants delegate to their inner basis.
Trait Implementations§
Source§impl Clone for SmoothBasisSpec
impl Clone for SmoothBasisSpec
Source§fn clone(&self) -> SmoothBasisSpec
fn clone(&self) -> SmoothBasisSpec
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 SmoothBasisSpec
impl Debug for SmoothBasisSpec
Source§impl<'de> Deserialize<'de> for SmoothBasisSpec
impl<'de> Deserialize<'de> for SmoothBasisSpec
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for SmoothBasisSpec
impl RefUnwindSafe for SmoothBasisSpec
impl Send for SmoothBasisSpec
impl Sync for SmoothBasisSpec
impl Unpin for SmoothBasisSpec
impl UnsafeUnpin for SmoothBasisSpec
impl UnwindSafe for SmoothBasisSpec
Blanket Implementations§
impl<T> Allocation 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,
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,
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.