gam_solve/rho_optimizer.rs
1//! Central authority for outer smoothing-parameter optimization strategy.
2//!
3//! Every path that optimizes smoothing parameters (standard REML, link-wiggle,
4//! GAMLSS custom family, spatial kappa, etc.) declares its derivative
5//! capability here and receives an [`OuterPlan`] that determines which solver
6//! and Hessian source to use.
7//!
8//! # Design invariant
9//!
10//! The planner never synthesizes numerical Hessians. If a path cannot provide
11//! an analytic Hessian, that fact is visible in its
12//! [`OuterCapability`] declaration and in the resulting [`OuterPlan`], which
13//! falls back to BFGS or an EFS variant instead of synthesizing second-order
14//! curvature numerically.
15
16use gam_runtime::warm_start::{LoadSource, Session as CacheSession};
17
18use crate::estimate::EstimationError;
19
20use crate::estimate::reml::reml_outer_engine::BarrierConfig;
21
22use crate::priority_selection::{
23 PriorityBudgetStage, PriorityStageSummary, rank_indices_with_budget_cascade,
24};
25
26use crate::startup_stats::{
27 SeedRejection, StartupStats, format_no_seeds_passed, uniform_structural_key,
28};
29
30use ::opt::{
31 Arc as ArcOptimizer, ArcError, Bfgs, BfgsError, Bounds, FallbackPolicy as OptFallbackPolicy,
32 FirstOrderObjective, FirstOrderSample, FixedPoint, FixedPointError, FixedPointObjective,
33 FixedPointSample, FixedPointStatus, GradientTolerance, HessianFallbackPolicy,
34 HessianMaterialization, HessianOperator, HessianValue, InitialMetric, MatrixFreeTrustRegion,
35 MaxIterations, ObjectiveEvalError, OperatorObjective, OperatorSample, OptimizationStatus,
36 OptimizerObserver, SecondOrderObjective, SecondOrderSample, Solution, StepInfo, Tolerance,
37 ZerothOrderObjective,
38};
39
40use ndarray::{Array1, Array2, ArrayView2};
41
42use std::sync::Arc;
43
44use std::sync::Mutex;
45
46use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
47
48mod bridges;
49mod capability;
50mod fd_audit; // fd-ok: FD-audit oracle module; verifies analytic gradients against FD, never in math path
51mod hessian_operator;
52mod objective;
53mod run;
54mod run_plan;
55mod seed_screening;
56
57pub(crate) use crate::model_types::CERTIFICATE_RAIL_MARGIN;
58pub use crate::model_types::CriterionCertificate;
59pub(crate) use bridges::*;
60pub use capability::*;
61// #1521 carve: the spatial-optimization driver runs the FD-audit oracle as
62// `gam_solve::rho_optimizer::outer_gradient_fd_audit` and inspects its
63// `OuterGradientFdAudit`/`OuterGradientFdComponent` result. Those three are the
64// only fd_audit items consumed outside the module, so they are its entire
65// re-export surface (a whole-module `pub(crate) use fd_audit::*` glob brought in
66// nothing else and was dead). The oracle is audit-only, never on the math path.
67pub use fd_audit::{OuterGradientFdAudit, OuterGradientFdComponent, outer_gradient_fd_audit}; // fd-ok: audit-only oracle, not in the math path
68pub use gam_problem::{HessianResult, OuterEval};
69pub use hessian_operator::*;
70pub use objective::*;
71pub(crate) use run::*;
72// Re-export the outer-problem driver at `pub` (not just `pub(crate)`) so the
73// gam-pyffi crate can construct it directly for the SAE joint-fit FFI path.
74pub use run::OuterProblem;
75// Re-export the outer-loop result struct at `pub` (the blanket `run` re-export
76// above is `pub(crate)`) so the lifted gam-models fit-orchestration driver can
77// name `gam_solve::rho_optimizer::OuterResult` (#1521).
78pub use run::OuterResult;
79pub(crate) use run_plan::*;
80// Re-export the outer wall-clock deadline arming at `pub` (the blanket
81// `run_plan` re-export above is `pub(crate)`) so the gam-pyffi SAE fit entry can
82// bound its outer search the same way the in-crate survival entry does.
83pub use run_plan::{
84 arm_outer_wall_clock_deadline, clear_outer_wall_clock_deadline,
85 outer_wall_clock_deadline_exceeded,
86};
87pub(crate) use seed_screening::*;