Skip to main content

MatrixFreeSpdOperator

Struct MatrixFreeSpdOperator 

Source
pub struct MatrixFreeSpdOperator { /* private fields */ }
Expand description

Operator-backed SPD Hessian with exact spectral REML algebra.

The operator closure is still useful for construction paths that naturally expose HVPs, but REML cost/gradient/Hessian terms must all come from one exact decomposition so ∂ log|H| = tr(H⁻¹ ∂H) holds. We therefore materialize the coefficient Hessian by canonical-basis HVPs under an explicit memory cap and delegate logdet, traces, and solves to DenseSpectralOperator.

Implementations§

Source§

impl MatrixFreeSpdOperator

Source

pub fn new_with_mode<F>(dim: usize, apply: F, mode: PseudoLogdetMode) -> Self
where F: Fn(&Array1<f64>) -> Array1<f64> + Send + Sync + 'static,

Source

pub fn new_with_mode_and_dense_assemble<F>( dim: usize, apply: F, mode: PseudoLogdetMode, dense_assemble: Option<Arc<dyn Fn() -> Option<Array2<f64>> + Send + Sync>>, ) -> Self
where F: Fn(&Array1<f64>) -> Array1<f64> + Send + Sync + 'static,

Like [new_with_mode], but additionally accepts an optional single-pass dense assembly of the same penalized operator. When present and it yields a matrix, materialize_dense_operator uses it instead of the dim canonical-basis matvecs. See the field doc on dense_assemble.

Trait Implementations§

Source§

impl HessianOperator for MatrixFreeSpdOperator

Source§

fn prefers_stochastic_trace_estimation(&self) -> bool

The operator delegates logdet, trace_hinv_*, trace_logdet_*, solve, and solve_multi to a lazily-built DenseSpectralOperator whenever the exact-dense materialization fits the configured byte cap (see exact_dense_spectral_budget_ok / EXACT_DENSE_SPECTRAL_MAX_BYTES). In that regime the algebra is exact spectral — there is no stochastic preference to advertise, and forcing the caller to take the Hutchinson path would replace an O(p²) exact reduction with O(k·apply) noisy probes.

When the budget is exceeded the dense factor cannot be built and the CG trace-solve path added in 2bd6af68 is the only feasible route; the flag flips to true so stochastic_trace_solve* callers route through cg_trace_solve instead of crashing in exact_dense_spectral().expect.

Source§

fn logdet_traces_match_hinv_kernel(&self) -> bool

Mirror the prefers_stochastic_trace_estimation gate: when the dense factor is reachable the operator’s logdet / trace_hinv reductions all resolve through DenseSpectralOperator, whose logdet_traces_match_hinv_kernel is false for the smooth-spectral regularization variants we run. Reporting true here would let the outer evaluator route logdet-gradient/Hessian traces through the Hutchinson H⁻¹ kernel which does not satisfy ∂ log|H| = tr(H⁻¹ ∂H) under smooth-spectral. The CG-only regime (budget exceeded) lacks a dense reference so falling back to the stochastic kernel is acceptable as a best-effort estimate.

Source§

fn logdet(&self) -> f64

log|H|₊ — pseudo-logdet using only active eigenvalues/pivots.
Source§

fn as_exact_dense_spectral(&self) -> Option<&DenseSpectralOperator>

Exact dense spectral representation, when this backend has one. Read more
Source§

fn trace_hinv_product(&self, a: &Array2<f64>) -> f64

tr(H₊⁻¹ A) — trace of pseudo-inverse times a symmetric matrix. Uses the SAME decomposition as logdet.
Source§

fn trace_hinv_operator(&self, op: &dyn HyperOperator) -> f64

tr(H₊⁻¹ B) for an operator-backed Hessian drift. Read more
Source§

fn trace_hinv_product_cross(&self, a: &Array2<f64>, b: &Array2<f64>) -> f64

tr(H⁻¹ A H⁻¹ B) for dense symmetric Hessian drifts. Read more
Source§

fn trace_hinv_matrix_operator_cross( &self, matrix: &Array2<f64>, op: &dyn HyperOperator, ) -> f64

