pub struct GrassmannFrame { /* private fields */ }Expand description
A Grassmann point: a p × r column-orthonormal FRAME U spanning an atom’s
decoder column space (issue #972).
The decoder coefficient matrix B_k (M_k × p) factors as B_k = C_k · Uᵀ
where C_k (M_k × r) is the coordinate matrix that lives IN the
arrow-Schur border and U (p × r) is this frame, profiled OUT of the
border by closed-form streaming polar steps. The border then carries only
Σ_k M_k · r coefficients rather than Σ_k M_k · p — the reduction that
keeps the border Cholesky / evidence log-det tractable at frontier p.
Canonical inner gauge. U is only defined up to a right r × r
orthogonal rotation U → U R (with the matching C_k → C_k R); the column
span (the Grassmann point) is invariant. For deterministic serialization we
pin a canonical representative: the frame is the left-singular subspace of
the cross-moment, ordered by descending singular value, with each column’s
sign fixed so its largest-magnitude entry is non-negative. The ordering is
recorded by the gauge_singular_values field so the same span always
serializes to the same bytes (no run-to-run rotation drift).
Implementations§
Source§impl GrassmannFrame
impl GrassmannFrame
Sourcepub fn output_dim(&self) -> usize
pub fn output_dim(&self) -> usize
Ambient output dimension p.
Sourcepub fn gauge_singular_values(&self) -> &Array1<f64>
pub fn gauge_singular_values(&self) -> &Array1<f64>
Canonical descending singular values of the cross-moment that fixed this frame’s column ordering (issue #972). Exposed so the serialization / canonicalization path can read the recorded gauge and reproduce the same span byte-for-byte (no run-to-run rotation drift).
Sourcepub fn frame(&self) -> ArrayView2<'_, f64>
pub fn frame(&self) -> ArrayView2<'_, f64>
Read-only view of the orthonormal frame U (p × r).
Sourcepub fn manifold_dimension(&self) -> usize
pub fn manifold_dimension(&self) -> usize
Grassmann manifold dimension r·(p − r) of this frame — the count of
profiled-out degrees of freedom that must enter the Laplace evidence
dimension accounting (issue #972, evidence honesty). A point on the
Grassmannian Gr(r, p) has exactly this many intrinsic coordinates.
Sourcepub fn polar_update(cross_moment: ArrayView2<'_, f64>) -> Result<Self, String>
pub fn polar_update(cross_moment: ArrayView2<'_, f64>) -> Result<Self, String>
Closed-form streaming POLAR step (issue #972): given an accumulated
p × r cross-moment Mcm (a sum of decoder-target outer products that
pulls the frame toward the current column-span evidence), return the
orthogonal polar factor U_new = polar(Mcm).
polar(M) = W Vᵀ from the thin SVD M = W Σ Vᵀ: the nearest
column-orthonormal matrix to M in Frobenius norm, and the closed-form
MAP frame update on the Grassmannian. Runs OUTSIDE the border (an
O(p r² ) thin SVD), so the border never carries the p factor.
gauge_singular_values = Σ records the canonical descending-σ ordering.
Sourcepub fn reconstruct_decoder(
&self,
coords: ArrayView2<'_, f64>,
) -> Result<Array2<f64>, String>
pub fn reconstruct_decoder( &self, coords: ArrayView2<'_, f64>, ) -> Result<Array2<f64>, String>
Project a coordinate matrix C_k (M_k × r) back to the full decoder
B_k = C_k · Uᵀ (M_k × p) — the reconstruction used wherever the
full-B consumers (assembly, decode, smoothness pullback) read the
decoder. fast_abt computes C_k · Uᵀ without materializing Uᵀ.
Sourcepub fn project_decoder(
&self,
decoder: ArrayView2<'_, f64>,
) -> Result<Array2<f64>, String>
pub fn project_decoder( &self, decoder: ArrayView2<'_, f64>, ) -> Result<Array2<f64>, String>
Project a full decoder B_k (M_k × p) onto this frame, returning the
coordinate matrix C_k = B_k · U (M_k × r) that the border stores.
The frame is orthonormal so U is its own pseudo-inverse-from-the-right:
C_k = B_k U recovers the in-span coordinates exactly and discards the
component of B_k orthogonal to the frame (zero when B_k’s span lies in
range(U), i.e. when the frame rank matched the decoder rank).
Sourcepub fn max_principal_angle(
&self,
other: ArrayView2<'_, f64>,
) -> Result<f64, String>
pub fn max_principal_angle( &self, other: ArrayView2<'_, f64>, ) -> Result<f64, String>
Largest principal angle (radians) between this frame’s column span and
another p × r' orthonormal frame’s span — the Grassmann geodesic
distance component used by the planted-atom recovery verifier (issue
#972).
The naive formula arccos(min σ_i(UᵀV)) loses half the available
precision for near-parallel spans: when cos θ = 1 − ε (the
ε ~ fp64.eps regime hit by a polar update of an already-orthonormal
frame), arccos(1 − ε) ≈ √(2ε) ≈ 1.49e-8, so a planted span the
solver actually recovered to machine precision was being reported as
O(√fp64.eps) off. The stable form uses BOTH the cosines from
M = UᵀV (small-angle limit: cos θ ≈ 1 − θ²/2, sensitive to noise)
AND the sines from the orthogonal complement
V_⊥ = (I − UUᵀ) V (small-angle limit: sin θ ≈ θ, sensitive to the
quantity we actually want), then combines them with atan2(sin, cos).
atan2 returns a precise angle across the whole [0, π/2] interval
regardless of which leg is small — so an exactly-equal-frame test now
reports the genuine ~fp64.eps residual instead of an inflated
√fp64.eps. The pairing is exact because the singular values of
M and V_⊥ are matched component-wise to the same principal
angle: σ_r(M) = cos θ_max and σ_1(V_⊥) = sin θ_max.
Trait Implementations§
Source§impl Clone for GrassmannFrame
impl Clone for GrassmannFrame
Source§fn clone(&self) -> GrassmannFrame
fn clone(&self) -> GrassmannFrame
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 GrassmannFrame
impl RefUnwindSafe for GrassmannFrame
impl Send for GrassmannFrame
impl Sync for GrassmannFrame
impl Unpin for GrassmannFrame
impl UnsafeUnpin for GrassmannFrame
impl UnwindSafe for GrassmannFrame
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,
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.