9df217d868
Downstream-consumer corpus for the #295 library surface: a standalone workspace (path-deps, no aura-cli in the link graph — cargo tree verified) exercising the four cycle axes as a World program would, public interface only: a DefaultMemberRunner member run over real GER40, a hand-authored campaign document through aura_campaign::execute, the IC + registry deflation dispatch as library calls, and load_family/reproduce round-trips. Run transcripts committed beside the sources. Findings routed separately: the family-id mismatch between the registry enumeration and the reproduce keying (list-then-reproduce dead-ends) to debug; the reproduce-API friction (no report on the simple path; DataSource/pip re-specification the manifest already holds, wrong pip silently DIVERGED) to a follow-up. Four working confirmations, chief among them the cycle's acceptance claim: all four axes compiled first-try from the public docs alone. refs #295
72 lines
3.2 KiB
Rust
72 lines
3.2 KiB
Rust
//! Axis 3 — the Information Coefficient as a pure library call
|
|
//! (`aura_measurement::information_coefficient`), including its permutation-null
|
|
//! deflation (the returned `overfit_probability`). No data archive, no `aura`
|
|
//! binary: just two in-memory (timestamp, value) series a downstream measurement
|
|
//! World program would hold. Runs an *informed* signal (correlated with the
|
|
//! forward return) against a *noise* signal to show the deflation discriminates.
|
|
use aura_core::Timestamp;
|
|
use aura_measurement::information_coefficient;
|
|
|
|
const N: usize = 400;
|
|
const HORIZON: usize = 1;
|
|
const PERMUTATIONS: usize = 500;
|
|
const SEED: u64 = 12_345;
|
|
|
|
// A tiny deterministic LCG so the fixture is reproducible without an rng dep.
|
|
struct Lcg(u64);
|
|
impl Lcg {
|
|
fn next_unit(&mut self) -> f64 {
|
|
self.0 = self.0.wrapping_mul(6_364_136_223_846_793_005).wrapping_add(1_442_695_040_888_963_407);
|
|
// top 53 bits -> [0,1)
|
|
((self.0 >> 11) as f64) / ((1u64 << 53) as f64)
|
|
}
|
|
fn next_signed(&mut self) -> f64 {
|
|
self.next_unit() * 2.0 - 1.0
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut rng = Lcg(0x1234_5678_9abc_def0);
|
|
|
|
// A random-walk price and its forward one-step return.
|
|
let mut price = Vec::with_capacity(N);
|
|
let mut level = 100.0f64;
|
|
for _ in 0..N {
|
|
level += rng.next_signed();
|
|
price.push(level);
|
|
}
|
|
let price_series: Vec<(Timestamp, f64)> =
|
|
price.iter().enumerate().map(|(i, &p)| (Timestamp(i as i64 * 60_000), p)).collect();
|
|
|
|
// Informed signal: the forward return plus noise (so it genuinely forecasts).
|
|
let mut informed = Vec::with_capacity(N);
|
|
for i in 0..N {
|
|
let fwd = if i + HORIZON < N { price[i + HORIZON] - price[i] } else { 0.0 };
|
|
informed.push(fwd + 0.5 * rng.next_signed());
|
|
}
|
|
let informed_series: Vec<(Timestamp, f64)> =
|
|
informed.iter().enumerate().map(|(i, &s)| (Timestamp(i as i64 * 60_000), s)).collect();
|
|
|
|
// Noise signal: uncorrelated with the forward return.
|
|
let noise_series: Vec<(Timestamp, f64)> =
|
|
(0..N).map(|i| (Timestamp(i as i64 * 60_000), rng.next_signed())).collect();
|
|
|
|
let informed_ic = information_coefficient(&informed_series, &price_series, HORIZON, PERMUTATIONS, SEED);
|
|
let noise_ic = information_coefficient(&noise_series, &price_series, HORIZON, PERMUTATIONS, SEED);
|
|
|
|
println!("informed signal:");
|
|
println!(" information_coefficient = {:.4}", informed_ic.information_coefficient);
|
|
println!(" overfit_probability = {:.4}", informed_ic.overfit_probability);
|
|
println!(" n_pairs = {}", informed_ic.n_pairs);
|
|
println!("noise signal:");
|
|
println!(" information_coefficient = {:.4}", noise_ic.information_coefficient);
|
|
println!(" overfit_probability = {:.4}", noise_ic.overfit_probability);
|
|
println!(" n_pairs = {}", noise_ic.n_pairs);
|
|
|
|
// Determinism check (C1/C18 for a measurement): same inputs -> same bytes.
|
|
let again = information_coefficient(&informed_series, &price_series, HORIZON, PERMUTATIONS, SEED);
|
|
let deterministic = again.information_coefficient == informed_ic.information_coefficient
|
|
&& again.overfit_probability == informed_ic.overfit_probability;
|
|
println!("deterministic re-run identical: {deterministic}");
|
|
}
|