pub struct BlockwiseFitOptions {Show 23 fields
pub inner_max_cycles: usize,
pub inner_tol: f64,
pub outer_max_iter: usize,
pub outer_tol: f64,
pub outer_rel_cost_tol: Option<f64>,
pub rho_lower_bound: f64,
pub minweight: f64,
pub ridge_floor: f64,
pub ridge_policy: RidgePolicy,
pub use_remlobjective: bool,
pub use_outer_hessian: bool,
pub compute_covariance: bool,
pub screening_max_inner_iterations: Option<Arc<Atomic<usize>>>,
pub outer_inner_max_iterations: Option<Arc<Atomic<usize>>>,
pub early_exit_threshold: Option<f64>,
pub outer_score_subsample: Option<Arc<OuterScoreSubsample>>,
pub auto_outer_subsample: bool,
pub outer_eval_context: Option<OuterEvalContext>,
pub cache_session: Option<Arc<Session>>,
pub cache_mirror_sessions: Vec<Arc<Session>>,
pub joint_penalties: Option<Arc<JointPenaltyBundle>>,
pub screen_initial_rho: bool,
pub seed_screening: bool,
}Expand description
Stable public API for installing outer-score subsampling.
Fields§
§inner_max_cycles: usize§inner_tol: f64§outer_max_iter: usize§outer_tol: f64§outer_rel_cost_tol: Option<f64>Optional override for the OUTER smoothing optimizer’s
relative-cost-decrease convergence stop, decoupled from outer_tol.
The outer convergence test derives BOTH the absolute projected-gradient
floor (max(outer_tol, n·1e-9)) AND the relative-cost stop
(rel_cost = outer_tol) from the single outer_tol. A caller that needs
a tight absolute floor to resolve λ to the genuine REML optimum at
large n (where the floor is n·1e-9) is then forced to also accept a
tight rel-cost stop, which on a flat REML ridge never trips and grinds
the optimizer to outer_max_iter — dozens of surplus O(D·p³)
Laplace-derivative outer iterations (the #1082 multinomial
smooth-by-factor wall-clock blow-up). When Some(r), the rel-cost stop
uses r while the absolute floor keeps using outer_tol, so accuracy
(absolute floor) and perf (loose rel-cost) are selected independently.
None preserves the legacy coupling (rel_cost = outer_tol) for every
existing caller byte-for-byte.
rho_lower_bound: f64Lower box bound for smoothing coordinates ρ = log λ.
The default preserves the historical custom-family domain
λ >= exp(-10). Families with known calibration failures at the
near-zero penalty boundary can raise this lower bound without changing
the upper effective-df cap or adding family-specific branches inside the
optimizer.
minweight: f64§ridge_floor: f64§ridge_policy: RidgePolicyShared ridge semantics used by solve/quadratic/logdet terms.
use_remlobjective: boolIf true, outer smoothing optimization uses a Laplace/REML-style objective: -loglik + penalty + 0.5(log|H| - log|S|_+) where H is blockwise working curvature and S is blockwise penalty.
use_outer_hessian: boolIf false, the outer smoothing optimizer uses exact gradients but does not request an analytic outer Hessian from the family.
compute_covariance: boolIf false, skip post-fit joint covariance assembly.
screening_max_inner_iterations: Option<Arc<Atomic<usize>>>Shared cap engaged during seed screening so cost-only evaluations can stop inner iterations early without affecting the full solve.
outer_inner_max_iterations: Option<Arc<Atomic<usize>>>Shared cap engaged during regular outer iterations. Unlike screening, this is only a budget: capped solves still have to earn the ordinary KKT certificate before derivatives may be exposed.
early_exit_threshold: Option<f64>Optional line-search objective ceiling for lazy log-likelihood-only
evaluations. Families whose per-row log-likelihood contributions are
non-positive may stop once the partial negative log-likelihood is already
above this ceiling, because the unvisited rows cannot improve the trial
objective enough to be accepted. Default None preserves exact full-sum
behavior and is the only mode used outside backtracking rejection tests.
outer_score_subsample: Option<Arc<OuterScoreSubsample>>Stable public API for installing outer-score subsampling.
Optional stratified row subsample used by outer-only score/gradient
passes. When Some(s), outer score/gradient hot loops should iterate
only over s.rows and multiply each contribution by that row’s
Horvitz-Thompson inverse-inclusion weight. Inner-PIRLS and final
covariance passes always run on the full data, so this field is
consulted only by outer-only call sites. Default None preserves the
full-data behavior. Wrapping in Arc keeps Clone cheap across the
many places BlockwiseFitOptions is duplicated per-eval.
auto_outer_subsample: boolGate for marginal-slope families to auto-derive a stratified
outer-score subsample at large scale (see
[crate::families::marginal_slope_shared::auto_outer_score_subsample]).
Default true. Auto-subsampling makes the early rho-gradient
evaluations unbiased stochastic estimators with bounded relative
variance (≈ 1 % at the conservative defaults), then the family switches
back to full-data gradients for the remaining outer iterations. That
keeps large marginal-slope fits fast during the high-motion part of the
trajectory while preserving the default tight outer_tol polish on
exact gradients. For small datasets the auto path declines to install a
mask and the fit remains full-data throughout.
When outer_score_subsample is already Some(...) the auto
path is bypassed entirely (caller-provided masks always win).
outer_eval_context: Option<OuterEvalContext>Outer-evaluation context populated by the smoothing optimizer at
the top of each real outer derivative evaluation. Used by
auto-subsample install paths to key the stratified mask on the
outer ρ rather than the inner β proxy: during the inner trust-
region / coefficient line search β changes on every trial step,
so keying on β re-fires phase prints (and re-shuffles the mask)
inside a single outer eval. Keying on (rho, eval_id) instead
keeps the mask stable across the inner Newton at one ρ, and
suppresses auto-subsample entirely on inner trial evaluations via
the [EvalScope::InnerCoefficient] tag set by
[coefficient_line_search_options].
None preserves legacy behavior (no context — install paths fall
back to “no auto-subsample”). Default None.
cache_session: Option<Arc<Session>>Optional persistent warm-start cache session. When Some, the
outer smoothing optimizer consults the on-disk cache before
starting (to seed θ from the last accepted iterate) and writes
checkpoints + a final entry on completion. When None, the fit
runs cold and writes nothing — the default for unit tests and
any caller that pinned a deterministic optimum.
Callers that need cross-process reuse must supply the session explicitly; ordinary workflow fits leave this empty so refit-heavy loops do not touch the shared on-disk store.
cache_mirror_sessions: Vec<Arc<Session>>Optional mirror sessions that receive a copy of the final-result finalize() write. Callers can use this to broadcast a converged ρ to additional keyspace(s) so future fits with related structure can warm-start from this run. Writes still pass through the session rate limiter, so mirroring checkpoints does not add unbounded I/O.
joint_penalties: Option<Arc<JointPenaltyBundle>>Optional bundle of cross-block (full-width) penalties, paired with
their current log λ values from the outer ρ vector. When Some,
the inner joint-Newton primitives add the contributions
- objective:
½ Σ_j exp(ρ_j) βᵀ S_j β - gradient:
Σ_j exp(ρ_j) S_j β - Hessian:
Σ_j exp(ρ_j) S_j
in addition to the per-block penalty stack assembled from
ParameterBlockSpec.penalties. The per-block path is unchanged.
None preserves legacy behaviour for every existing caller.
screen_initial_rho: boolWhether the outer smoothing optimizer screens the explicit
initial_rho seed through the seed-screening cascade before the
solver starts.
Default true — the general path benefits from ranking the
initial seed against the generated exploration seeds via cheap
capped proxy fits.
A caller sets this false when initial_rho is already the correct,
identified optimum for its regime so that re-screening it adds only
cost. The survival location-scale constant-scale (parametric-AFT)
path uses this: its time-warp ρ seed is pinned AT the inner ρ box
bound (the affine-baseline limit), where the REML/LAML profile is a
dead-flat unidentified ridge. Running the screening cascade there
drives each proxy fit (and, when every capped stage collapses to
non-finite cost, the uncapped final stage) into a full inner solve on
the near-singular flat Hessian — the source of the multi-minute
no-iteration-log stall (#736, #735, #721). Skipping screening lets the
already-correct seed flow straight to the outer solver, which certifies
box-constraint stationarity at iteration 0. Genuinely flexible regimes
(smooth scale / spatial) leave this true and keep full screening.
seed_screening: boolSet ONLY while the inner solve is invoked from the seed-screening proxy
(custom_family_seed_screening_proxy_labeled), which RANKS candidate
seeds by their penalized objective and never produces the final fit.
When true, the inner joint-Newton skips the full per-axis
Jeffreys/Firth curvature (custom_family_joint_jeffreys_term’s
for k in 0..p directional-derivative loop, O(p · per-axis-Hdot) per
cycle), keeping ONLY the cheap value-only Jeffreys term
(custom_family_joint_jeffreys_value, one reduced-info eigendecomposition)
in the screening score. The per-axis gradient/curvature is what the inner
Newton step needs to converge a near-separating fit; the screening proxy
is capped and only ranks, so it does not need step convergence — it needs
a finite, separation-aware score cheaply. For a K-block coupled family
(Dirichlet/multinomial) each per-axis directional derivative is itself
O(K²·n·p), so running the full term for every cascade candidate over the
joint width p is the wrong cost class and made the coupled fit
non-completing during screening alone (gam#729/#808). The actual fit
(after a seed is selected) runs with this false, so the load-bearing
Firth curvature is fully present where it matters.
Default false — only the screening proxy sets it true.
Trait Implementations§
Source§impl Clone for BlockwiseFitOptions
impl Clone for BlockwiseFitOptions
Source§fn clone(&self) -> BlockwiseFitOptions
fn clone(&self) -> BlockwiseFitOptions
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Default for BlockwiseFitOptions
impl Default for BlockwiseFitOptions
Source§fn default() -> BlockwiseFitOptions
fn default() -> BlockwiseFitOptions
Auto Trait Implementations§
impl Freeze for BlockwiseFitOptions
impl RefUnwindSafe for BlockwiseFitOptions
impl Send for BlockwiseFitOptions
impl Sync for BlockwiseFitOptions
impl Unpin for BlockwiseFitOptions
impl UnsafeUnpin for BlockwiseFitOptions
impl UnwindSafe for BlockwiseFitOptions
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.