use super::*;
fn zz2155_mode_geography_for_link(label: &str, link: InverseLink) {
let (y, x) = zz2155_fixture(600, 2155);
let (pilot_beta, pilot_eta) = zz2155_pilot(&y, &x, &link);
eprintln!(
"[zz2155:{label}] pilot beta = ({:+.6}, {:+.6})",
pilot_beta[0], pilot_beta[1]
);
let selected = select_wiggle_basis_from_seed(
pilot_eta.view(),
&WiggleBlockConfig {
degree: 3,
num_internal_knots: 8,
penalty_order: 2,
double_penalty: true,
},
&[1, 2, 3],
)
.expect("wiggle basis selection");
let problem = Zz2155Problem {
y: y.clone(),
x: x.clone(),
link: link.clone(),
knots: selected.knots.clone(),
degree: selected.degree,
wiggle_template: selected.block.clone(),
};
let k_w = selected.block.penalties.len();
eprintln!(
"[zz2155:{label}] wiggle: {} coefficients, {k_w} penalties, nullspace {:?}",
match &selected.block.design {
DesignMatrix::Dense(d) => d.to_dense().ncols(),
DesignMatrix::Sparse(_) => 0,
},
selected.block.nullspace_dims,
);
for rho_center in [0.0_f64, 2.0] {
let rho = Array1::from_elem(k_w, rho_center);
let cold = problem.solve_fixed_lambda_freeze_refit(&rho, &pilot_eta, &pilot_beta, None);
let mut carried: Option<(Array1<f64>, Array1<f64>, Array1<f64>)> = None;
let mut cont: Result<(f64, f64, Array1<f64>, Array1<f64>, Array1<f64>, usize), String> =
Err("continuation never ran".to_string());
for tau in [8.0_f64, 5.0, 3.0, 1.5, 0.5, 0.0] {
let rho_tau = rho.mapv(|v| v + tau);
let (eta_seed, beta_eta_seed, beta_w_seed) = match &carried {
Some((be, bw, eh)) => (eh.clone(), be.clone(), Some(bw.clone())),
None => (pilot_eta.clone(), pilot_beta.clone(), None),
};
cont = problem.solve_fixed_lambda_freeze_refit(
&rho_tau,
&eta_seed,
&beta_eta_seed,
beta_w_seed.as_ref(),
);
match &cont {
Ok((pen, dev, be, bw, eh, cycles)) => {
eprintln!(
"[zz2155:{label}] rho={rho_center:+.1} tau={tau:+.1}: pen_obj={pen:.10e} dev={dev:.6e} |beta_w|_1={:.6e} cycles={cycles}",
bw.iter().map(|v| v.abs()).sum::<f64>()
);
carried = Some((be.clone(), bw.clone(), eh.clone()));
}
Err(e) => {
eprintln!("[zz2155:{label}] rho={rho_center:+.1} tau={tau:+.1}: FAILED {e}");
carried = None;
}
}
}
match (&cold, &cont) {
(Ok((pc, dc, _, bwc, _, cyc_c)), Ok((pk, dk, _, bwk, _, cyc_k))) => {
let dbw = bwc
.iter()
.zip(bwk.iter())
.map(|(a, b)| (a - b).abs())
.fold(0.0_f64, f64::max);
eprintln!(
"[zz2155:{label}] VERDICT rho={rho_center:+.1}: cold pen={pc:.10e} (dev {dc:.6e}, {cyc_c} cyc) vs continuation pen={pk:.10e} (dev {dk:.6e}, {cyc_k} cyc); pen gap (cold-cont)={:+.6e}; max|Δβ_w|={dbw:.3e}",
pc - pk
);
}
(Ok((pc, ..)), Err(e)) => {
eprintln!(
"[zz2155:{label}] VERDICT rho={rho_center:+.1}: cold pen={pc:.10e}; continuation FAILED: {e}"
);
}
(Err(e), Ok((pk, ..))) => {
eprintln!(
"[zz2155:{label}] VERDICT rho={rho_center:+.1}: cold FAILED ({e}); continuation pen={pk:.10e}"
);
}
(Err(ec), Err(ek)) => {
eprintln!(
"[zz2155:{label}] VERDICT rho={rho_center:+.1}: BOTH FAILED cold={ec} cont={ek}"
);
}
}
assert!(
cold.is_ok() || cont.is_ok(),
"[zz2155:{label}] rho={rho_center:+.1}: no strategy converged"
);
}
}
#[test]
fn zz_measure_2155_loglog_mode_geography() {
zz2155_mode_geography_for_link("loglog", InverseLink::Standard(StandardLink::LogLog));
}
#[test]
fn zz_measure_2155_cauchit_mode_geography() {
zz2155_mode_geography_for_link("cauchit", InverseLink::Standard(StandardLink::Cauchit));
}
#[test]
fn zz_measure_2155_cloglog_control_mode_geography() {
zz2155_mode_geography_for_link("cloglog", InverseLink::Standard(StandardLink::CLogLog));
}