use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use fdars_core::classification::{fclassif_cv, fclassif_knn, fclassif_lda, fclassif_qda};
use fdars_core::matrix::FdMatrix;
use std::f64::consts::PI;
fn generate_two_class_data(n: usize, m: usize) -> (FdMatrix, Vec<usize>, Vec<f64>) {
let argvals: Vec<f64> = (0..m).map(|j| j as f64 / (m - 1) as f64).collect();
let n_per_class = n / 2;
let mut data = vec![0.0; n * m];
let mut labels = vec![0usize; n];
for i in 0..n {
let class = if i < n_per_class { 0 } else { 1 };
labels[i] = class;
let offset = ((i as f64 * 7.3 + 1.1).sin()) * 0.3;
for j in 0..m {
let t = argvals[j];
let value = if class == 0 {
(2.0 * PI * t).sin() + offset
} else {
(2.0 * PI * t).cos() + offset + 1.0
};
data[i + j * n] = value; }
}
let mat = FdMatrix::from_column_major(data, n, m).unwrap();
(mat, labels, argvals)
}
fn bench_lda(c: &mut Criterion) {
let mut group = c.benchmark_group("fclassif_lda");
let m = 50;
for &n in &[50, 200, 500] {
for &ncomp in &[3, 5, 10] {
if ncomp >= n / 2 {
continue;
}
let (data, y, _argvals) = generate_two_class_data(n, m);
let label = format!("n{}_nc{}", n, ncomp);
group.bench_with_input(BenchmarkId::new("params", &label), &label, |b, _| {
b.iter(|| fclassif_lda(black_box(&data), black_box(&y), None, black_box(ncomp)));
});
}
}
group.finish();
}
fn bench_qda(c: &mut Criterion) {
let mut group = c.benchmark_group("fclassif_qda");
let m = 50;
for &n in &[50, 200, 500] {
for &ncomp in &[3, 5, 10] {
if ncomp >= n / 2 {
continue;
}
let (data, y, _argvals) = generate_two_class_data(n, m);
let label = format!("n{}_nc{}", n, ncomp);
group.bench_with_input(BenchmarkId::new("params", &label), &label, |b, _| {
b.iter(|| fclassif_qda(black_box(&data), black_box(&y), None, black_box(ncomp)));
});
}
}
group.finish();
}
fn bench_knn(c: &mut Criterion) {
let mut group = c.benchmark_group("fclassif_knn");
let m = 50;
for &n in &[50, 200, 500] {
for &ncomp in &[3, 5, 10] {
if ncomp >= n / 2 {
continue;
}
for &k in &[3, 5, 7] {
let (data, y, _argvals) = generate_two_class_data(n, m);
let label = format!("n{}_nc{}_k{}", n, ncomp, k);
group.bench_with_input(BenchmarkId::new("params", &label), &label, |b, _| {
b.iter(|| {
fclassif_knn(
black_box(&data),
black_box(&y),
None,
black_box(ncomp),
black_box(k),
)
});
});
}
}
}
group.finish();
}
fn bench_cv(c: &mut Criterion) {
let mut group = c.benchmark_group("fclassif_cv");
let m = 50;
let ncomp = 5;
let seed = 42;
for &n in &[50, 200] {
let (data, y, argvals) = generate_two_class_data(n, m);
for method in &["lda", "qda"] {
let label = format!("n{}_{}", n, method);
group.bench_with_input(BenchmarkId::new("params", &label), &label, |b, _| {
b.iter(|| {
fclassif_cv(
black_box(&data),
black_box(&argvals),
black_box(&y),
None,
black_box(method),
black_box(ncomp),
5,
black_box(seed),
)
});
});
}
}
group.finish();
}
criterion_group!(benches, bench_lda, bench_qda, bench_knn, bench_cv);
criterion_main!(benches);