use std::time::Duration;
use criterion::{Criterion, Throughput, black_box, criterion_group, criterion_main};
use flexfloat::bitarray::{BitArrayArith, BoolBitArray, UsizeBitArray};
use flexfloat::flexfloat::FlexFloat;
const AGM_ITERATIONS: usize = 10;
fn agm_pi<B: BitArrayArith>(iters: usize) -> FlexFloat<B> {
let one = FlexFloat::<B>::from_f64(1.0);
let two = FlexFloat::<B>::from_f64(2.0);
let four = FlexFloat::<B>::from_f64(4.0);
let mut a = one.clone();
let mut b = one.clone() / &two.clone().sqrt();
let mut t = one.clone() / &four;
let mut p = one.clone();
for _ in 0..iters {
let a_next = (a.clone() + &b) / &two;
let b_next = (a.clone() * &b).sqrt();
let diff = a.clone() - &a_next;
let t_next = t - &(p.clone() * &(diff.clone() * &diff));
let p_next = two.clone() * &p;
a = a_next;
b = b_next;
t = t_next;
p = p_next;
}
let sum = a + &b;
(sum.clone() * &sum) / &(four * &t)
}
fn agm_pi_f64(iters: usize) -> f64 {
let mut a = 1.0_f64;
let mut b = 1.0_f64 / 2.0_f64.sqrt();
let mut t = 0.25_f64;
let mut p = 1.0_f64;
for _ in 0..iters {
let a_next = (a + b) / 2.0;
let b_next = (a * b).sqrt();
let diff = a - a_next;
let t_next = t - p * diff * diff;
let p_next = 2.0 * p;
a = a_next;
b = b_next;
t = t_next;
p = p_next;
}
let sum = a + b;
sum * sum / (4.0 * t)
}
fn criterion_config() -> Criterion {
Criterion::default()
.warm_up_time(Duration::from_secs(3))
.measurement_time(Duration::from_secs(15))
.sample_size(50)
.noise_threshold(0.02)
}
fn bench_agm_pi(c: &mut Criterion) {
let mut group = c.benchmark_group("agm_pi");
group.throughput(Throughput::Elements(AGM_ITERATIONS as u64));
group.bench_function("BoolBitArray", |b| {
b.iter(|| black_box(agm_pi::<BoolBitArray>(black_box(AGM_ITERATIONS))))
});
group.bench_function("UsizeBitArray", |b| {
b.iter(|| black_box(agm_pi::<UsizeBitArray>(black_box(AGM_ITERATIONS))))
});
group.bench_function("f64_baseline", |b| {
b.iter(|| black_box(agm_pi_f64(black_box(AGM_ITERATIONS))))
});
group.finish();
}
criterion_group! {
name = benches;
config = criterion_config();
targets = bench_agm_pi
}
criterion_main!(benches);