tr(H⁻¹ A H⁻¹ B) for a dense drift A and an operator-backed drift B. Read more
Source§

fn trace_hinv_operator_cross( &self, left: &dyn HyperOperator, right: &dyn HyperOperator, ) -> f64

tr(H⁻¹ A H⁻¹ B) for operator-backed Hessian drifts. Read more
Source§

fn trace_logdet_operator(&self, op: &dyn HyperOperator) -> f64

tr(G_ε(H) B) for an operator-backed Hessian drift. Read more
Source§

fn solve(&self, rhs: &Array1<f64>) -> Array1<f64>

H⁻¹ v — linear solve using the active decomposition.
Source§

fn solve_multi(&self, rhs: &Array2<f64>) -> Array2<f64>

H⁻¹ M — multi-column solve.
Source§

fn stochastic_trace_solve(&self, rhs: &Array1<f64>, rel_tol: f64) -> Array1<f64>

H⁻¹ v for stochastic trace probes. Read more
Source§

fn stochastic_trace_solve_for_probe( &self, rhs: &Array1<f64>, rel_tol: f64, probe_id: u64, trace_state: Option<&Arc<Mutex<StochasticTraceState>>>, ) -> Array1<f64>

H⁻¹ v for a deterministic stochastic trace probe id. Read more
Source§

fn stochastic_trace_solve_multi( &self, rhs: &Array2<f64>, rel_tol: f64, ) -> Array2<f64>

H⁻¹ M for stochastic trace probes.
Source§

fn trace_logdet_hessian_cross( &self, h_i: &Array2<f64>, h_j: &Array2<f64>, ) -> f64

Cross-trace for the logdet Hessian: ∂²_{ij} log|R_ε(H)| = tr(G_ε Ḧ_{ij}) + spectral_cross(Ḣ_i, Ḣ_j). Read more
Source§

fn trace_logdet_hessian_cross_matrix_operator( &self, h_i: &Array2<f64>, h_j: &dyn HyperOperator, ) -> f64

Operator-backed mixed form of [trace_logdet_hessian_cross]. Read more
Source§

fn trace_logdet_hessian_cross_operator( &self, h_i: &dyn HyperOperator, h_j: &dyn HyperOperator, ) -> f64

Operator-backed form of [trace_logdet_hessian_cross]. Read more
Source§

fn active_rank(&self) -> usize

Number of active dimensions (rank of pseudo-inverse).
Source§

fn dim(&self) -> usize

Full dimension of H.
Source§

fn is_dense(&self) -> bool

Whether this operator is backed by a dense factorization. Read more
Source§

fn as_dense_spectral(&self) -> Option<&DenseSpectralOperator>

Access the dense spectral backend when this operator is powered by a single eigendecomposition.
Source§

fn has_matrix_free_trace_cg_operator(&self) -> bool

Whether this backend exposes a matrix-free operator usable by trace CG.
Source§

fn assemble_h_dense_for_tangent_projection(&self) -> Result<Array2<f64>, String>

Assemble the raw dense Hessian represented by this backend for active-constraint tangent projection. Read more
Source§

fn trace_logdet_gradient(&self, a: &Array2<f64>) -> f64

tr(G_ε(H) A) — trace for the logdet gradient ∂_i log|R_ε(H)|. Read more
Source§

fn xt_logdet_kernel_x_diagonal(&self, x: &DesignMatrix) -> Array1<f64>

diag(X · G_ε(H) · Xᵀ) — the leverage corresponding to trace_logdet_gradient. trace_logdet_gradient(Xᵀ diag(w) X) = Σᵢ wᵢ · h^G[i]. Read more
Source§

fn trace_logdet_h_k( &self, a_k: &Array2<f64>, third_deriv_correction: Option<&Array2<f64>>, ) -> f64

Efficient computation of tr(G_ε(H) Hₖ) for the logdet gradient. Read more
Source§

fn trace_logdet_block_local( &self, block: &Array2<f64>, scale: f64, start: usize, end: usize, ) -> f64

tr(G_ε(H) · A_block) where A_block is a p_block × p_block matrix embedded at rows/columns [start..end]. Read more

Auto Trait Implementations§

Blanket Implementations§

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> 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, 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