#[cfg(test)]
mod tests {
use crate::manifold::{
SaeFisherRowMetricRequest, SaeFitAssignmentKind, SaeFitConfig, SaeFitSeedReport,
SaeFitSeedRequest, SaeManifoldTerm, SaeMinimalSeedReport, SaeMinimalSeedRequest,
build_sae_fit_seed, build_sae_minimal_seed,
};
use gam_terms::analytic_penalties::AnalyticPenaltyRegistry;
use ndarray::{Array2, Array3};
const N_MONTHS: usize = 12;
const N_ROWS: usize = 96;
const P_OUT: usize = 6;
const NOISE_SIGMA: f64 = 0.01;
fn lcg(state: &mut u64) -> f64 {
*state = state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
((*state >> 11) as f64) / ((1u64 << 53) as f64)
}
fn lcg_normal(state: &mut u64) -> f64 {
let u1 = lcg(state).max(1e-12);
let u2 = lcg(state);
(-2.0 * u1.ln()).sqrt() * (std::f64::consts::TAU * u2).cos()
}
fn month_embedding_target() -> Array2<f64> {
let mut state = 0x2263_0000_0000_0003u64;
Array2::from_shape_fn((N_ROWS, P_OUT), |(i, j)| {
let theta = std::f64::consts::TAU * (i as f64) / (N_ROWS as f64);
let harmonic = (j / 2 + 1) as f64;
let clean = if j % 2 == 0 {
(harmonic * theta).cos()
} else {
(harmonic * theta).sin()
};
clean + NOISE_SIGMA * lcg_normal(&mut state)
})
}
fn build_month_term() -> (SaeManifoldTerm, Array2<f64>) {
let target = month_embedding_target();
let assignment_kind = SaeFitAssignmentKind::Softmax;
let minimal = build_sae_minimal_seed(SaeMinimalSeedRequest {
target: target.view(),
atom_basis: vec!["periodic".to_string()],
atom_dim: vec![1],
assignment_kind,
alpha: 1.0,
tau: 1.0,
threshold: 0.0,
top_k: None,
random_state: 0,
initial_logits: None,
initial_coords: None,
})
.expect("minimal seed on the month circle");
let SaeMinimalSeedReport {
geometry_plans,
basis_values,
basis_jacobian,
decoder_coefficients,
smooth_penalties,
initial_logits,
initial_coords,
refine_routing,
} = minimal;
let identity_u = Array3::<f64>::from_shape_fn(
(N_ROWS, P_OUT, 1),
|(_, i, _)| if i == 0 { 1.0 } else { 0.0 },
);
let metric_request = SaeFisherRowMetricRequest::from_tag(
identity_u.view(),
N_ROWS,
P_OUT,
None,
Some("uncertified_approximation"),
None,
)
.expect("behavioral metric request");
let registry = AnalyticPenaltyRegistry::new();
let seed = build_sae_fit_seed(SaeFitSeedRequest {
target: target.view(),
geometry_plans: &geometry_plans,
basis_values: basis_values.view(),
basis_jacobian: basis_jacobian.view(),
decoder_coefficients: decoder_coefficients.view(),
smooth_penalties: smooth_penalties.view(),
initial_logits: initial_logits.view(),
initial_coords: initial_coords.view(),
alpha: 1.0,
tau: 1.0,
learnable_alpha: false,
assignment_kind,
sparsity_strength: 1.0,
smoothness: 1.0,
max_iter: 40,
learning_rate: 1.0,
ridge_ext_coord: 1.0e-6,
ridge_beta: 1.0e-6,
top_k: None,
threshold: 0.0,
native_ard_enabled: true,
seed_refine_routing: refine_routing,
seed_refine_random_state: 0,
data_row_reseed: false,
fit_config: SaeFitConfig::default(),
temperature_schedule: None,
fisher_metric: Some(metric_request),
row_loss_weights: None,
registry: ®istry,
})
.expect("fit seed on the month circle");
let SaeFitSeedReport {
base_term: term, ..
} = seed;
(term, target)
}
#[test]
fn fixture_chart_spans_the_circle() {
let (term, _) = build_month_term();
let coords = term.assignment.coords[0].as_matrix();
let mut lo = f64::INFINITY;
let mut hi = f64::NEG_INFINITY;
for row in 0..coords.nrows() {
lo = lo.min(coords[[row, 0]]);
hi = hi.max(coords[[row, 0]]);
}
let span_turns = hi - lo;
let mut distinct: Vec<f64> = (0..coords.nrows()).map(|r| coords[[r, 0]]).collect();
distinct.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
distinct.dedup_by(|a, b| (*a - *b).abs() <= 1e-6);
eprintln!(
"[#2263 fixture] fitted chart spans {span_turns:.4} turns over {} rows, \
{} distinct coordinates",
coords.nrows(),
distinct.len()
);
assert!(
span_turns >= 0.8,
"the fitted chart spans only {span_turns:.4} turns; a displacement measured on it \
says nothing about steering"
);
assert!(
distinct.len() >= N_MONTHS,
"the fitted chart collapsed to {} distinct coordinates for {} rows; it cannot \
resolve {N_MONTHS} months",
distinct.len(),
coords.nrows()
);
}
}