pub struct BasisBuildResult {
pub design: DesignMatrix,
pub penalties: Vec<Array2<f64>>,
pub nullspace_dims: Vec<usize>,
pub penaltyinfo: Vec<PenaltyInfo>,
pub metadata: BasisMetadata,
pub kronecker_factored: Option<KroneckerFactoredBasis>,
pub ops: Vec<Option<Arc<dyn PenaltyOp>>>,
pub null_eigenvectors: Vec<Option<Array2<f64>>>,
pub joint_null_rotation: Option<JointNullRotation>,
}Expand description
Standardized basis build result for engine-level composition.
Fields§
§design: DesignMatrix§penalties: Vec<Array2<f64>>§nullspace_dims: Vec<usize>§penaltyinfo: Vec<PenaltyInfo>§metadata: BasisMetadata§kronecker_factored: Option<KroneckerFactoredBasis>Optional factored rowwise-Kronecker representation for tensor-product
bases. When present, downstream code can keep the design operator-backed
instead of forcing a fully materialized n x prod(q_j) block.
ops: Vec<Option<Arc<dyn PenaltyOp>>>Per-active-penalty operator handles (parallel to penalties). Each
entry is Some(op) when the closed-form factory emitted an op-form
penalty bit-equivalent to the dense matrix, None for ordinary dense
penalties. Downstream consumers route through the Some entries to
avoid materializing dense p x p Grams in exact operator algebra.
null_eigenvectors: Vec<Option<Array2<f64>>>Per-active-penalty null-space eigenvector matrices (parallel to
penalties). Each entry is Some(U_null) with U_null.ncols() == nullspace_dims[k] when the active block has a non-trivial null space
(eigenvalues ≤ spectral tolerance), and None when the block is
already full-rank. The columns of U_null are the eigenvectors of
sym_penalty at the (near-)zero eigenvalues — i.e., an orthonormal
basis of null(S_block) in the block’s own coordinate system.
This is the raw spectral data that the construction pipeline uses to
absorb each smooth’s penalty null space into the parametric block
(reparameterize-and-split). Without absorption the inner Newton solve
cannot converge on data whose unpenalized signal lies along a null
direction of S (phantom-multiplier refusal at the KKT certificate).
joint_null_rotation: Option<JointNullRotation>Joint-null absorption rotation for this basis, when the basis carries any penalties with a non-trivial joint null space.
Some(rotation) records Q = [U_range | U_null] where U_null spans
the joint null space null(Σ_k S_k) over this basis’s active
penalties (unscaled — the structural joint null is independent of
λ). After the basis pipeline applies this rotation, the design
becomes X · Q and each penalty becomes Qᵀ S_k Q, block-diagonal
with a guaranteed-zero null tail. The same Q must be replayed at
prediction time, so it is persisted in the fitted model. None
indicates either no penalties on this basis, or a full-rank joint
penalty (joint nullity = 0). A Some value is never recorded with
joint_nullity == 0 — the None discriminant is canonical for
“nothing to absorb”.
Stage-2 commit A: this field is plumbed into the struct but neither
computed nor applied yet. Stage-2 commit B populates it; Stage-2
commit D applies the rotation to design and penalties.
Trait Implementations§
Source§impl Clone for BasisBuildResult
impl Clone for BasisBuildResult
Source§fn clone(&self) -> BasisBuildResult
fn clone(&self) -> BasisBuildResult
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !Freeze for BasisBuildResult
impl !RefUnwindSafe for BasisBuildResult
impl !UnwindSafe for BasisBuildResult
impl Send for BasisBuildResult
impl Sync for BasisBuildResult
impl Unpin for BasisBuildResult
impl UnsafeUnpin for BasisBuildResult
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,
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.