use iqdb_quantize::{BinaryQuantizer, ProductQuantizer, Quantizer, ScalarQuantizer};
use iqdb_types::IqdbError;
const DIM: usize = 768;
fn main() -> Result<(), IqdbError> {
let corpus: Vec<Vec<f32>> = (0..128)
.map(|i| {
(0..DIM)
.map(|d| (((i * 31 + d * 17) % 251) as f32 / 251.0) - 0.5)
.collect()
})
.collect();
let refs: Vec<&[f32]> = corpus.iter().map(Vec::as_slice).collect();
let sample = &corpus[0];
let raw_bytes = DIM * size_of::<f32>();
println!("raw f32 vector: {DIM} dims = {raw_bytes} bytes\n");
println!("{:<8} {:>8} {:>14}", "scheme", "bytes", "compression");
println!("{:-<32}", "");
let mut sq = ScalarQuantizer::new();
sq.train(&refs)?;
let sq_bytes = sq.quantize(sample)?.len();
report("SQ8", sq_bytes, raw_bytes);
let mut pq = ProductQuantizer::with_config(16, 64, 7);
pq.train(&refs)?;
let pq_bytes = pq.quantize(sample)?.len();
report("PQ(16)", pq_bytes, raw_bytes);
let mut bq = BinaryQuantizer::new();
bq.train(&refs)?;
let bq_code = bq.quantize(sample)?;
let bq_bytes = size_of_val(bq_code.as_words());
report("BQ", bq_bytes, raw_bytes);
Ok(())
}
fn report(name: &str, bytes: usize, raw_bytes: usize) {
let ratio = raw_bytes as f32 / bytes as f32;
println!("{name:<8} {bytes:>8} {ratio:>13.0}x");
}