use iqdb_quantize::{BinaryQuantizer, Quantizer};
use iqdb_types::{DistanceMetric, IqdbError};
fn main() -> Result<(), IqdbError> {
let corpus: [&[f32]; 4] = [
&[0.1, 0.2, 0.9, 0.8], &[0.2, 0.1, 0.8, 0.9], &[0.9, 0.8, 0.1, 0.2], &[0.8, 0.9, 0.2, 0.1], ];
let mut bq = BinaryQuantizer::new();
bq.train(&corpus)?;
let codes = corpus
.iter()
.map(|v| bq.quantize(v))
.collect::<Result<Vec<_>, _>>()?;
let f32_bytes = size_of_val(corpus[0]);
let code_bytes = size_of_val(codes[0].as_words());
println!(
"dim {} packs into {} u64 word(s) = {code_bytes} bytes (from {f32_bytes} f32 bytes; \
one bit per dimension, 32x at realistic dims)",
codes[0].dim(),
codes[0].as_words().len(),
);
println!("\npairwise Hamming distance:");
for code in &codes {
for other in &corpus {
let d = bq.distance(other, code, DistanceMetric::Hamming)?;
print!(" {d:>3.0}");
}
println!();
}
let err = bq
.distance(&[0.5_f32, 0.5, 0.5, 0.5], &codes[0], DistanceMetric::Cosine)
.unwrap_err();
println!("\nCosine against a binary code is rejected: {err:?}");
Ok(())
}