pub struct ExternalJointHyperEvaluator<'a> { /* private fields */ }Implementations§
Source§impl<'a> ExternalJointHyperEvaluator<'a>
impl<'a> ExternalJointHyperEvaluator<'a>
pub fn new( y: ArrayView1<'a, f64>, w: ArrayView1<'a, f64>, x: &DesignMatrix, offset: ArrayView1<'_, f64>, s_list: &[BlockwisePenalty], opts: &ExternalOptimOptions, context: &str, ) -> Result<Self, EstimationError>
Sourcepub fn slow_path_reset_count(&self) -> u64
pub fn slow_path_reset_count(&self) -> u64
#1033 instrumentation accessor: number of slow-path reset_surface
rebuilds the evaluator has performed since construction. A trial that
takes the design-revision fast path (cache hit) does not advance this, so
a test can assert the n-row reconditioning lane was not re-entered by
checking this counter is unchanged across a repeat-revision eval.
Sourcepub fn stage_glm_first_step_gram(&mut self, gram: Option<Array2<f64>>)
pub fn stage_glm_first_step_gram(&mut self, gram: Option<Array2<f64>>)
Stage (or clear) the frozen-weight GLM first-Fisher-step Gram for the
next trial eval (#1111 / #1033 mechanism (c)). The staged Gram is
installed onto the inner REML surface inside prepare_eval_state and
then cleared; passing None clears any previously staged Gram so a stale
previous-ψ Gram is never consumed.
Sourcepub fn stage_glm_psi_gram_deriv(
&mut self,
deriv: Option<(Array2<f64>, Array1<f64>)>,
)
pub fn stage_glm_psi_gram_deriv( &mut self, deriv: Option<(Array2<f64>, Array1<f64>)>, )
Stage (or clear) the GLM frozen-W conditioned-frame exact ψ-derivative
pair (∂XᵀWX/∂ψ, ∂XᵀW(y−offset)/∂ψ) for the next trial eval
(#1033 / #1111). Produced by gradient_pair_if_sound when the frozen-W
tensor covers ψ for the gradient and the working weight has not drifted;
installed onto the inner REML surface inside prepare_eval_state (after
reset_surface, on both the slow and design-revision fast paths) and
then cleared. Serves the GLM ψ-gradient a_j / g_j n-free; the
Hessian curvature B_j always stays the exact n-dependent slab. Passing
None clears any previously staged pair so a stale previous-ψ
derivative is never consumed.
pub fn set_analytic_penalty_registry( &mut self, registry: Option<&AnalyticPenaltyRegistry>, )
pub fn set_persistent_latent_values_fingerprint( &mut self, id_mode: &LatentIdMode, )
pub fn load_persistent_latent_values( &self, n_obs: usize, latent_dim: usize, ) -> Option<Array2<f64>>
pub fn store_persistent_latent_values(&self, values: &Array2<f64>)
Sourcepub fn build_and_set_psi_gram_tensor(
&mut self,
eval_raw_design: impl FnMut(f64) -> Result<DesignMatrix, String>,
weights: ArrayView1<'_, f64>,
z: ArrayView1<'_, f64>,
psi_lo: f64,
psi_hi: f64,
) -> bool
pub fn build_and_set_psi_gram_tensor( &mut self, eval_raw_design: impl FnMut(f64) -> Result<DesignMatrix, String>, weights: ArrayView1<'_, f64>, z: ArrayView1<'_, f64>, psi_lo: f64, psi_hi: f64, ) -> bool
Build and attach a certified ψ-Gram tensor (#1033b) for the single
design-moving hyperparameter ψ over [psi_lo, psi_hi].
eval_raw_design(psi) returns the EXACT realized design at psi in the
raw (user) column frame — the same realizer the per-trial path uses.
This method threads it through THIS evaluator’s parametric column
conditioning before the tensor sees it, so the tensor’s assembled
XᵀWX(ψ) lives in the SAME conditioned frame as the streamed
gaussian_fixed_cache_if_eligible (which forms its Gram from
x_fit = conditioning.apply_to_design(x)). The conditioning is a fixed,
ψ-invariant column transform (means/scales frozen from the baseline
design at construction), so applying it inside the build keeps the
expansion analytic and the per-trial installed cache frame-exact —
without restricting to identity conditioning. Returns whether a
certified tensor was attached; false keeps the exact per-trial path.
Sourcepub fn set_supports_nfree_penalty_rekey(&mut self, supported: bool)
pub fn set_supports_nfree_penalty_rekey(&mut self, supported: bool)
Declare whether the design cache can rebuild S(ψ) exactly and n-free
for the single spatial term (#1033, penalty lane). Set ONCE at setup from
cache.supports_nfree_penalty_rekey(). When true, the design-revision
fast path’s design-realization skip is permitted (the penalty can be
re-keyed without reset_surface) and every fast-path trial MUST have a
staged exact penalty (stage_fast_path_penalty), else prepare_eval_state
hard-errors rather than pairing a stale S.
Sourcepub fn supports_nfree_penalty_rekey(&self) -> bool
pub fn supports_nfree_penalty_rekey(&self) -> bool
True when the n-free penalty re-key lane is enabled for this fit.
Sourcepub fn stage_fast_path_penalty(
&mut self,
penalty: Option<(Vec<CanonicalPenalty>, Vec<usize>)>,
)
pub fn stage_fast_path_penalty( &mut self, penalty: Option<(Vec<CanonicalPenalty>, Vec<usize>)>, )
Stage (or clear) the EXACT n-free canonical penalty surface S(ψ) for the
NEXT trial eval (#1033, penalty lane). The CALLER (which holds the design
cache) computes cache.canonical_penalties_at(theta) and hands the
owned (Vec<CanonicalPenalty>, active_nullspace_dims) here BEFORE the
eval — sidestepping a &mut cache borrow alias with the evaluator. On the
design-revision fast path prepare_eval_state /
prepare_eval_state_cost_only consume the staged value via
refresh_psi_penalty_surface and re-install S(ψ_new) on the kept
reference surface; the slow path clears it (the freshly realized penalty
is used instead). Passing None clears any previously staged surface so a
stale previous-ψ S is never consumed.
Sourcepub fn build_frozen_glm_gram_tensor(
&self,
eval_raw_design: impl FnMut(f64) -> Result<DesignMatrix, String>,
frozen_w: ArrayView1<'_, f64>,
working_z: ArrayView1<'_, f64>,
psi_lo: f64,
psi_hi: f64,
) -> Option<FrozenWeightGramTensor>
pub fn build_frozen_glm_gram_tensor( &self, eval_raw_design: impl FnMut(f64) -> Result<DesignMatrix, String>, frozen_w: ArrayView1<'_, f64>, working_z: ArrayView1<'_, f64>, psi_lo: f64, psi_hi: f64, ) -> Option<FrozenWeightGramTensor>
Build a certified frozen-weight GLM ψ-Gram tensor (#1111 / #1033 mechanism (c)) for the single design-moving hyperparameter ψ.
Mirrors Self::build_and_set_psi_gram_tensor but for the GLM
design-moving lane: the working weight w and working response z are
FROZEN at the warm working point, and the tensor wraps the weighted
design A(ψ) = diag(√w)·X_fit(ψ). Crucially eval_raw_design is threaded
through THIS evaluator’s parametric column conditioning before the tensor
sees it, so the assembled frozen-W Gram XᵀWX(ψ) lives in the SAME
conditioned x_fit frame the inner PIRLS solve forms its Gram in — the
same frame-correctness contract the Gaussian lane relies on. Without this
the tensor would be assembled in the raw user-column frame and silently
mismatch any inner consumer.
Returns the certified tensor (caller owns it, e.g. to re-use the
per-trial weight-drift guard), or None when no Chebyshev rung certifies
— the caller then keeps the exact per-trial PIRLS rebuild.
Sourcepub fn psi_gram_tensor_covers_gradient(&self, psi: f64) -> bool
pub fn psi_gram_tensor_covers_gradient(&self, psi: f64) -> bool
True when a certified ψ-Gram tensor is installed AND psi lies inside
its certified GRADIENT window — i.e. the n-free k-space ψ-derivatives
(∂G/∂ψ, ∂b/∂ψ) will serve the Gaussian gradient HyperCoord, so the
caller’s per-trial n×k ∂X/∂ψ slab is redundant (#1033). For the
sufficient-statistic kappa search this covers the full optimizer window;
otherwise the caller does not arm the n-free outer loop.
Sourcepub fn psi_gram_tensor_covers(&self, psi: f64) -> bool
pub fn psi_gram_tensor_covers(&self, psi: f64) -> bool
True when a certified ψ-Gram tensor is installed AND psi lies inside its
full certified VALUE window — i.e. the n-free assembled Gaussian
sufficient statistics XᵀWX(ψ)/XᵀWz(ψ) reproduce the streamed Gram to the
certification tolerance. The caller uses this to skip the per-trial O(n·p)
design realization + conditioning entirely (#1033): when the value lane is
covered, prepare_eval_state installs the n-free GaussianFixedCache, so
the stale realized design is never read for its rows on the inner Gaussian
PLS fast path. Strictly narrower-or-equal callers also gate on
psi_gram_tensor_covers_gradient for the gradient channel.
Sourcepub fn psi_gram_tensor_covers_skip(&self, psi: f64) -> bool
pub fn psi_gram_tensor_covers_skip(&self, psi: f64) -> bool
True when the design-realization SKIP to psi is β̂-SOUND given the
reference surface pinned at the last slow-path reset (#1264). Restored
after the “stale-penalty-not-stale-basis” theory was empirically refuted:
cluster measured β̂rel≈1.7e-5 (17× the issue’s 1e-6 bar) when the n-free κ skip
fires on production Duchon geometry — EVEN at a ψ the n-free VALUE window
admits — because the inner penalized solve (QsᵀGQs+S)β=b is run in the
CONDITIONED reduced basis, and that basis ROTATES with ψ on the near-
singular radial Gram (κ(G)≈9.5e14). The skip installs the Chebyshev-
interpolated gram_at(ψ) (≤1e-10 vs the streamed exact Gram), and when the
reduced basis at the trial ψ differs from the reference surface’s basis the
κ-amplified round-off moves the shipped κ-optimum past 1e-6.
So the skip is sound ONLY where the reduced basis is provably unchanged:
the gauge-invariant range-projector witness reduced_basis_equal(psi_ref, psi) against the pinning ψ recorded at the last slow-path reset. Without a
recorded pinning ψ (no reset yet) the skip is refused. Value coverage alone
is NOT sufficient — this is the load-bearing #1264 soundness gate.
Sourcepub fn nfree_fast_path_revision(&self) -> Option<u64>
pub fn nfree_fast_path_revision(&self) -> Option<u64>
Revision of the canonical surface pinned by the last slow-path
reset_surface, if any. The spatial κ caller passes this revision back
on certified n-free value/gradient probes so Self::prepare_eval_state
and Self::prepare_eval_state_cost_only take their design-revision fast
paths even if the caller-side realizer revision has since advanced on an
unrelated miss. The fast path re-keys the Gaussian Gram and S(ψ) from
k-space statistics, so it intentionally reuses this pinned surface rather
than requiring equality with the current realizer revision (#1033).
pub fn has_psi_gram_tensor(&self) -> bool
Sourcepub fn current_beta(&self) -> Option<Array1<f64>>
pub fn current_beta(&self) -> Option<Array1<f64>>
Return the most-recently converged inner β from the last PIRLS solve, if
it is finite and the right dimension. Used by SpatialJointContext to
warm-start successive outer evaluations instead of cold-starting PIRLS
from zero every iteration — especially important for GLM families (Poisson,
NB, Binomial) that cannot use the Gaussian Gram tensor n-free shortcut.
pub fn evaluate_with_order( &mut self, x: &DesignMatrix, s_list: &[BlockwisePenalty], nullspace_dims: &[usize], linear_constraints: Option<LinearInequalityConstraints>, theta: &Array1<f64>, rho_dim: usize, hyper_dirs: Vec<DirectionalHyperParam>, warm_start_beta: Option<ArrayView1<'_, f64>>, context: &str, order: OuterEvalOrder, design_revision: Option<u64>, ) -> Result<(f64, Array1<f64>, HessianResult), EstimationError>
pub fn evaluate_efs( &mut self, x: &DesignMatrix, s_list: &[BlockwisePenalty], nullspace_dims: &[usize], linear_constraints: Option<LinearInequalityConstraints>, theta: &Array1<f64>, rho_dim: usize, hyper_dirs: Vec<DirectionalHyperParam>, warm_start_beta: Option<ArrayView1<'_, f64>>, context: &str, design_revision: Option<u64>, ) -> Result<EfsEval, EstimationError>
Sourcepub fn evaluate_cost_only(
&mut self,
x: &DesignMatrix,
s_list: &[BlockwisePenalty],
nullspace_dims: &[usize],
linear_constraints: Option<LinearInequalityConstraints>,
theta: &Array1<f64>,
rho_dim: usize,
warm_start_beta: Option<ArrayView1<'_, f64>>,
context: &str,
design_revision: Option<u64>,
) -> Result<f64, EstimationError>
pub fn evaluate_cost_only( &mut self, x: &DesignMatrix, s_list: &[BlockwisePenalty], nullspace_dims: &[usize], linear_constraints: Option<LinearInequalityConstraints>, theta: &Array1<f64>, rho_dim: usize, warm_start_beta: Option<ArrayView1<'_, f64>>, context: &str, design_revision: Option<u64>, ) -> Result<f64, EstimationError>
Cost-only evaluation at the current κ-realized design. Used by the
joint [ρ, ψ] BFGS line-search cost callback so probes pay neither the
try_build_spatial_log_kappa_hyper_dirs cost nor the gradient assembly
cost. The gradient callback continues to use [evaluate_with_order].
Contract: the caller MUST have already realized the design at the κ
implied by theta’s ψ tail (typically via the
SingleBlockExactJointDesignCache::ensure_theta path). The penalty
gradients w.r.t. ρ are independent of κ for the spatial single-block
path, but correction gates still need to know that the objective lives
on a joint [ρ, ψ] surface. Pass the ψ-tail count into the shared cost
bridge so value-only probes decline the same ext-coordinate-incomplete
corrections as the analytic joint path.
Auto Trait Implementations§
impl<'a> !Freeze for ExternalJointHyperEvaluator<'a>
impl<'a> !RefUnwindSafe for ExternalJointHyperEvaluator<'a>
impl<'a> !Sync for ExternalJointHyperEvaluator<'a>
impl<'a> !UnwindSafe for ExternalJointHyperEvaluator<'a>
impl<'a> Send for ExternalJointHyperEvaluator<'a>
impl<'a> Unpin for ExternalJointHyperEvaluator<'a>
impl<'a> UnsafeUnpin for ExternalJointHyperEvaluator<'a>
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> 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.