use reqsketch::{RankAccuracy, ReqSketch, SearchCriteria};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("REQ Sketch Demo - Relative Error Quantiles");
println!("==========================================\n");
let mut sketch = ReqSketch::new();
println!("Created REQ sketch with k={}", sketch.k());
println!("Adding 10,000 random values...");
for i in 0..10_000 {
let value = (i as f64) + (i as f64 * 0.1).sin() * 100.0; sketch.update(value);
}
println!("Sketch statistics:");
println!(" Total items processed: {}", sketch.len());
println!(" Items retained: {}", sketch.num_retained());
println!(" Estimation mode: {}", sketch.is_estimation_mode());
println!(" Min value: {:?}", sketch.min_item());
println!(" Max value: {:?}", sketch.max_item());
println!();
println!("Quantile queries:");
let quantiles = [0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99, 1.0];
for &q in &quantiles {
let value = sketch.quantile(q, SearchCriteria::Inclusive)?;
println!(" {:.0}th percentile: {:.2}", q * 100.0, value);
}
println!();
println!("Rank queries:");
let test_values = [1000.0, 5000.0, 9000.0];
for &value in &test_values {
let rank = sketch.rank(&value, SearchCriteria::Inclusive)?;
println!(" Rank of {:.0}: {:.4} ({:.1}%)", value, rank, rank * 100.0);
}
println!();
println!("Probability Mass Function:");
let split_points = [2000.0, 5000.0, 8000.0];
let pmf = sketch.pmf(&split_points, SearchCriteria::Inclusive)?;
println!(" Intervals and their probabilities:");
println!(" (-∞, {:.0}]: {:.4}", split_points[0], pmf[0]);
for i in 1..split_points.len() {
println!(
" ({:.0}, {:.0}]: {:.4}",
split_points[i - 1],
split_points[i],
pmf[i]
);
}
println!(
" ({:.0}, ∞): {:.4}",
split_points[split_points.len() - 1],
pmf[pmf.len() - 1]
);
println!();
println!("Comparing accuracy modes:");
let _high_rank_sketch: ReqSketch<f64> = ReqSketch::builder()
.k(16)?
.rank_accuracy(RankAccuracy::HighRank)
.build()?;
let _low_rank_sketch: ReqSketch<f64> = ReqSketch::builder()
.k(16)?
.rank_accuracy(RankAccuracy::LowRank)
.build()?;
println!(" High rank accuracy mode optimizes for accuracy near rank 1.0");
println!(" Low rank accuracy mode optimizes for accuracy near rank 0.0");
println!();
println!("Sketch merging demonstration:");
let mut sketch1 = ReqSketch::new();
let mut sketch2 = ReqSketch::new();
for i in 0..1000 {
sketch1.update(i as f64);
sketch2.update((i + 1000) as f64);
}
println!(
" Sketch 1: {} items, median = {:.2}",
sketch1.len(),
sketch1.quantile(0.5, SearchCriteria::Inclusive)?
);
println!(
" Sketch 2: {} items, median = {:.2}",
sketch2.len(),
sketch2.quantile(0.5, SearchCriteria::Inclusive)?
);
sketch1.merge(&sketch2)?;
println!(
" Merged sketch: {} items, median = {:.2}",
sketch1.len(),
sketch1.quantile(0.5, SearchCriteria::Inclusive)?
);
println!("\nDemo completed successfully!");
Ok(())
}