pub mod product_quantizer;
pub mod codebook;
pub mod encoder;
pub mod decoder;
pub mod distance;
pub mod training;
pub use product_quantizer::{ProductQuantizer, ProductQuantizerConfig};
pub use codebook::Codebook;
pub use encoder::Encoder;
pub use decoder::Decoder;
pub use distance::DistanceComputer;
pub use training::train_codebook;
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct QuantizedVector {
pub codes: Vec<u8>,
}
impl QuantizedVector {
pub fn new(codes: Vec<u8>) -> Self {
Self { codes }
}
pub fn memory_size(&self) -> usize {
self.codes.len()
}
}
#[derive(Debug, thiserror::Error)]
pub enum PqError {
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Dimension mismatch: expected {expected}, got {actual}")]
DimensionMismatch { expected: usize, actual: usize },
#[error("Training error: {0}")]
TrainingError(String),
#[error("Encoding error: {0}")]
EncodingError(String),
#[error("Decoding error: {0}")]
DecodingError(String),
#[error("Invalid sub-quantizer index: {0}")]
InvalidSubQuantizerIndex(usize),
#[error("Invalid centroid index: {0}")]
InvalidCentroidIndex(usize),
#[error("Insufficient training data: got {0} samples, need at least {1}")]
InsufficientTrainingData(usize, usize),
}
pub type PqResult<T> = std::result::Result<T, PqError>;
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn test_quantized_vector_creation() {
let codes = vec![23, 156, 87, 12, 200, 45, 178, 91];
let qv = QuantizedVector::new(codes.clone());
assert_eq!(qv.codes, codes);
assert_eq!(qv.memory_size(), 8);
}
}