use irithyll::stream::AsyncSGBT;
use irithyll::{SGBTConfig, Sample};
fn xorshift64(state: &mut u64) -> f64 {
*state ^= *state << 13;
*state ^= *state >> 7;
*state ^= *state << 17;
(*state as f64) / (u64::MAX as f64)
}
#[tokio::main]
async fn main() {
println!("=== Irithyll: Async Streaming Ingestion ===");
println!("Target function: y = 4*x1 - 2*x2 + 1\n");
let config = SGBTConfig::builder()
.n_steps(30)
.learning_rate(0.1)
.grace_period(20)
.max_depth(4)
.n_bins(32)
.build()
.expect("valid config");
let mut runner = AsyncSGBT::new(config);
let sender = runner.sender();
let predictor = runner.predictor();
println!(" Model initialized: {}", predictor.is_initialized());
println!(" Samples seen: {}", predictor.n_samples_seen());
let train_handle = tokio::spawn(async move { runner.run().await });
println!("\n--- Sending 500 samples ---");
let mut rng: u64 = 0xABCD_EF01_2345_6789;
let n_samples = 500;
for i in 0..n_samples {
let x1 = xorshift64(&mut rng) * 10.0 - 5.0;
let x2 = xorshift64(&mut rng) * 10.0 - 5.0;
let noise = (xorshift64(&mut rng) - 0.5) * 0.2;
let target = 4.0 * x1 - 2.0 * x2 + 1.0 + noise;
sender
.send(Sample::new(vec![x1, x2], target))
.await
.expect("channel should be open");
if (i + 1) % 100 == 0 {
println!(
" Sent {:>4} samples | Model has trained on: {}",
i + 1,
predictor.n_samples_seen(),
);
}
}
println!("\n--- All samples sent, dropping sender ---");
drop(sender);
let result = train_handle.await.expect("task should not panic");
result.expect("training should succeed");
println!(" Training loop completed.");
println!(" Final samples seen: {}", predictor.n_samples_seen());
println!(" Model initialized: {}", predictor.is_initialized());
println!("\n--- Final Predictions (y = 4*x1 - 2*x2 + 1) ---");
println!(
" {:>6} {:>6} | {:>10} {:>10} {:>10}",
"x1", "x2", "true_y", "predicted", "error"
);
println!(" {}", "-".repeat(52));
let test_points: [(f64, f64); 5] = [
(1.0, 1.0),
(-2.0, 3.0),
(0.0, 0.0),
(3.0, -1.0),
(-1.0, -2.0),
];
for (x1, x2) in &test_points {
let true_y = 4.0 * x1 - 2.0 * x2 + 1.0;
let pred = predictor.predict(&[*x1, *x2]);
let error = (pred - true_y).abs();
println!(
" {:>6.1} {:>6.1} | {:>10.4} {:>10.4} {:>10.4}",
x1, x2, true_y, pred, error
);
}
println!("\n[DONE] Async ingestion example complete.");
}