use motif_rs::{EuclideanEngine, MatrixProfileConfig};
fn main() {
let n = 500;
let m = 50;
let mut ts = Vec::with_capacity(n);
for i in 0..n {
let t = i as f64;
let base = (t * std::f64::consts::TAU / 100.0).sin();
let noise = ((t * 7.3).sin() * (t * 13.7).cos()) * 0.05;
ts.push(base + noise);
}
let engine = EuclideanEngine::new(MatrixProfileConfig::new(m));
let mp = engine.compute(&ts);
println!("Time series length: {n}");
println!("Subsequence length: {m}");
println!("Matrix profile length: {}", mp.profile.len());
let (min_idx, min_dist) = mp
.profile
.iter()
.enumerate()
.min_by(|a, b| a.1.partial_cmp(b.1).unwrap())
.unwrap();
let nn_idx = mp.profile_index[min_idx];
println!("\nBest matching pair:");
println!(" Subsequence at index {min_idx}");
println!(" Nearest neighbor at index {nn_idx}");
println!(" Distance: {min_dist:.6}");
let (max_idx, max_dist) = mp
.profile
.iter()
.enumerate()
.filter(|(_, d)| d.is_finite())
.max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
.unwrap();
println!("\nMost anomalous subsequence:");
println!(" Index: {max_idx}");
println!(" Distance: {max_dist:.6}");
let finite_dists: Vec<f64> = mp
.profile
.iter()
.copied()
.filter(|d| d.is_finite())
.collect();
let mean = finite_dists.iter().sum::<f64>() / finite_dists.len() as f64;
let std = (finite_dists.iter().map(|d| (d - mean).powi(2)).sum::<f64>()
/ finite_dists.len() as f64)
.sqrt();
println!("\nProfile statistics:");
println!(" Mean distance: {mean:.6}");
println!(" Std deviation: {std:.6}");
println!(" Min distance: {min_dist:.6}");
println!(" Max distance: {max_dist:.6}");
}