use super::*;
use ::opt::FixedPointObjective;
use ndarray::array;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
#[test]
fn certificate_attests_consistent_quadratic() {
let center = array![0.3, -0.7];
let cost_center = center.clone();
let grad_center = center.clone();
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_initial_rho(array![2.0, 2.0])
.with_seed_config(crate::seeding::SeedConfig {
max_seeds: 1,
seed_budget: 1,
..Default::default()
});
let mut obj = problem.build_objective(
(),
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - &cost_center;
Ok(0.5 * d.dot(&d))
},
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - &grad_center;
Ok(OuterEval {
cost: 0.5 * d.dot(&d),
gradient: d,
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "certificate consistent quadratic")
.expect("consistent quadratic must optimize");
let cert = result
.criterion_certificate
.as_ref()
.expect("gradient-based solve must ship a certificate");
assert!(
cert.first_order_consistent(),
"consistent value/gradient paths flagged as desynced: {}",
cert.summary(),
);
assert!(
cert.lambdas_railed.is_empty(),
"interior optimum reported railed λ: {}",
cert.summary(),
);
assert!(cert.fd_step > 0.0 && cert.fd_error > 0.0);
}
#[test]
fn rho_uncertainty_diagnostic_does_not_change_outer_solution() {
let center = array![0.25];
let seed_config = crate::seeding::SeedConfig {
max_seeds: 1,
seed_budget: 1,
..Default::default()
};
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_initial_rho(array![1.5])
.with_seed_config(seed_config)
.with_problem_size(8, 3);
let config = problem.config();
let mut without_diagnostic = problem.build_objective(
(),
{
let center = center.clone();
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - ¢er;
Ok(0.5 * d.dot(&d))
}
},
{
let center = center.clone();
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - ¢er;
Ok(OuterEval {
cost: 0.5 * d.dot(&d),
gradient: d,
hessian: HessianResult::Analytic(array![[1.0]]),
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut with_diagnostic = problem.build_objective(
(),
{
let center = center.clone();
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - ¢er;
Ok(0.5 * d.dot(&d))
}
},
{
let center = center.clone();
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - ¢er;
Ok(OuterEval {
cost: 0.5 * d.dot(&d),
gradient: d,
hessian: HessianResult::Analytic(array![[1.0]]),
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let baseline =
run_outer_uncertified(&mut without_diagnostic, &config, "rho-diagnostic-baseline")
.expect("baseline outer run");
let diagnosed = run_outer(&mut with_diagnostic, &config, "rho-diagnostic-run")
.expect("diagnostic outer run");
assert_eq!(baseline.rho, diagnosed.rho);
assert_eq!(
baseline.final_value.to_bits(),
diagnosed.final_value.to_bits()
);
assert_eq!(baseline.iterations, diagnosed.iterations);
assert_eq!(baseline.final_grad_norm, diagnosed.final_grad_norm);
assert!(diagnosed.rho_uncertainty_diagnostic.is_some());
}
#[test]
fn certificate_flags_value_gradient_desync() {
let value_center = array![0.0, 0.0];
let wrong_center = array![3.0, -2.0];
let wrong_center_for_eval = wrong_center.clone();
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_initial_rho(array![1.0, 1.0])
.with_seed_config(crate::seeding::SeedConfig {
max_seeds: 1,
seed_budget: 1,
..Default::default()
});
let mut obj = problem.build_objective(
(),
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - &value_center;
Ok(0.5 * d.dot(&d))
},
move |_: &mut (), rho: &Array1<f64>| {
let d = rho - &wrong_center_for_eval;
Ok(OuterEval {
cost: 0.5 * d.dot(&d),
gradient: d,
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "certificate desynced quadratic")
.expect("desynced quadratic still returns a result");
let cert = result
.criterion_certificate
.as_ref()
.expect("gradient-based solve must ship a certificate");
assert!(
cert.fd_directional.abs() > 1e-3,
"audit direction nearly orthogonal to the desync displacement: {}",
cert.summary(),
);
assert!(
!cert.first_order_consistent(),
"value↔gradient desync NOT flagged: {}",
cert.summary(),
);
assert!(cert.agreement_z > CERTIFICATE_Z_GATE);
}
#[test]
fn certificate_audit_direction_is_deterministic_and_context_sensitive() {
let theta = array![1.5, -0.25, 7.0];
let a = certificate_audit_direction(&theta, "ctx-one");
let b = certificate_audit_direction(&theta, "ctx-one");
assert_eq!(a, b, "same fingerprint must give the same direction");
let c = certificate_audit_direction(&theta, "ctx-two");
assert!(
(&a - &c).iter().any(|d| d.abs() > 1e-12),
"different context must give a different direction",
);
assert!((a.dot(&a).sqrt() - 1.0).abs() < 1e-12, "unit norm");
}
#[test]
fn certificate_hessian_pd_probe_classifies_definiteness() {
assert_eq!(
certificate_hessian_is_pd(&Array2::<f64>::eye(3)),
Some(true)
);
let indefinite = array![[1.0, 2.0], [2.0, 1.0]];
assert_eq!(certificate_hessian_is_pd(&indefinite), Some(false));
assert_eq!(
certificate_hessian_is_pd(&Array2::<f64>::zeros((0, 0))),
None
);
let non_finite = array![[f64::NAN]];
assert_eq!(certificate_hessian_is_pd(&non_finite), None);
}
#[test]
fn certificate_rail_detection_uses_outer_box() {
let config = OuterConfig::default(); let rho = array![29.8, 0.0, -29.6];
assert_eq!(certificate_railed_lambdas(&rho, 3, &config), vec![0, 2]);
assert_eq!(certificate_railed_lambdas(&rho, 1, &config), vec![0]);
let bounded = OuterConfig {
bounds: Some((array![-5.0, -5.0, -5.0], array![5.0, 5.0, 5.0])),
..OuterConfig::default()
};
let pinned = array![4.9, -4.7, 0.0];
assert_eq!(certificate_railed_lambdas(&pinned, 3, &bounded), vec![0, 1]);
}
fn audit_at_railed_optimum(
config: &OuterConfig,
theta_hat: Array1<f64>,
analytic_gradient: Array1<f64>,
value_slope_railed: f64,
) -> Option<CriterionCertificate> {
let slope = value_slope_railed;
let mut obj = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.build_objective(
(),
move |_: &mut (), rho: &Array1<f64>| {
Ok(0.5 * rho[0] * rho[0] + slope * rho[1])
},
move |_: &mut (), rho: &Array1<f64>| {
Ok(OuterEval {
cost: 0.5 * rho[0] * rho[0] + slope * rho[1],
gradient: array![rho[0], slope],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut result = OuterResult::new(
theta_hat,
0.0,
1,
true,
OuterPlan {
solver: Solver::Bfgs,
hessian_source: HessianSource::BfgsApprox,
},
);
result.final_gradient = Some(analytic_gradient);
audit_first_order_optimality(&mut obj, config, "railed-audit-unit", &result)
}
#[test]
fn certificate_does_not_false_flag_when_only_railed_coordinate_disagrees() {
let bounded = OuterConfig {
bounds: Some((array![-5.0, -5.0], array![5.0, 5.0])),
..OuterConfig::default()
};
let theta_hat = array![0.0, 5.0];
let analytic_gradient = array![0.0, -0.5];
let value_slope_railed = 7.0;
let full_dir = certificate_audit_direction(&theta_hat, "railed-audit-unit");
assert!(
full_dir[1].abs() > 1e-3,
"audit direction must have a non-trivial railed component to make \
the full-space check meaningful: {full_dir:?}",
);
let analytic_full = analytic_gradient.dot(&full_dir);
let fd_full_slope = value_slope_railed * full_dir[1];
assert!(
(analytic_full - fd_full_slope).abs() > 1e-2,
"full-direction analytic and value-path slopes should disagree \
(artifact precondition): analytic={analytic_full} fd≈{fd_full_slope}",
);
let cert = audit_at_railed_optimum(&bounded, theta_hat, analytic_gradient, value_slope_railed)
.expect("railed audit must still produce a certificate");
assert_eq!(
cert.lambdas_railed,
vec![1],
"coord 1 must be detected as railed: {}",
cert.summary(),
);
assert!(
cert.first_order_consistent(),
"railed-coordinate disagreement was FALSE-FLAGGED as a desync; the \
free subspace agrees, so this must be reported consistent: {}",
cert.summary(),
);
assert!(
cert.agreement_z < CERTIFICATE_Z_GATE,
"projected-onto-free z must be small: {}",
cert.summary(),
);
}
#[test]
fn certificate_still_fires_on_genuine_interior_gradient_desync() {
let bounded = OuterConfig {
bounds: Some((array![-5.0, -5.0], array![5.0, 5.0])),
..OuterConfig::default()
};
let theta_hat = array![2.5, 5.0];
let analytic_gradient = array![0.0, -0.5]; let value_slope_railed = 7.0;
let cert = audit_at_railed_optimum(&bounded, theta_hat, analytic_gradient, value_slope_railed)
.expect("railed audit must still produce a certificate");
assert_eq!(
cert.lambdas_railed,
vec![1],
"coord 1 railed: {}",
cert.summary()
);
assert!(
!cert.first_order_consistent(),
"genuine interior (free-coordinate) desync was masked by the railed \
projection — the certificate failed its core job: {}",
cert.summary(),
);
assert!(
cert.agreement_z > CERTIFICATE_Z_GATE,
"interior desync must exceed the z gate: {}",
cert.summary(),
);
}
#[test]
fn certificate_full_space_unchanged_when_nothing_railed() {
let bounded = OuterConfig {
bounds: Some((array![-30.0, -30.0], array![30.0, 30.0])),
..OuterConfig::default()
};
let theta_hat = array![0.0, 1.0];
let analytic_gradient = array![0.0, 7.0];
let cert = audit_at_railed_optimum(&bounded, theta_hat, analytic_gradient, 7.0)
.expect("interior audit must produce a certificate");
assert!(
cert.lambdas_railed.is_empty(),
"no coordinate is near a bound: {}",
cert.summary(),
);
assert!(
cert.first_order_consistent(),
"consistent interior optimum flagged: {}",
cert.summary(),
);
}
struct FailingSeedMaterializationOperator {
dim: usize,
}
impl OuterHessianOperator for FailingSeedMaterializationOperator {
fn dim(&self) -> usize {
self.dim
}
fn matvec(&self, v: &Array1<f64>) -> Result<Array1<f64>, String> {
Ok(v.clone())
}
fn is_cheap_to_materialize(&self) -> bool {
true
}
fn materialize_dense(&self) -> Result<Array2<f64>, String> {
Err("seed materialization failed".to_string())
}
}
#[test]
fn materialize_dense_uses_single_batched_mul_mat() {
struct BatchedOnlyHessian {
matrix: Array2<f64>,
matvec_calls: Arc<AtomicUsize>,
mul_mat_calls: Arc<AtomicUsize>,
rhs_columns: Arc<AtomicUsize>,
}
impl OuterHessianOperator for BatchedOnlyHessian {
fn dim(&self) -> usize {
self.matrix.nrows()
}
fn matvec(&self, v: &Array1<f64>) -> Result<Array1<f64>, String> {
self.matvec_calls.fetch_add(1, Ordering::Relaxed);
Ok(self.matrix.dot(v))
}
fn mul_mat(&self, factor: ArrayView2<'_, f64>) -> Result<Array2<f64>, String> {
self.mul_mat_calls.fetch_add(1, Ordering::Relaxed);
self.rhs_columns
.fetch_add(factor.ncols(), Ordering::Relaxed);
Ok(self.matrix.dot(&factor))
}
}
let matvec_calls = Arc::new(AtomicUsize::new(0));
let mul_mat_calls = Arc::new(AtomicUsize::new(0));
let rhs_columns = Arc::new(AtomicUsize::new(0));
let op = BatchedOnlyHessian {
matrix: array![[2.0, 0.25, -0.5], [0.5, 3.0, 1.0], [-0.25, 2.0, 4.0]],
matvec_calls: Arc::clone(&matvec_calls),
mul_mat_calls: Arc::clone(&mul_mat_calls),
rhs_columns: Arc::clone(&rhs_columns),
};
let dense = op
.materialize_dense()
.expect("batched dense materialization");
let expected = array![[2.0, 0.375, -0.375], [0.375, 3.0, 1.5], [-0.375, 1.5, 4.0]];
assert_eq!(dense, expected);
assert_eq!(
mul_mat_calls.load(Ordering::Relaxed),
1,
"dense materialization must batch all identity columns into one mul_mat call"
);
assert_eq!(
rhs_columns.load(Ordering::Relaxed),
3,
"the single batched materialization call must include every identity RHS"
);
assert_eq!(
matvec_calls.load(Ordering::Relaxed),
0,
"operators with batched mul_mat must not be probed column-by-column"
);
}
#[test]
fn plan_analytic_hessian_selects_arc() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 3,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn plan_prefer_gradient_only_does_not_hide_analytic_hessian() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 3,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: true,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn plan_survival_baseline_exact_hessian_selects_arc() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 3,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn plan_no_hessian_few_params_selects_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 3,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_no_hessian_many_params_selects_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 12,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_cost_only_few_params_fails_loudly_with_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 5,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
}
#[test]
fn plan_cost_only_many_params_with_fixed_point_still_efs() {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 20,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn plan_no_gradient_with_declared_hessian_stays_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Either,
n_params: 4,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_boundary_8_params_uses_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: SMALL_OUTER_BFGS_MAX_PARAMS,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_boundary_9_params_uses_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: SMALL_OUTER_BFGS_MAX_PARAMS + 1,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_efs_selected_for_penalty_like_many_params() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn plan_penalty_like_without_fixed_point_stays_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_efs_not_selected_few_params_even_if_penalty_like() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 5,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_efs_not_selected_with_analytic_hessian() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 20,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
}
#[test]
fn plan_efs_with_no_gradient_penalty_like_many_params() {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 20,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn plan_efs_allowed_with_barrier_config() {
let barrier = BarrierConfig {
tau: 1e-6,
constrained_indices: vec![0, 1],
lower_bounds: vec![0.0, 0.0],
bound_signs: vec![1.0, 1.0],
};
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: Some(barrier),
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn plan_efs_allowed_with_barrier_config_no_gradient() {
let barrier = BarrierConfig {
tau: 1e-6,
constrained_indices: vec![0],
lower_bounds: vec![0.0],
bound_signs: vec![1.0],
};
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 20,
psi_dim: 0,
fixed_point_available: true,
barrier_config: Some(barrier),
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn barrier_curvature_significant_blocks_efs_at_runtime() {
let barrier = BarrierConfig {
tau: 1e-6,
constrained_indices: vec![0],
lower_bounds: vec![0.0],
bound_signs: vec![1.0],
};
let beta_near = Array1::from_vec(vec![0.001]);
assert!(barrier.barrier_curvature_is_significant(&beta_near, 1.0, 0.01));
let beta_far = Array1::from_vec(vec![10.0]);
assert!(!barrier.barrier_curvature_is_significant(&beta_far, 1.0, 0.01));
}
#[test]
fn barrier_curvature_locally_concentrated_covers_both_failure_modes() {
let barrier = BarrierConfig {
tau: 1e-6,
constrained_indices: vec![0, 1],
lower_bounds: vec![0.0, 0.0],
bound_signs: vec![1.0, 1.0],
};
let mild_uniform = Array1::from_vec(vec![1.0e-2, 1.0e-2]);
assert!(!barrier.barrier_curvature_locally_concentrated(&mild_uniform, 0.1, 1.0));
let tight_uniform = Array1::from_vec(vec![1.0e-4, 1.0e-4]);
assert!(barrier.barrier_curvature_locally_concentrated(&tight_uniform, 0.1, 1.0));
assert!(!barrier.barrier_curvature_locally_concentrated(&tight_uniform, 0.1, 1.0e9));
let large_uniform = Array1::from_vec(vec![10.0, 10.0]);
assert!(!barrier.barrier_curvature_locally_concentrated(&large_uniform, 0.1, 1.0));
let imbalanced = Array1::from_vec(vec![1.0e-2, 1.0]);
assert!(barrier.barrier_curvature_locally_concentrated(&imbalanced, 0.1, 1.0));
assert!(!barrier.barrier_curvature_locally_concentrated(&imbalanced, 1.0e-3, 1.0e9));
let infeasible = Array1::from_vec(vec![-0.5, 1.0]);
assert!(barrier.barrier_curvature_locally_concentrated(&infeasible, 0.1, 1.0));
}
#[test]
fn hessian_result_unwrap_analytic() {
let h = Array2::<f64>::eye(3);
let result = HessianResult::Analytic(h.clone());
assert!(result.is_analytic());
let extracted = result.unwrap_analytic();
assert_eq!(extracted, h);
}
#[test]
#[should_panic(expected = "expected analytic Hessian")]
fn hessian_result_unwrap_unavailable_panics() {
let result = HessianResult::Unavailable;
result.unwrap_analytic();
}
#[test]
fn zero_params_selects_arc() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 0,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn hessian_result_into_option() {
let h = Array2::<f64>::eye(2);
let result = HessianResult::Analytic(h.clone());
assert_eq!(result.into_option(), Some(h));
let result = HessianResult::Unavailable;
assert_eq!(result.into_option(), None);
}
#[test]
fn closure_objective_delegates() {
let mut obj = ClosureObjective {
state: 42_i32,
cap: OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 1,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
},
cost_fn: |_: &mut i32, _: &Array1<f64>| Ok(1.0),
eval_fn: |_: &mut i32, _: &Array1<f64>| {
Ok(OuterEval {
cost: 1.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
eval_order_fn: None::<
fn(&mut i32, &Array1<f64>, OuterEvalOrder) -> Result<OuterEval, EstimationError>,
>,
reset_fn: Some(|st: &mut i32| {
*st = 42;
}),
efs_fn: None::<fn(&mut i32, &Array1<f64>) -> Result<EfsEval, EstimationError>>,
screening_proxy_fn: None::<fn(&mut i32, &Array1<f64>) -> Result<f64, EstimationError>>,
seed_fn: None::<fn(&mut i32, &Array1<f64>) -> Result<(), EstimationError>>,
continuation_prewarm: true,
};
assert_eq!(obj.capability().n_params, 1);
assert_eq!(obj.eval_cost(&Array1::zeros(1)).unwrap(), 1.0);
}
#[test]
fn closure_objective_seed_inner_state_delegates_when_hook_present() {
let mut obj = ClosureObjective {
state: Vec::<f64>::new(),
cap: OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 1,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
},
cost_fn: |_: &mut Vec<f64>, _: &Array1<f64>| Ok(0.0),
eval_fn: |_: &mut Vec<f64>, _: &Array1<f64>| {
Ok(OuterEval {
cost: 0.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
eval_order_fn: None::<
fn(&mut Vec<f64>, &Array1<f64>, OuterEvalOrder) -> Result<OuterEval, EstimationError>,
>,
reset_fn: None::<fn(&mut Vec<f64>)>,
efs_fn: None::<fn(&mut Vec<f64>, &Array1<f64>) -> Result<EfsEval, EstimationError>>,
screening_proxy_fn: None::<fn(&mut Vec<f64>, &Array1<f64>) -> Result<f64, EstimationError>>,
seed_fn: None::<fn(&mut Vec<f64>, &Array1<f64>) -> Result<(), EstimationError>>,
continuation_prewarm: true,
}
.with_seed_inner_state(|state: &mut Vec<f64>, beta: &Array1<f64>| {
state.extend(beta.iter().copied());
Ok(())
});
let outcome = obj.seed_inner_state(&array![1.5, -2.0]).unwrap();
assert_eq!(outcome, SeedOutcome::Installed);
assert_eq!(obj.state, vec![1.5, -2.0]);
}
#[test]
fn hybrid_efs_backtracking_uses_half_step_after_first_rejection() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 12,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let mut obj = ClosureObjective {
state: (),
cap: cap.clone(),
cost_fn: |_: &mut (), theta: &Array1<f64>| {
let psi = theta[11];
let cost = if (psi - 0.0).abs() < 1e-12 {
1.0
} else if (psi - 0.5).abs() < 1e-12 {
0.5
} else {
2.0
};
Ok(cost)
},
eval_fn: |_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: theta[11].abs(),
gradient: Array1::zeros(theta.len()),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
eval_order_fn: None::<
fn(&mut (), &Array1<f64>, OuterEvalOrder) -> Result<OuterEval, EstimationError>,
>,
reset_fn: None::<fn(&mut ())>,
efs_fn: Some(|_: &mut (), theta: &Array1<f64>| {
let mut steps = vec![0.0; theta.len()];
steps[11] = 1.0;
Ok(EfsEval {
cost: 1.0,
steps,
beta: None,
psi_gradient: Some(array![1.0]),
psi_indices: Some(vec![11]),
inner_hessian_scale: None,
logdet_enclosure_gap: None,
})
}),
screening_proxy_fn: None::<fn(&mut (), &Array1<f64>) -> Result<f64, EstimationError>>,
seed_fn: None::<fn(&mut (), &Array1<f64>) -> Result<(), EstimationError>>,
continuation_prewarm: true,
};
let mut bridge = OuterFixedPointBridge {
obj: &mut obj,
layout: cap.theta_layout(),
barrier_config: None,
fixed_point_tolerance: 1e-8,
consecutive_psi_zero_iters: 0,
};
let sample = bridge
.eval_step(&Array1::zeros(cap.n_params))
.expect("hybrid EFS step should backtrack cleanly");
assert_eq!(sample.status, FixedPointStatus::Continue);
assert_eq!(sample.step.len(), cap.n_params);
assert_eq!(sample.step[11], 0.5);
assert!(
sample
.step
.iter()
.enumerate()
.all(|(idx, &value)| idx == 11 || value == 0.0)
);
}
#[test]
fn run_bfgs_mode_aware_eval_skips_hessian_work() {
let seen_orders = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_initial_rho(array![1.0])
.with_max_iter(1);
let mut obj = problem.build_objective_with_eval_order(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| {
Err(EstimationError::InvalidInput(
"legacy eager eval should not run on BFGS".to_string(),
))
},
{
let seen_orders = Arc::clone(&seen_orders);
move |_: &mut (), theta: &Array1<f64>, order: OuterEvalOrder| {
seen_orders.lock().unwrap().push(order);
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "mode-aware bfgs first order")
.expect("BFGS should use the order-aware first-order bridge");
assert_eq!(result.plan_used.solver, Solver::Bfgs);
let seen_orders = seen_orders.lock().unwrap();
assert!(
!seen_orders.is_empty(),
"mode-aware eval hook should have been used"
);
assert!(
seen_orders
.iter()
.all(|order| *order != OuterEvalOrder::ValueGradientHessian),
"BFGS must not request Hessian work, saw {seen_orders:?}"
);
assert!(
seen_orders.contains(&OuterEvalOrder::ValueAndGradient),
"BFGS should request value+gradient at accepted points, saw {seen_orders:?}"
);
}
#[test]
fn first_order_bridge_keeps_true_gradient_on_repeated_flat_cost() {
let eval_calls = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable);
let mut obj = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(1000.0),
{
let eval_calls = Arc::clone(&eval_calls);
move |_: &mut (), _: &Array1<f64>| {
let call = eval_calls.fetch_add(1, Ordering::Relaxed);
let cost = match call {
0 => 999.9995,
1 => 999.9990,
_ => 999.9987,
};
Ok(OuterEval {
cost,
gradient: array![4.0],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut bridge = OuterFirstOrderBridge {
obj: &mut obj,
layout: OuterThetaLayout::new(1, 0),
outer_inner_cap: None,
iter_count: 0,
g_norm_initial: None,
last_g_norm: None,
last_value_grad_rho: None,
value_probe_cache: Vec::new(),
cost_stall: None,
consecutive_probe_refusals: 0,
};
let first = FirstOrderObjective::eval_grad(&mut bridge, &array![0.0])
.expect("first flat-cost eval should expose the true gradient");
let second = FirstOrderObjective::eval_grad(&mut bridge, &array![0.0])
.expect("second flat-cost eval should expose the true gradient");
let third = FirstOrderObjective::eval_grad(&mut bridge, &array![0.0])
.expect("third flat-cost eval should expose the true gradient");
let fourth = FirstOrderObjective::eval_grad(&mut bridge, &array![0.0])
.expect("fourth flat-cost eval should expose the true gradient");
assert_eq!(first.gradient[0], 4.0);
assert_eq!(second.gradient[0], 4.0);
assert_eq!(third.gradient[0], 4.0);
assert_eq!(fourth.gradient[0], 4.0);
assert_eq!(bridge.last_g_norm, Some(4.0));
assert_eq!(eval_calls.load(Ordering::Relaxed), 4);
}
#[test]
fn outer_second_order_bridge_separates_first_and_second_order_requests() {
let seen_orders = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either);
let mut obj = problem.build_objective_with_eval_order(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| {
Err(EstimationError::InvalidInput(
"legacy eager eval should not run".to_string(),
))
},
{
let seen_orders = Arc::clone(&seen_orders);
move |_: &mut (), theta: &Array1<f64>, order: OuterEvalOrder| {
seen_orders.lock().unwrap().push(order);
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: match order {
OuterEvalOrder::Value => HessianResult::Unavailable,
OuterEvalOrder::ValueAndGradient => HessianResult::Unavailable,
OuterEvalOrder::ValueGradientHessian => {
HessianResult::Analytic(array![[2.0]])
}
},
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut bridge = OuterSecondOrderBridge {
obj: &mut obj,
layout: OuterThetaLayout::new(1, 0),
hessian_source: HessianSource::Analytic,
materialize_operator_max_dim: OUTER_HVP_MATERIALIZE_MAX_DIM,
eval_count: 0,
outer_inner_cap: None,
g_norm_initial: None,
last_g_norm: None,
last_value_grad_rho: None,
};
let grad_sample = FirstOrderObjective::eval_grad(&mut bridge, &array![1.0]).expect("grad eval");
assert_eq!(grad_sample.value, 1.0);
assert_eq!(grad_sample.gradient, array![2.0]);
let hess_sample =
SecondOrderObjective::eval_hessian(&mut bridge, &array![1.0]).expect("hessian eval");
assert_eq!(hess_sample.value, 1.0);
assert_eq!(hess_sample.gradient, array![2.0]);
assert_eq!(hess_sample.hessian, Some(array![[2.0]]));
let seen_orders = seen_orders.lock().unwrap();
assert!(
*seen_orders
== vec![
OuterEvalOrder::ValueAndGradient,
OuterEvalOrder::ValueGradientHessian
],
"second-order bridge should split first-order and second-order requests, saw {seen_orders:?}"
);
}
#[test]
fn analytic_route_unavailable_hessian_is_fatal() {
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either);
let mut obj = problem.build_objective_with_eval_order(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| {
Err(EstimationError::InvalidInput(
"legacy eager eval should not run".to_string(),
))
},
move |_: &mut (), theta: &Array1<f64>, _order: OuterEvalOrder| {
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut bridge = OuterSecondOrderBridge {
obj: &mut obj,
layout: OuterThetaLayout::new(1, 0),
hessian_source: HessianSource::Analytic,
materialize_operator_max_dim: OUTER_HVP_MATERIALIZE_MAX_DIM,
eval_count: 0,
outer_inner_cap: None,
g_norm_initial: None,
last_g_norm: None,
last_value_grad_rho: None,
};
let err = SecondOrderObjective::eval_hessian(&mut bridge, &array![1.0])
.expect_err("Analytic route must reject Unavailable Hessian, not pass None to opt");
match err {
ObjectiveEvalError::Fatal { message } => {
assert!(
message.contains("HessianSource::Analytic") && message.contains("Unavailable"),
"fatal message should explain the analytic-route mismatch, saw: {message}"
);
}
ObjectiveEvalError::Recoverable { message } => panic!(
"Analytic-route Hessian violations must be Fatal (FD estimation is forbidden); \
got Recoverable: {message}"
),
}
}
#[test]
fn outer_config_default() {
let cfg = OuterConfig::default();
assert_eq!(cfg.tolerance, 1e-5);
assert_eq!(cfg.max_iter, 200);
assert_eq!(cfg.rho_bound, 30.0);
}
#[test]
fn plan_hybrid_efs_selected_for_psi_coords_many_params() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::HybridEfs);
assert_eq!(p.hessian_source, HessianSource::HybridEfsFixedPoint);
}
#[test]
fn plan_psi_without_fixed_point_stays_bfgs() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 1,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_hybrid_efs_no_gradient_selected_for_psi_coords() {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::HybridEfs);
assert_eq!(p.hessian_source, HessianSource::HybridEfsFixedPoint);
}
fn cap_for_routing(
gradient: Derivative,
hessian: DeclaredHessianForm,
n_params: usize,
) -> OuterCapability {
OuterCapability {
gradient,
hessian,
n_params,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
}
}
#[test]
fn routing_analytic_analytic_stays_arc_at_large_scale() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 6);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_analytic_analytic_stays_arc_at_dense_work_scale() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 3);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_unavailable_hessian_routes_to_bfgs() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Unavailable, 8);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn routing_explicit_prefer_gradient_only_does_not_override_exact_hessian() {
let mut cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 6);
cap.prefer_gradient_only = true;
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_log_line_arc_analytic_does_not_advertise_matrix_free() {
let p = OuterPlan {
solver: Solver::Arc,
hessian_source: HessianSource::Analytic,
};
let line = p.routing_log_line();
assert!(line.contains("solver=Arc"), "got {line}");
assert!(line.contains("hessian=Analytic"), "got {line}");
assert!(line.contains("matrix-free=false"), "got {line}");
}
#[test]
fn routing_log_line_bfgs_reports_no_matrix_free() {
let p = OuterPlan {
solver: Solver::Bfgs,
hessian_source: HessianSource::BfgsApprox,
};
let line = p.routing_log_line();
assert!(line.contains("solver=Bfgs"), "got {line}");
assert!(line.contains("hessian=BfgsApprox"), "got {line}");
assert!(line.contains("matrix-free=false"), "got {line}");
}
#[test]
fn routing_log_line_efs_reports_no_matrix_free() {
for source in [
HessianSource::EfsFixedPoint,
HessianSource::HybridEfsFixedPoint,
] {
let p = OuterPlan {
solver: Solver::Efs,
hessian_source: source,
};
assert!(
p.routing_log_line().contains("matrix-free=false"),
"{:?} should not advertise matrix-free",
source
);
}
}
#[test]
fn routing_custom_family_gamlss_stays_on_arc_when_both_derivs_analytic() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 4);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_matern_iso_kappa_stays_on_arc_when_both_derivs_analytic() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 5);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_matern_iso_large_kappa_dim_stays_on_arc_with_analytic_hessian() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 37,
psi_dim: 31,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn routing_marginal_slope_stays_on_arc_when_both_derivs_analytic() {
let cap = cap_for_routing(Derivative::Analytic, DeclaredHessianForm::Either, 3);
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn plan_hybrid_efs_not_selected_few_params() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 5,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn plan_exact_hvp_capability_selects_arc_even_when_fixed_point_is_available() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 64,
psi_dim: 16,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: true,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
assert_eq!(p.hessian_source, HessianSource::Analytic);
}
#[test]
fn plan_hybrid_efs_not_selected_with_analytic_hessian() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 20,
psi_dim: 1,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Arc);
}
#[test]
fn plan_pure_efs_not_hybrid_when_all_penalty_like() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Efs);
assert_eq!(p.hessian_source, HessianSource::EfsFixedPoint);
}
#[test]
fn automatic_fallbacks_preserve_analytic_hessian_for_arc_primary() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 12,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&cap).solver, Solver::Arc);
let attempts = automatic_fallback_attempts(&cap);
assert!(
attempts.is_empty(),
"ARC primary must not lateral-demote to BFGS+BfgsApprox; \
ARC budget retries live in the runner",
);
}
#[test]
fn automatic_fallbacks_from_efs_prefer_analytic_bfgs_over_fd() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&cap).solver, Solver::Efs);
let attempts = automatic_fallback_attempts(&cap);
assert!(!attempts.is_empty(), "EFS failure must have a fallback");
assert_eq!(attempts[0].gradient, Derivative::Analytic);
assert_eq!(attempts[0].hessian, DeclaredHessianForm::Unavailable);
assert!(attempts[0].disable_fixed_point);
assert_eq!(plan(&attempts[0]).solver, Solver::Bfgs);
assert!(
attempts.iter().all(|c| c.gradient == Derivative::Analytic),
"fallback cascade must stay on analytic-gradient attempts",
);
}
#[test]
fn automatic_fallbacks_from_hybrid_efs_prefer_analytic_bfgs_over_fd() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 2,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&cap).solver, Solver::HybridEfs);
let attempts = automatic_fallback_attempts(&cap);
assert!(!attempts.is_empty());
assert_eq!(attempts[0].gradient, Derivative::Analytic);
assert!(attempts[0].disable_fixed_point);
assert_eq!(plan(&attempts[0]).solver, Solver::Bfgs);
}
#[test]
fn disabled_fallback_hybrid_efs_capability_routes_to_bfgs_primary() {
let trapped_cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 9,
psi_dim: 6,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&trapped_cap).solver, Solver::HybridEfs);
let disabled_config = OuterConfig {
fallback_policy: FallbackPolicy::Disabled,
..OuterConfig::default()
};
let primary_cap = primary_capability_for_config(
trapped_cap.clone(),
&disabled_config,
"large-scale exact adaptive",
);
assert!(primary_cap.disable_fixed_point);
assert_eq!(plan(&primary_cap).solver, Solver::Bfgs);
let pure_efs_cap = OuterCapability {
psi_dim: 0,
..trapped_cap.clone()
};
assert_eq!(plan(&pure_efs_cap).solver, Solver::Efs);
let pure_primary_cap =
primary_capability_for_config(pure_efs_cap.clone(), &disabled_config, "pure EFS");
assert!(!pure_primary_cap.disable_fixed_point);
assert_eq!(plan(&pure_primary_cap).solver, Solver::Efs);
let no_gradient_cap = OuterCapability {
gradient: Derivative::Unavailable,
..trapped_cap.clone()
};
assert_eq!(plan(&no_gradient_cap).solver, Solver::HybridEfs);
let no_gradient_primary_cap = primary_capability_for_config(
no_gradient_cap.clone(),
&disabled_config,
"gradient-unavailable hybrid EFS",
);
assert!(!no_gradient_primary_cap.disable_fixed_point);
assert_eq!(plan(&no_gradient_primary_cap).solver, Solver::HybridEfs);
let automatic_config = OuterConfig::default();
let automatic_cap = primary_capability_for_config(
trapped_cap.clone(),
&automatic_config,
"large-scale exact adaptive",
);
assert!(!automatic_cap.disable_fixed_point);
assert_eq!(plan(&automatic_cap).solver, Solver::HybridEfs);
let automatic_attempts = automatic_fallback_attempts(&trapped_cap);
assert!(!automatic_attempts.is_empty());
assert!(automatic_attempts[0].disable_fixed_point);
assert_eq!(plan(&automatic_attempts[0]).solver, Solver::Bfgs);
}
#[test]
fn disabled_fallback_hybrid_efs_problem_uses_bfgs_without_calling_efs() {
let efs_calls = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(9)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_psi_dim(6)
.with_fallback_policy(FallbackPolicy::Disabled)
.with_initial_rho(Array1::zeros(9))
.with_max_iter(5);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(0.5 * theta.dot(theta)),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: 0.5 * theta.dot(theta),
gradient: theta.clone(),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
{
let efs_calls = Arc::clone(&efs_calls);
Some(move |_: &mut (), _: &Array1<f64>| {
efs_calls.fetch_add(1, Ordering::Relaxed);
Err(EstimationError::RemlOptimizationFailed(format!(
"{} synthetic large-scale adaptive HybridEFS escape",
EFS_FIRST_ORDER_FALLBACK_MARKER,
)))
})
},
);
let result = problem
.run(&mut obj, "disabled fallback marker")
.expect("disabled-fallback HybridEFS-shaped problem should route directly to BFGS");
assert_eq!(result.plan_used.solver, Solver::Bfgs);
assert_eq!(
efs_calls.load(Ordering::Relaxed),
0,
"central primary-capability canonicalization should avoid the EFS hook entirely"
);
}
#[test]
fn automatic_fallbacks_without_gradient_stop_at_fixed_point_status() {
for (psi_dim, expected_solver) in [(0, Solver::Efs), (2, Solver::HybridEfs)] {
let cap = OuterCapability {
gradient: Derivative::Unavailable,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&cap).solver, expected_solver);
assert!(
automatic_fallback_attempts(&cap).is_empty(),
"gradient-unavailable fixed-point capabilities must not fabricate a BFGS fallback",
);
}
}
#[test]
fn automatic_fallbacks_do_not_repeat_arc_when_fixed_point_is_irrelevant() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Either,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
};
assert_eq!(plan(&cap).solver, Solver::Arc);
let attempts = automatic_fallback_attempts(&cap);
assert!(
attempts.is_empty(),
"ARC primary with incidental fixed_point_available must not \
cascade through the EFS arm or lateral-demote to BFGS",
);
}
#[test]
fn plan_disable_fixed_point_forces_bfgs_even_when_efs_eligible() {
let cap = OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Unavailable,
n_params: 15,
psi_dim: 0,
fixed_point_available: true,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: true,
};
let p = plan(&cap);
assert_eq!(p.solver, Solver::Bfgs);
assert_eq!(p.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn run_malformed_gradient_seed_surfaces_as_error() {
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_initial_rho(Array1::zeros(2))
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(0.0),
|_: &mut (), _: &Array1<f64>| {
Ok(OuterEval {
cost: 0.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let err = problem
.run(&mut obj, "test gradient mismatch")
.expect_err("malformed analytic gradient must surface as error");
assert!(
matches!(err, EstimationError::RemlOptimizationFailed(_)),
"unexpected error variant: {err:?}",
);
}
#[test]
fn run_bfgs_ignores_malformed_hessian_payload() {
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_initial_rho(array![0.0])
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Analytic(array![[f64::NAN, 0.0], [0.0, 1.0]]),
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "bfgs should ignore malformed hessian payload")
.expect("valid first-order data should be enough for BFGS");
assert_eq!(result.plan_used.solver, Solver::Bfgs);
assert_eq!(result.plan_used.hessian_source, HessianSource::BfgsApprox);
}
#[test]
fn finite_outer_eval_reports_gradient_length_mismatch() {
let err = finite_outer_eval_or_error(
"test gradient mismatch",
OuterThetaLayout::new(2, 0),
OuterEval {
cost: 0.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
},
)
.expect_err("gradient mismatch should be rejected");
let message = match err {
ObjectiveEvalError::Recoverable { message } | ObjectiveEvalError::Fatal { message } => {
message
}
};
assert!(
message.contains("outer gradient length mismatch"),
"unexpected error: {message}"
);
}
#[test]
fn run_with_initial_seed_still_considers_generated_candidates() {
let generated =
crate::seeding::generate_rho_candidates(1, None, &crate::seeding::SeedConfig::default());
let valid_seed = generated
.first()
.expect("seed generator should yield at least one candidate")
.clone();
let expected_seed = valid_seed.clone();
let initial_seed = array![9.0];
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_initial_rho(initial_seed)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let valid_seed = valid_seed.clone();
move |_: &mut (), theta: &Array1<f64>| {
if theta == valid_seed {
Ok(0.0)
} else {
Ok(f64::INFINITY)
}
}
},
move |_: &mut (), theta: &Array1<f64>| {
if theta == valid_seed {
Ok(OuterEval {
cost: 0.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
} else {
Ok(OuterEval::infeasible(theta.len()))
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "generated seed should remain reachable")
.expect("generated seed should still be eligible when an initial seed is provided");
assert_eq!(result.rho, expected_seed);
}
#[test]
fn run_indefinite_analytic_seed_stays_on_arc() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_initial_rho(array![0.0])
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Analytic(array![[-1.0]]),
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "indefinite seed geometry")
.expect("indefinite analytic seed geometry should stay on the second-order plan");
assert_eq!(result.plan_used.solver, Solver::Arc);
assert_eq!(result.plan_used.hessian_source, HessianSource::Analytic);
}
#[test]
fn run_seed_materialization_failure_surfaces_arc_error_verbatim() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_initial_rho(array![0.0])
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Operator(Arc::new(FailingSeedMaterializationOperator {
dim: 1,
})),
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let err = problem
.run(&mut obj, "seed materialization failure")
.expect_err(
"ARC primary must surface the materialization failure verbatim — \
no lateral demote to BFGS+BfgsApprox",
);
let msg = err.to_string();
assert!(
msg.contains("seed materialization failed"),
"error must propagate the underlying materialization message; got: {msg}"
);
}
#[test]
fn run_nonconverged_arc_stays_on_arc_after_budget_retry_ladder() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let (_d, session) = tmp_cache_session("nonconverged-arc-cache");
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_initial_rho(array![5.0])
.with_max_iter(1)
.with_cache_session(Arc::clone(&session));
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0].powi(4)),
|_: &mut (), theta: &Array1<f64>| {
let x = theta[0];
Ok(OuterEval {
cost: x.powi(4),
gradient: array![4.0 * x.powi(3)],
hessian: HessianResult::Analytic(array![[12.0 * x.powi(2)]]),
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "nonconverged arc should stay on arc")
.expect(
"ARC ladder must surface the last non-converged ARC result rather than \
demoting to BFGS+BfgsApprox",
);
assert_eq!(
result.plan_used.solver,
Solver::Arc,
"ARC primary must not lateral-demote after budget exhaustion"
);
assert_eq!(
result.plan_used.hessian_source,
HessianSource::Analytic,
"analytic outer Hessian must be preserved across the budget-bump retry ladder"
);
assert!(
!result.converged,
"test fixture is engineered so the ladder cannot converge; \
converged=true would mean the fixture stopped exercising the ladder"
);
}
#[test]
fn candidate_selection_prefers_lower_cost_within_same_convergence_class() {
let plan = OuterPlan {
solver: Solver::Bfgs,
hessian_source: HessianSource::BfgsApprox,
};
let mut nonconverged_hi = OuterResult::new(array![0.0], 9.0, 1, false, plan);
nonconverged_hi.final_grad_norm = Some(1.0);
let mut nonconverged_lo = OuterResult::new(
array![1.0],
1.0,
1,
false,
OuterPlan {
solver: Solver::Bfgs,
hessian_source: HessianSource::BfgsApprox,
},
);
nonconverged_lo.final_grad_norm = Some(1.0);
let mut converged = OuterResult::new(
array![2.0],
5.0,
1,
true,
OuterPlan {
solver: Solver::Bfgs,
hessian_source: HessianSource::BfgsApprox,
},
);
converged.final_grad_norm = Some(0.0);
assert!(candidate_improves_best(&nonconverged_hi, None));
assert!(candidate_improves_best(
&nonconverged_lo,
Some(&nonconverged_hi)
));
assert!(!candidate_improves_best(
&nonconverged_hi,
Some(&nonconverged_lo)
));
assert!(candidate_improves_best(&converged, Some(&nonconverged_lo)));
assert!(!candidate_improves_best(&nonconverged_lo, Some(&converged)));
}
#[test]
fn gaussian_multistart_compares_converged_seed_costs() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 2;
seed_config.risk_profile = crate::seeding::SeedRiskProfile::Gaussian;
let started = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_max_iter(4);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(if theta[0] < -1.0 { 0.0 } else { 10.0 }),
{
let started = Arc::clone(&started);
move |_: &mut (), theta: &Array1<f64>| {
started.lock().unwrap().push(theta.clone());
Ok(OuterEval {
cost: if theta[0] < -1.0 { 0.0 } else { 10.0 },
gradient: array![0.0],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "Gaussian quality multistart")
.expect("Gaussian multistart should compare both converged seeds");
let starts = started.lock().unwrap();
assert!(
starts.len() >= 2,
"Gaussian quality mode should not stop at the first converged seed"
);
assert!(
result.rho[0] < -1.0,
"lower-cost converged Gaussian seed should win"
);
assert_eq!(result.final_value, 0.0);
}
#[test]
fn run_starts_solver_with_direct_startup_eval() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let calls = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let calls = Arc::clone(&calls);
move |_: &mut (), theta: &Array1<f64>| {
calls.lock().unwrap().push("cost");
Ok(theta[0] * theta[0])
}
},
{
let calls = Arc::clone(&calls);
move |_: &mut (), theta: &Array1<f64>| {
calls.lock().unwrap().push("eval");
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Analytic(array![[2.0]]),
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
problem
.run(&mut obj, "solver should start from a direct startup eval")
.expect("analytic plans should start with a direct full evaluation");
let calls = calls.lock().unwrap();
let first_eval_idx = calls
.iter()
.position(|call| *call == "eval")
.expect("solver should eventually request a full eval");
assert!(
first_eval_idx == 0,
"startup should not perform a separate cost-screening pass first: {calls:?}"
);
}
#[test]
fn run_screening_reorders_expensive_generated_seeds_before_full_startup_eval() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 4;
seed_config.seed_budget = 2;
seed_config.risk_profile = crate::seeding::SeedRiskProfile::GeneralizedLinear;
let screening_cap = Arc::new(AtomicUsize::new(0));
let valid_seed = crate::seeding::generate_rho_candidates(1, None, &seed_config)
.last()
.expect("seed generator should yield at least one candidate")
.clone();
let started = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_screening_cap(Arc::clone(&screening_cap))
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let valid_seed = valid_seed.clone();
move |_: &mut (), theta: &Array1<f64>| {
if theta == valid_seed {
Ok(0.0)
} else {
Ok(1000.0)
}
}
},
{
let valid_seed = valid_seed.clone();
let started = Arc::clone(&started);
move |_: &mut (), theta: &Array1<f64>| {
started.lock().unwrap().push(theta.clone());
if theta == valid_seed {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Analytic(array![[1.0]]),
inner_beta_hint: None,
})
} else {
Ok(OuterEval::infeasible(theta.len()))
}
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "screening should reorder expensive seeds")
.expect("screened startup should reach the best generated seed");
assert_eq!(result.rho, valid_seed);
assert_eq!(
started.lock().unwrap().first().cloned(),
Some(valid_seed),
"screening should move the lowest-cost seed to the front before full startup eval",
);
assert_eq!(screening_cap.load(std::sync::atomic::Ordering::Relaxed), 0);
}
#[test]
fn initial_rho_with_single_seed_budget_skips_expensive_screening() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 4;
seed_config.seed_budget = 1;
seed_config.risk_profile = crate::seeding::SeedRiskProfile::GeneralizedLinear;
let screening_cap = Arc::new(AtomicUsize::new(0));
let screening_calls = Arc::new(AtomicUsize::new(0));
let initial_seed = array![9.0];
let started = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_screening_cap(Arc::clone(&screening_cap))
.with_initial_rho(initial_seed.clone())
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let screening_calls = Arc::clone(&screening_calls);
move |_: &mut (), _theta: &Array1<f64>| {
screening_calls.fetch_add(1, Ordering::Relaxed);
Ok(0.0)
}
},
{
let started = Arc::clone(&started);
let initial_seed = initial_seed.clone();
move |_: &mut (), theta: &Array1<f64>| {
started.lock().unwrap().push(theta.clone());
if theta == initial_seed {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Analytic(array![[1.0]]),
inner_beta_hint: None,
})
} else {
Ok(OuterEval::infeasible(theta.len()))
}
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "initial rho should be authoritative")
.expect("initial-rho startup should not spend seed-screening solves");
assert_eq!(result.rho, initial_seed);
assert_eq!(
screening_calls.load(Ordering::Relaxed),
0,
"explicit initial rho plus seed_budget=1 should skip screening"
);
assert_eq!(
started.lock().unwrap().first().cloned(),
Some(initial_seed),
"solver should start from the explicit initial rho"
);
assert_eq!(screening_cap.load(Ordering::Relaxed), 0);
}
#[test]
fn run_screening_reorders_bfgs_seeds_before_full_startup_eval() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
seed_config.risk_profile = crate::seeding::SeedRiskProfile::Gaussian;
let screening_cap = Arc::new(AtomicUsize::new(0));
let initial_seed = array![9.0];
let valid_seed = crate::seeding::generate_rho_candidates(1, None, &seed_config)
.first()
.expect("seed generator should yield at least one candidate")
.clone();
let started = Arc::new(Mutex::new(Vec::new()));
let screening_calls = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_screening_cap(Arc::clone(&screening_cap))
.with_initial_rho(initial_seed)
.with_screen_initial_rho(true)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let valid_seed = valid_seed.clone();
let screening_calls = Arc::clone(&screening_calls);
move |_: &mut (), theta: &Array1<f64>| {
screening_calls.fetch_add(1, Ordering::Relaxed);
if theta == valid_seed {
Ok(0.0)
} else {
Ok(1000.0)
}
}
},
{
let valid_seed = valid_seed.clone();
let started = Arc::clone(&started);
move |_: &mut (), theta: &Array1<f64>| {
started.lock().unwrap().push(theta.clone());
if theta == valid_seed {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
} else {
Ok(OuterEval::infeasible(theta.len()))
}
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let result = problem
.run(&mut obj, "BFGS screening should reorder expensive seeds")
.expect("screened BFGS startup should reach the best generated seed");
assert_eq!(result.plan_used.solver, Solver::Bfgs);
assert_eq!(result.rho, valid_seed);
assert_eq!(
started.lock().unwrap().first().cloned(),
Some(valid_seed),
"BFGS screening should move the lowest-cost seed to the front before full startup eval",
);
assert!(
screening_calls.load(Ordering::Relaxed) > 1,
"BFGS seed screening should rank candidates with cost-only probes first",
);
assert_eq!(screening_cap.load(Ordering::Relaxed), 0);
}
#[test]
fn screening_cap_survives_per_seed_reset_before_proxy_eval() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 3;
seed_config.seed_budget = 1;
seed_config.risk_profile = crate::seeding::SeedRiskProfile::Gaussian;
let screening_cap = Arc::new(AtomicUsize::new(0));
let proxy_saw_cap = Arc::new(AtomicBool::new(false));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_screening_cap(Arc::clone(&screening_cap))
.with_max_iter(1);
let mut obj = problem.build_objective_with_screening_proxy(
(),
|_: &mut (), _: &Array1<f64>| Ok(0.0),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: theta[0].abs(),
gradient: array![0.0],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
|_: &mut (), theta: &Array1<f64>, _: OuterEvalOrder| {
Ok(OuterEval {
cost: theta[0].abs(),
gradient: array![0.0],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
{
let screening_cap = Arc::clone(&screening_cap);
Some(move |_: &mut ()| {
screening_cap.store(0, Ordering::Relaxed);
})
},
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
{
let screening_cap = Arc::clone(&screening_cap);
let proxy_saw_cap = Arc::clone(&proxy_saw_cap);
move |_: &mut (), theta: &Array1<f64>| {
let cap = screening_cap.load(Ordering::Relaxed);
if cap > 0 {
proxy_saw_cap.store(true, Ordering::Relaxed);
Ok(theta[0].abs())
} else {
Err(EstimationError::RemlOptimizationFailed(
"screening proxy ran without an active cap".to_string(),
))
}
}
},
);
problem
.run(&mut obj, "screening cap reset regression")
.expect("screening cap should be restored after each per-seed reset");
assert!(
proxy_saw_cap.load(Ordering::Relaxed),
"screening proxy should observe a nonzero cap"
);
assert_eq!(screening_cap.load(Ordering::Relaxed), 0);
}
#[test]
fn rank_seeds_cascade_escalates_when_initial_cap_collapses_all() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
seed_config.screen_max_inner_iterations = 3;
let screening_cap = Arc::new(AtomicUsize::new(0));
let initial_seed = array![5.0];
let valid_seed = crate::seeding::generate_rho_candidates(1, None, &seed_config)
.first()
.expect("seed generator should yield at least one candidate")
.clone();
let max_cap_seen = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_seed_config(seed_config)
.with_screening_cap(Arc::clone(&screening_cap))
.with_initial_rho(initial_seed.clone())
.with_screen_initial_rho(true)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let screening_cap = Arc::clone(&screening_cap);
let max_cap_seen = Arc::clone(&max_cap_seen);
let valid_seed = valid_seed.clone();
move |_: &mut (), theta: &Array1<f64>| {
let cap = screening_cap.load(Ordering::Relaxed);
max_cap_seen.fetch_max(cap, Ordering::Relaxed);
if cap > 0 && cap < 12 {
return Ok(f64::NAN);
}
if theta == valid_seed {
Ok(0.0)
} else {
Ok(1000.0)
}
}
},
{
let valid_seed = valid_seed.clone();
move |_: &mut (), theta: &Array1<f64>| {
if theta == valid_seed {
Ok(OuterEval {
cost: 0.0,
gradient: array![0.0],
hessian: HessianResult::Analytic(array![[1.0]]),
inner_beta_hint: None,
})
} else {
Ok(OuterEval::infeasible(theta.len()))
}
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
problem
.run(&mut obj, "cascade should escalate")
.expect("cascade should reach a finite cost at the 4× cap stage");
let max_cap = max_cap_seen.load(Ordering::Relaxed);
assert_eq!(
max_cap, 12,
"cascade should stop at the 4× cap stage; observed max cap = {max_cap}"
);
assert_eq!(
screening_cap.load(Ordering::Relaxed),
0,
"screening cap must be restored to its previous value after cascade"
);
}
#[test]
fn run_efs_skips_global_cost_screening() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 6;
seed_config.seed_budget = 1;
let screening_calls = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(15)
.with_gradient(Derivative::Unavailable)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
{
let screening_calls = Arc::clone(&screening_calls);
move |_: &mut (), _: &Array1<f64>| {
screening_calls.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
Ok(0.0)
}
},
|_: &mut (), theta: &Array1<f64>| Ok(OuterEval::infeasible(theta.len())),
None::<fn(&mut ())>,
Some(|_: &mut (), theta: &Array1<f64>| {
Ok(EfsEval {
cost: 0.0,
steps: vec![0.0; theta.len()],
beta: None,
psi_gradient: None,
psi_indices: None,
inner_hessian_scale: None,
logdet_enclosure_gap: None,
})
}),
);
problem
.run(
&mut obj,
"EFS should not use a separate global cost-screening pass",
)
.expect("first generated EFS seed should be sufficient");
assert_eq!(
screening_calls.load(std::sync::atomic::Ordering::Relaxed),
0,
"EFS startup should not call eval_cost just to screen seeds"
);
}
#[test]
fn run_efs_skips_invalid_leading_seed_without_spending_budget() {
let generated =
crate::seeding::generate_rho_candidates(15, None, &crate::seeding::SeedConfig::default());
let valid_seed = generated
.first()
.expect("seed generator should yield at least one candidate")
.clone();
let invalid_seed = Array1::from_elem(15, 9.0);
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 1;
let problem = OuterProblem::new(15)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_initial_rho(invalid_seed)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(0.0),
|_: &mut (), theta: &Array1<f64>| Ok(OuterEval::infeasible(theta.len())),
None::<fn(&mut ())>,
{
let valid_seed = valid_seed.clone();
Some(move |_: &mut (), theta: &Array1<f64>| {
if theta == valid_seed {
Ok(EfsEval {
cost: 0.0,
steps: vec![0.0; theta.len()],
beta: None,
psi_gradient: None,
psi_indices: None,
inner_hessian_scale: None,
logdet_enclosure_gap: None,
})
} else {
Err(EstimationError::RemlOptimizationFailed(
"invalid EFS seed".to_string(),
))
}
})
},
);
let result = problem
.run(&mut obj, "efs generated seed should remain reachable")
.expect("invalid startup seeds should not consume the only EFS seed slot");
assert_eq!(result.rho, valid_seed);
assert_eq!(result.plan_used.solver, Solver::Efs);
}
#[test]
fn run_efs_runtime_fallback_marker_degrades_to_bfgs_immediately() {
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.seed_budget = 2;
let efs_calls = Arc::new(AtomicUsize::new(0));
let problem = OuterProblem::new(12)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_initial_rho(Array1::zeros(12))
.with_max_iter(5);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(0.5 * theta.dot(theta)),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: 0.5 * theta.dot(theta),
gradient: theta.clone(),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
{
let efs_calls = Arc::clone(&efs_calls);
Some(move |_: &mut (), _: &Array1<f64>| {
efs_calls.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
Err(EstimationError::RemlOptimizationFailed(format!(
"{} synthetic runtime escape hatch",
EFS_FIRST_ORDER_FALLBACK_MARKER,
)))
})
},
);
let result = problem
.run(&mut obj, "efs runtime fallback marker")
.expect("runtime EFS escape hatch should degrade to BFGS");
assert_eq!(result.plan_used.solver, Solver::Bfgs);
assert_eq!(
efs_calls.load(std::sync::atomic::Ordering::Relaxed),
1,
"runtime fallback marker should abort the EFS attempt immediately"
);
}
#[test]
fn run_rejects_invalid_theta_layout() {
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_psi_dim(2)
.with_initial_rho(Array1::zeros(1))
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(0.0),
|_: &mut (), _: &Array1<f64>| {
Ok(OuterEval {
cost: 0.0,
gradient: Array1::zeros(1),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let err = problem
.run(&mut obj, "test invalid layout")
.expect_err("invalid theta layout should fail cleanly");
assert!(
err.to_string().contains("invalid outer theta layout"),
"unexpected error: {err}"
);
}
#[test]
fn effective_seed_budget_caps_expensive_solver_retries() {
assert_eq!(
effective_seed_budget(
4,
Solver::Efs,
crate::seeding::SeedRiskProfile::GeneralizedLinear,
false,
),
1
);
assert_eq!(
effective_seed_budget(
4,
Solver::HybridEfs,
crate::seeding::SeedRiskProfile::Survival,
false,
),
1
);
assert_eq!(
effective_seed_budget(
3,
Solver::Arc,
crate::seeding::SeedRiskProfile::GeneralizedLinear,
true,
),
1
);
assert_eq!(
effective_seed_budget(
3,
Solver::Arc,
crate::seeding::SeedRiskProfile::Survival,
false,
),
1
);
assert_eq!(
effective_seed_budget(
3,
Solver::Bfgs,
crate::seeding::SeedRiskProfile::Survival,
false,
),
3
);
}
#[test]
fn run_arc_projects_seed_before_seed_validation_eval() {
let seen = Arc::new(Mutex::new(Vec::new()));
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 1;
seed_config.seed_budget = 1;
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Either)
.with_bounds(array![0.0], array![1.0])
.with_initial_rho(array![2.0])
.with_seed_config(seed_config)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok((theta[0] - 0.25).powi(2)),
{
let seen = Arc::clone(&seen);
move |_: &mut (), theta: &Array1<f64>| {
seen.lock().unwrap().push(theta.clone());
Ok(OuterEval {
cost: (theta[0] - 0.25).powi(2),
gradient: array![2.0 * (theta[0] - 0.25)],
hessian: HessianResult::Analytic(array![[2.0]]),
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
problem
.run(&mut obj, "arc seed projection")
.expect("arc should evaluate the projected seed");
assert_eq!(
seen.lock().unwrap().first().cloned(),
Some(array![1.0]),
"Arc must project the seed before validating the initial sample",
);
}
#[test]
fn run_bfgs_projects_seed_before_seed_validation_eval() {
let seen = Arc::new(Mutex::new(Vec::new()));
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 1;
seed_config.seed_budget = 1;
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_bounds(array![0.0], array![1.0])
.with_initial_rho(array![2.0])
.with_seed_config(seed_config)
.with_max_iter(1);
let mut obj = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok((theta[0] - 0.25).powi(2)),
{
let seen = Arc::clone(&seen);
move |_: &mut (), theta: &Array1<f64>| {
seen.lock().unwrap().push(theta.clone());
Ok(OuterEval {
cost: (theta[0] - 0.25).powi(2),
gradient: array![2.0 * (theta[0] - 0.25)],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
}
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
problem
.run(&mut obj, "bfgs seed projection")
.expect("BFGS should evaluate the projected seed");
assert_eq!(
seen.lock().unwrap().first().cloned(),
Some(array![1.0]),
"BFGS must project the seed before validating the initial sample",
);
}
fn tmp_cache_session(label: &str) -> (tempfile::TempDir, Arc<CacheSession>) {
let dir = tempfile::tempdir().unwrap();
let store = crate::cache::WarmStartStore::open(
dir.path().to_path_buf(),
crate::cache::StoreOptions {
size_budget_bytes: 1024 * 1024,
ttl: std::time::Duration::from_secs(60),
},
)
.unwrap();
let mut fp = crate::cache::Fingerprinter::new();
fp.absorb_str(b"outer-test", label);
let key = fp.finalize();
(dir, Arc::new(CacheSession::open(store, key)))
}
#[test]
fn checkpointing_objective_persists_finite_evals() {
let (_d, session) = tmp_cache_session("ckpt-persist");
let problem = OuterProblem::new(1).with_gradient(Derivative::Unavailable);
let mut inner: ClosureObjective<_, _, _> = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| Err(EstimationError::InvalidInput("eval not used".into())),
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut wrapped = CheckpointingObjective::new(&mut inner, Arc::clone(&session), Vec::new());
assert!(session.try_load().is_none());
let v0 = wrapped.eval_cost(&array![3.0]).unwrap();
assert!((v0 - 9.0).abs() < 1e-12);
let on_disk = session.try_load().expect("first eval should checkpoint");
let payload = decode_iterate(&on_disk.payload, 1).expect("payload decodes");
assert!((payload.cost - 9.0).abs() < 1e-12);
assert_eq!(payload.rho, vec![3.0]);
let v1 = wrapped.eval_cost(&array![0.5]).unwrap();
assert!((v1 - 0.25).abs() < 1e-12);
let on_disk = session
.try_load()
.expect("improving eval should checkpoint");
let payload = decode_iterate(&on_disk.payload, 1).expect("payload decodes");
assert!((payload.cost - 0.25).abs() < 1e-12);
assert_eq!(payload.rho, vec![0.5]);
let v_inf = wrapped.eval_cost(&array![f64::NAN]);
match v_inf {
Ok(value) => assert!(!value.is_finite()),
Err(err) => assert!(!err.to_string().is_empty()),
}
let on_disk = session.try_load().expect("prior best preserved");
let payload = decode_iterate(&on_disk.payload, 1).expect("payload decodes");
assert!((payload.cost - 0.25).abs() < 1e-12);
}
#[test]
fn checkpointing_objective_rejects_wrong_dim_on_decode() {
let bytes = encode_iterate(&array![1.0, 2.0, 3.0], None, 0.5, 0).expect("encode");
assert!(decode_iterate(&bytes, 3).is_some());
assert!(decode_iterate(&bytes, 5).is_none());
}
#[test]
fn iterate_payload_round_trips_beta() {
let rho = array![10.0, -10.0, 5.0];
let beta = array![0.12, -0.34, 0.56, 7.89];
let bytes = encode_iterate(&rho, Some(&beta), 1.0, 7).expect("encode");
let decoded = decode_iterate(&bytes, rho.len()).expect("decode");
assert_eq!(decoded.rho, rho.to_vec());
assert_eq!(decoded.beta, beta.to_vec());
let ro_bytes = encode_iterate(&rho, None, 1.0, 7).expect("encode-rho-only");
let ro = decode_iterate(&ro_bytes, rho.len()).expect("decode-rho-only");
assert!(ro.beta.is_empty());
}
#[test]
fn note_persists_inner_beta_hint_from_eval() {
let (_d, session) = tmp_cache_session("note-persists-beta");
let problem = OuterProblem::new(1).with_gradient(Derivative::Unavailable);
let mut inner: ClosureObjective<_, _, _> = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(1.0),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Unavailable,
inner_beta_hint: Some(array![1.5, 2.5, 3.5]),
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut wrapped = CheckpointingObjective::new(&mut inner, Arc::clone(&session), Vec::new());
let eval = wrapped.eval(&array![0.5]).expect("eval ok");
assert!((eval.cost - 0.25).abs() < 1e-12);
let on_disk = session
.try_load()
.expect("eval with finite β must persist a (ρ,β) checkpoint");
let payload = decode_iterate(&on_disk.payload, 1).expect("payload decodes");
assert_eq!(payload.beta, vec![1.5, 2.5, 3.5]);
let captured = wrapped.last_inner_beta().expect("β was captured");
assert_eq!(captured.to_vec(), vec![1.5, 2.5, 3.5]);
}
#[test]
fn note_rejects_nonfinite_inner_beta() {
let (_d, session) = tmp_cache_session("note-rejects-bad-beta");
let problem = OuterProblem::new(1).with_gradient(Derivative::Unavailable);
let mut inner: ClosureObjective<_, _, _> = problem.build_objective(
(),
|_: &mut (), _: &Array1<f64>| Ok(1.0),
|_: &mut (), theta: &Array1<f64>| {
Ok(OuterEval {
cost: theta[0] * theta[0],
gradient: array![2.0 * theta[0]],
hessian: HessianResult::Unavailable,
inner_beta_hint: Some(array![f64::NAN, 0.5]),
})
},
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut wrapped = CheckpointingObjective::new(&mut inner, Arc::clone(&session), Vec::new());
let eval = wrapped.eval(&array![0.5]).expect("eval ok");
assert!((eval.cost - 0.25).abs() < 1e-12);
assert!(
session.try_load().is_none(),
"non-finite β must abort the checkpoint write, not poison the cache",
);
assert!(
wrapped.last_inner_beta().is_none(),
"non-finite β must not be exposed via last_inner_beta()",
);
}
#[test]
fn classify_extracts_beta_from_v2_payload() {
let rho = array![1.0, 2.0];
let beta = array![10.0, 20.0, 30.0];
let payload = encode_iterate(&rho, Some(&beta), 1.0, 0).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(1.0),
iteration: Some(0),
kind: crate::cache::EntryKind::Checkpoint,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Preloaded,
};
let CacheSeedDecision::Seed {
beta: decoded_beta, ..
} = classify_cache_entry_for_outer(&loaded, 2)
else {
panic!("expected Seed decision");
};
assert_eq!(decoded_beta, beta.to_vec());
let payload = encode_iterate(&rho, None, 1.0, 0).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(1.0),
iteration: Some(0),
kind: crate::cache::EntryKind::Checkpoint,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Preloaded,
};
let CacheSeedDecision::Seed {
beta: decoded_beta, ..
} = classify_cache_entry_for_outer(&loaded, 2)
else {
panic!("expected Seed decision");
};
assert!(
decoded_beta.is_empty(),
"ρ-only payload must produce an empty beta so the dispatcher skips seed_inner_state"
);
}
#[test]
fn run_calls_seed_inner_state_with_cached_beta() {
struct RecordingObj {
seeded: Arc<Mutex<Option<Array1<f64>>>>,
eval_count: Arc<Mutex<usize>>,
}
impl OuterObjective for RecordingObj {
fn capability(&self) -> OuterCapability {
OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Dense,
n_params: 2,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
}
}
fn eval_cost(&mut self, theta: &Array1<f64>) -> Result<f64, EstimationError> {
Ok(theta.dot(theta))
}
fn eval(&mut self, theta: &Array1<f64>) -> Result<OuterEval, EstimationError> {
*self.eval_count.lock().unwrap() += 1;
Ok(OuterEval {
cost: theta.dot(theta),
gradient: 2.0 * theta,
hessian: HessianResult::Analytic(2.0 * Array2::<f64>::eye(theta.len())),
inner_beta_hint: None,
})
}
fn reset(&mut self) {}
fn seed_inner_state(&mut self, beta: &Array1<f64>) -> Result<SeedOutcome, EstimationError> {
*self.seeded.lock().unwrap() = Some(beta.clone());
Ok(SeedOutcome::Installed)
}
}
let (_d, session) = tmp_cache_session("seed-inner-state-call");
let bytes =
encode_iterate(&array![1.0, 2.0], Some(&array![7.5, 8.5, 9.5]), 5.0, 3).expect("encode");
session.checkpoint(&bytes, Some(5.0), Some(3));
let seeded: Arc<Mutex<Option<Array1<f64>>>> = Arc::new(Mutex::new(None));
let eval_count: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
let mut obj = RecordingObj {
seeded: Arc::clone(&seeded),
eval_count: Arc::clone(&eval_count),
};
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_max_iter(1)
.with_cache_session(Arc::clone(&session));
match problem.run(&mut obj, "seed-inner-state-call") {
Ok(result) => assert!(result.final_value.is_finite()),
Err(err) => assert!(!err.to_string().is_empty()),
}
let observed = seeded.lock().unwrap().clone();
assert_eq!(
observed,
Some(array![7.5, 8.5, 9.5]),
"dispatcher must call seed_inner_state with the cached β before run_outer",
);
}
#[test]
fn run_skips_seed_inner_state_when_payload_has_no_beta() {
struct CountingObj {
seed_calls: Arc<Mutex<usize>>,
}
impl OuterObjective for CountingObj {
fn capability(&self) -> OuterCapability {
OuterCapability {
gradient: Derivative::Analytic,
hessian: DeclaredHessianForm::Dense,
n_params: 2,
psi_dim: 0,
fixed_point_available: false,
barrier_config: None,
prefer_gradient_only: false,
disable_fixed_point: false,
}
}
fn eval_cost(&mut self, theta: &Array1<f64>) -> Result<f64, EstimationError> {
Ok(theta.dot(theta))
}
fn eval(&mut self, theta: &Array1<f64>) -> Result<OuterEval, EstimationError> {
Ok(OuterEval {
cost: theta.dot(theta),
gradient: 2.0 * theta,
hessian: HessianResult::Analytic(2.0 * Array2::<f64>::eye(theta.len())),
inner_beta_hint: None,
})
}
fn reset(&mut self) {}
fn seed_inner_state(&mut self, beta: &Array1<f64>) -> Result<SeedOutcome, EstimationError> {
*self.seed_calls.lock().unwrap() += beta.len().max(1);
Ok(SeedOutcome::Installed)
}
}
let (_d, session) = tmp_cache_session("seed-inner-state-skip");
let bytes = encode_iterate(&array![1.0, 2.0], None, 5.0, 3).expect("encode");
session.checkpoint(&bytes, Some(5.0), Some(3));
let seed_calls: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
let mut obj = CountingObj {
seed_calls: Arc::clone(&seed_calls),
};
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_max_iter(1)
.with_cache_session(Arc::clone(&session));
match problem.run(&mut obj, "seed-inner-state-skip") {
Ok(result) => assert!(result.final_value.is_finite()),
Err(err) => assert!(!err.to_string().is_empty()),
}
assert_eq!(
*seed_calls.lock().unwrap(),
0,
"seed_inner_state must not fire when the cached payload carries no β",
);
}
#[test]
fn cache_entry_classifier_honors_finite_seeds_regardless_of_saturation() {
for rho_seed in [array![9.0, 0.0], array![10.0, -10.0], array![-10.0, 10.0]] {
let payload = encode_iterate(&rho_seed, None, 1.0, 0).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(1.0),
iteration: Some(0),
kind: crate::cache::EntryKind::Checkpoint,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Preloaded,
};
assert!(cache_entry_would_help_outer(&loaded, 2));
let CacheSeedDecision::Seed { rho, .. } = classify_cache_entry_for_outer(&loaded, 2) else {
panic!(
"finite seed {:?} must be honored unchanged; the read-side clamp / \
all-saturated-discard branches were band-aids over the missing β cache",
rho_seed
);
};
assert_eq!(rho, rho_seed, "ρ must round-trip without reshaping");
}
}
#[test]
fn cache_entry_classifier_rejects_only_structural_failures() {
let payload = encode_iterate(&array![0.5, 0.5], None, 1.0, 0).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(f64::NAN),
iteration: Some(0),
kind: crate::cache::EntryKind::Checkpoint,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Preloaded,
};
assert!(matches!(
classify_cache_entry_for_outer(&loaded, 2),
CacheSeedDecision::Discard {
reason: "non-finite-payload",
..
}
));
let payload = encode_iterate(&array![0.5, 0.5], None, 1.0, 0).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(1.0),
iteration: Some(0),
kind: crate::cache::EntryKind::Checkpoint,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Preloaded,
};
assert!(matches!(
classify_cache_entry_for_outer(&loaded, 3),
CacheSeedDecision::Discard {
reason: "payload-shape-mismatch",
..
}
));
}
#[test]
fn exact_final_cache_hit_is_helpful_even_at_boundary() {
let payload = encode_iterate(&array![10.0, -10.0], None, 1.0, 3).expect("encode");
let loaded = crate::cache::LoadedEntry {
entry: crate::cache::CachedEntry {
payload,
objective: Some(1.0),
iteration: Some(3),
kind: crate::cache::EntryKind::Final,
written_unix_secs: 0,
},
source: crate::cache::LoadSource::Exact,
};
assert!(cache_entry_would_help_outer(&loaded, 2));
assert!(matches!(
classify_cache_entry_for_outer(&loaded, 2),
CacheSeedDecision::ExactFinal { iterations: 3, .. }
));
}
#[test]
fn checkpointing_objective_mirrors_checkpoints() {
let (_primary_dir, primary) = tmp_cache_session("ckpt-primary");
let (_mirror_dir, mirror) = tmp_cache_session("ckpt-mirror");
let problem = OuterProblem::new(1).with_gradient(Derivative::Unavailable);
let mut inner: ClosureObjective<_, _, _> = problem.build_objective(
(),
|_: &mut (), theta: &Array1<f64>| Ok(theta[0] * theta[0]),
|_: &mut (), _: &Array1<f64>| Err(EstimationError::InvalidInput("eval not used".into())),
None::<fn(&mut ())>,
None::<fn(&mut (), &Array1<f64>) -> Result<EfsEval, EstimationError>>,
);
let mut wrapped =
CheckpointingObjective::new(&mut inner, Arc::clone(&primary), vec![Arc::clone(&mirror)]);
let value = wrapped.eval_cost(&array![4.0]).unwrap();
assert_eq!(value, 16.0);
let primary_payload =
decode_iterate(&primary.try_load().expect("primary checkpoint").payload, 1)
.expect("primary decode");
let mirror_payload = decode_iterate(&mirror.try_load().expect("mirror checkpoint").payload, 1)
.expect("mirror decode");
assert_eq!(primary_payload.rho, vec![4.0]);
assert_eq!(mirror_payload.rho, vec![4.0]);
assert_eq!(primary_payload.cost, mirror_payload.cost);
}
#[test]
fn cached_rho_is_prepended_as_first_seed() {
let (_d, session) = tmp_cache_session("seed-prepend");
let payload = encode_iterate(&array![2.5], None, 0.25, 0).expect("encode");
session.checkpoint(&payload, Some(0.25), Some(0));
assert!(
session.try_load().is_some(),
"precondition: cache populated"
);
let seen: Arc<Mutex<Vec<Array1<f64>>>> = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_bounds(array![-5.0], array![5.0])
.with_initial_rho(array![-3.0]) .with_max_iter(8)
.with_cache_session(Arc::clone(&session));
let mut obj = problem.build_objective(
seen.clone(),
|seen: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| {
seen.lock().unwrap().push(theta.clone());
Ok((theta[0] - 2.5).powi(2))
},
|_: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| {
Ok(OuterEval {
cost: (theta[0] - 2.5).powi(2),
gradient: array![2.0 * (theta[0] - 2.5)],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut Arc<Mutex<Vec<Array1<f64>>>>)>,
None::<
fn(&mut Arc<Mutex<Vec<Array1<f64>>>>, &Array1<f64>) -> Result<EfsEval, EstimationError>,
>,
);
match problem.run(&mut obj, "seed-prepend") {
Ok(result) => assert!(result.final_value.is_finite()),
Err(err) => assert!(!err.to_string().is_empty()),
}
let evals = seen.lock().unwrap();
let pos_cached = evals.iter().position(|r| (r[0] - 2.5).abs() < 1e-9);
let pos_initial = evals.iter().position(|r| (r[0] + 3.0).abs() < 1e-9);
assert!(
pos_cached.is_some(),
"cached rho must be evaluated; saw {:?}",
*evals
);
if let (Some(c), Some(i)) = (pos_cached, pos_initial) {
assert!(
c <= i,
"cached rho (idx {c}) must precede initial_rho (idx {i})",
);
}
}
#[test]
fn all_saturated_cached_rho_is_honored_as_seed() {
let (_d, session) = tmp_cache_session("all-saturated-honored");
let payload = encode_iterate(&array![10.0, -10.0], None, 1.0, 0).expect("encode");
session.checkpoint(&payload, Some(1.0), Some(0));
assert!(
session.try_load().is_some(),
"precondition: cache populated"
);
let seen: Arc<Mutex<Vec<Array1<f64>>>> = Arc::new(Mutex::new(Vec::new()));
let mut seed_config = crate::seeding::SeedConfig::default();
seed_config.max_seeds = 4;
seed_config.seed_budget = 1;
let problem = OuterProblem::new(2)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_seed_config(seed_config)
.with_initial_rho(array![0.0, 0.0])
.with_rho_bound(10.0)
.with_max_iter(1)
.with_cache_session(Arc::clone(&session));
let mut obj = problem.build_objective(
seen.clone(),
|_: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| Ok(theta.dot(theta)),
|seen: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| {
seen.lock().unwrap().push(theta.clone());
Ok(OuterEval {
cost: theta.dot(theta),
gradient: theta.clone(),
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut Arc<Mutex<Vec<Array1<f64>>>>)>,
None::<
fn(&mut Arc<Mutex<Vec<Array1<f64>>>>, &Array1<f64>) -> Result<EfsEval, EstimationError>,
>,
);
match problem.run(&mut obj, "all-saturated-honored") {
Ok(result) => assert!(result.final_value.is_finite()),
Err(err) => assert!(!err.to_string().is_empty()),
}
let evals = seen.lock().unwrap();
assert!(
evals.iter().any(|rho| rho == array![10.0, -10.0]),
"cached saturated ρ must be evaluated unchanged under v2 (ρ, β) invariant; saw {:?}",
*evals
);
}
#[test]
fn exact_final_cache_hit_skips_outer_validation() {
let (_d, session) = tmp_cache_session("final-skip");
let payload = encode_iterate(&array![2.5], None, 0.25, 7).expect("encode");
session.finalize(&payload, Some(0.25), Some(7));
let seen: Arc<Mutex<Vec<Array1<f64>>>> = Arc::new(Mutex::new(Vec::new()));
let problem = OuterProblem::new(1)
.with_gradient(Derivative::Analytic)
.with_hessian(DeclaredHessianForm::Unavailable)
.with_bounds(array![-5.0], array![5.0])
.with_initial_rho(array![-3.0])
.with_max_iter(8)
.with_cache_session(Arc::clone(&session));
let mut obj = problem.build_objective(
seen.clone(),
|seen: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| {
seen.lock().unwrap().push(theta.clone());
Ok((theta[0] - 2.5).powi(2))
},
|_: &mut Arc<Mutex<Vec<Array1<f64>>>>, theta: &Array1<f64>| {
Ok(OuterEval {
cost: (theta[0] - 2.5).powi(2),
gradient: array![2.0 * (theta[0] - 2.5)],
hessian: HessianResult::Unavailable,
inner_beta_hint: None,
})
},
None::<fn(&mut Arc<Mutex<Vec<Array1<f64>>>>)>,
None::<
fn(&mut Arc<Mutex<Vec<Array1<f64>>>>, &Array1<f64>) -> Result<EfsEval, EstimationError>,
>,
);
let result = problem
.run(&mut obj, "final-skip")
.expect("final exact hit should return cached outer result");
assert_eq!(result.rho, array![2.5]);
assert_eq!(result.final_value, 0.25);
assert_eq!(result.iterations, 7);
assert!(result.converged);
assert!(
seen.lock().unwrap().is_empty(),
"exact final hit should not evaluate the outer objective"
);
}