use blr_active::active_learning::multi_sensor::MultiSensorSession;
use blr_active::SessionConfig;
fn hall_sensor(b_field: f64, rng: &mut u64) -> f64 {
let true_val = 0.4 * b_field + 0.05 * b_field * b_field * b_field;
let noise = 0.03 * lcg_normal(rng);
true_val + noise
}
fn rtd_sensor(temp_c: f64, rng: &mut u64) -> f64 {
let true_val = 100.0 + 0.385 * temp_c; let noise = 0.02 * lcg_normal(rng);
true_val + noise
}
fn lcg_normal(state: &mut u64) -> f64 {
*state = state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
(*state as i64 as f64) / (i64::MAX as f64)
}
fn main() {
println!("=== Multi-Sensor Calibration Workflow ===\n");
let mut rng: u64 = 0x1234_5678_abcd_ef00;
let mut multi = MultiSensorSession::new();
let hall_config = SessionConfig {
target_precision: 0.08, max_iterations: 30,
top_k: 1,
input_range: (-2.0, 2.0),
grid_resolution: 40,
..SessionConfig::default()
};
multi.add_sensor(
"hall",
hall_config,
|b: f64| vec![1.0, b, b * b, b * b * b],
4,
);
let rtd_config = SessionConfig {
target_precision: 0.06, max_iterations: 30,
top_k: 1,
input_range: (0.0, 150.0),
grid_resolution: 40,
..SessionConfig::default()
};
multi.add_sensor("rtd", rtd_config, |t: f64| vec![1.0, t, t * t], 3);
println!("Seeding each sensor with 6 initial measurements...");
for i in 0..6 {
let b = -2.0 + 4.0 * (i as f64) / 5.0;
multi.add_measurement("hall", b, hall_sensor(b, &mut rng));
}
for i in 0..6 {
let t = 0.0 + 150.0 * (i as f64) / 5.0;
multi.add_measurement("rtd", t, rtd_sensor(t, &mut rng));
}
println!("\nRunning active learning (max 25 iterations each)...\n");
println!(
"{:<6} {:<8} {:<12} {:<10}",
"Iter", "Sensor", "Measure at", "y"
);
println!("{}", "-".repeat(45));
let mut iteration = 0_usize;
loop {
if multi.all_goals_met() {
println!("\n✓ All sensors have met their precision goals!");
break;
}
let recommendations = multi.next_iteration_all();
if recommendations.is_empty() {
println!("No more recommendations — all sessions complete.");
break;
}
for rec in &recommendations {
if rec.recommendations.is_empty() {
continue;
}
let input_val = rec.recommendations[0].input_value;
let y = match rec.sensor_id.as_str() {
"hall" => hall_sensor(input_val, &mut rng),
"rtd" => rtd_sensor(input_val, &mut rng),
_ => 0.0,
};
println!(
"{:<6} {:<8} {:<12.3} {:<10.4}",
iteration, rec.sensor_id, input_val, y
);
multi.add_measurement(&rec.sensor_id, input_val, y);
}
iteration += 1;
if iteration >= 25 {
println!("\nMax demonstration iterations reached.");
break;
}
}
println!("\n── Final Precision Summary ──");
for (sensor_id, precision_std) in multi.precision_summary() {
println!(" {:<8} std = {:.4}", sensor_id, precision_std);
}
println!("\nDone. Both sensors calibrated concurrently.");
}