use pounce_algorithm::init::default::DefaultIterateInitializer as Init;
use pounce_common::types::Number;
const THETA_0: Number = 1.0;
const THETA_ACCEPTED: Number = 0.2500000062500001;
const ALPHA_ACCEPTED: Number = 0.5;
const ETA_DEFAULT: Number = 1e-2;
fn meaningful_etas() -> Vec<Number> {
let mut v = vec![1e-12, 1e-6, ETA_DEFAULT];
for k in 1..=100 {
v.push(k as Number / 100.0);
}
v
}
#[test]
fn no_eta_accepts_a_trial_that_does_not_reduce_the_violation() {
for &eta in &meaningful_etas() {
for &alpha in &[1.0, 0.5, 0.25, 0.125] {
assert!(
!Init::accepts_trial(THETA_0, THETA_0, alpha, eta),
"eta = {eta}, alpha = {alpha} accepted a trial that did \
not move the violation at all",
);
assert!(
!Init::accepts_trial(THETA_0, THETA_0 * 1.001, alpha, eta),
"eta = {eta}, alpha = {alpha} accepted a trial that made \
the violation WORSE",
);
}
}
}
#[test]
fn no_eta_rejects_the_eigenb2_step() {
for &eta in &meaningful_etas() {
assert!(
Init::accepts_trial(THETA_0, THETA_ACCEPTED, ALPHA_ACCEPTED, eta),
"eta = {eta} rejected the trial that eigenb2 (and eigena2) \
accepted; if this ever becomes reachable, gh#616's \
conclusion that eta cannot separate them needs re-deriving",
);
}
}
#[test]
fn the_eigenb2_step_is_a_median_sized_reduction_not_a_marginal_one() {
let ratio = THETA_ACCEPTED / THETA_0;
assert!(
(ratio - 0.25).abs() < 1e-8,
"eigenb2's accepted step cut the violation to {ratio} of theta_0; \
gh#616's argument assumes 1/4",
);
let corpus_ratios: &[Number] = &[
0.0, 5.0e-9, 5.2e-6, 0.01, 0.037, 0.194, 0.25, 0.2505, 0.2548, 0.2624, 0.5382, 0.875, 0.8889, ];
let stricter = corpus_ratios.iter().filter(|&&r| r < ratio).count();
assert!(
stricter >= 6,
"at least six accepted corpus steps reduce the violation by more \
than eigenb2's does; got {stricter}. A rejection band placed \
above eigenb2's ratio would take the rest of the tail with it, \
which is the measurement gh#616 rests on",
);
}
#[test]
fn eta_tightens_toward_short_steps_first() {
assert!(Init::accepts_trial(1.0, 0.99, 1.0, 0.009));
assert!(!Init::accepts_trial(1.0, 0.99, 1.0, 0.011));
assert!(Init::accepts_trial(1.0, 0.99, 0.125, 0.079));
assert!(!Init::accepts_trial(1.0, 0.99, 0.125, 0.081));
}
#[test]
fn non_finite_trials_are_never_accepted() {
for &eta in &meaningful_etas() {
assert!(!Init::accepts_trial(THETA_0, Number::NAN, 1.0, eta));
assert!(!Init::accepts_trial(THETA_0, Number::INFINITY, 1.0, eta));
}
}