Skip to main content

GrassmannFrame

Struct GrassmannFrame 

Source
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

Source

pub fn output_dim(&self) -> usize

Ambient output dimension p.

Source

pub fn rank(&self) -> usize

Frame rank r (number of profiled column directions).

Source

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).

Source

pub fn frame(&self) -> ArrayView2<'_, f64>

Read-only view of the orthonormal frame U (p × r).

Source

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.

Source

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.

Source

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ᵀ.

Source

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).

Source

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

Source§

fn clone(&self) -> GrassmannFrame

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for GrassmannFrame

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V