use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use fdars_core::alignment::{elastic_align_pair, elastic_self_distance_matrix, karcher_mean};
use fdars_core::matrix::FdMatrix;
use std::f64::consts::PI;
fn generate_curves(n: usize, m: usize) -> (FdMatrix, Vec<f64>) {
let argvals: Vec<f64> = (0..m).map(|j| j as f64 / (m - 1) as f64).collect();
let mut data = vec![0.0; n * m];
for i in 0..n {
let phase = 0.2 * ((i as f64 * 3.7 + 0.5).sin());
let amp = 1.0 + 0.3 * ((i as f64 * 5.1 + 0.3).sin());
for j in 0..m {
let t = argvals[j];
data[i + j * n] = amp * (2.0 * PI * (t + phase)).sin();
}
}
let mat = FdMatrix::from_column_major(data, n, m).unwrap();
(mat, argvals)
}
fn bench_elastic_align_pair(c: &mut Criterion) {
let mut group = c.benchmark_group("elastic_align_pair");
for &m in &[50, 100, 200] {
let (mat, argvals) = generate_curves(2, m);
let f1 = mat.row(0);
let f2 = mat.row(1);
group.bench_with_input(BenchmarkId::new("m", m), &m, |b, _| {
b.iter(|| {
elastic_align_pair(
black_box(&f1),
black_box(&f2),
black_box(&argvals),
black_box(0.0),
)
});
});
}
let (mat, argvals) = generate_curves(2, 100);
let f1 = mat.row(0);
let f2 = mat.row(1);
group.bench_function("m100_lambda0.1", |b| {
b.iter(|| {
elastic_align_pair(
black_box(&f1),
black_box(&f2),
black_box(&argvals),
black_box(0.1),
)
});
});
group.finish();
}
fn bench_self_distance_matrix(c: &mut Criterion) {
let mut group = c.benchmark_group("elastic_self_distance_matrix");
let m = 50;
for &n in &[10, 30, 50] {
let (mat, argvals) = generate_curves(n, m);
group.bench_with_input(BenchmarkId::new("n", n), &n, |b, _| {
b.iter(|| {
elastic_self_distance_matrix(black_box(&mat), black_box(&argvals), black_box(0.0))
});
});
}
group.finish();
}
fn bench_karcher_mean(c: &mut Criterion) {
let mut group = c.benchmark_group("karcher_mean");
let n = 20;
let m = 50;
let (mat, argvals) = generate_curves(n, m);
group.bench_function("n20_m50", |b| {
b.iter(|| {
karcher_mean(
black_box(&mat),
black_box(&argvals),
black_box(15),
black_box(1e-4),
black_box(0.0),
)
});
});
let n = 10;
let (mat_small, argvals_small) = generate_curves(n, m);
group.bench_function("n10_m50", |b| {
b.iter(|| {
karcher_mean(
black_box(&mat_small),
black_box(&argvals_small),
black_box(15),
black_box(1e-4),
black_box(0.0),
)
});
});
group.finish();
}
criterion_group!(
benches,
bench_elastic_align_pair,
bench_self_distance_matrix,
bench_karcher_mean,
);
criterion_main!(benches);