RaBitQ

Struct RaBitQ 

Source
pub struct RaBitQ { /* private fields */ }
Expand description

RaBitQ quantizer

Implements scalar quantization with trained per-dimension ranges. Training computes min/max per dimension from sample data, enabling consistent quantization across all vectors and correct ADC distances.

§Usage

// Create and train quantizer
let mut quantizer = RaBitQ::new(RaBitQParams::bits4());
quantizer.train(&sample_vectors);

// Quantize vectors
let quantized = quantizer.quantize(&vector);

// ADC search (distances are mathematically correct)
let adc = quantizer.build_adc_table(&query);
let dist = adc.distance(&quantized.data);

Implementations§

Source§

impl RaBitQ

Source

pub fn new(params: RaBitQParams) -> Self

Create a new RaBitQ quantizer (untrained)

Call train() before use to enable correct ADC distances.

Source

pub fn new_trained(params: RaBitQParams, trained: TrainedParams) -> Self

Create a trained RaBitQ quantizer

Source

pub fn default_4bit() -> Self

Create with default 4-bit quantization

Source

pub fn params(&self) -> &RaBitQParams

Get quantization parameters

Source

pub fn is_trained(&self) -> bool

Check if quantizer has been trained

Source

pub fn trained_params(&self) -> Option<&TrainedParams>

Get trained parameters (if any)

Source

pub fn train(&mut self, vectors: &[&[f32]]) -> Result<(), &'static str>

Train quantizer on sample vectors

Computes per-dimension min/max ranges from the sample. Must be called before quantization for correct ADC distances.

§Arguments
  • vectors - Representative sample of vectors to train from
§Errors

Returns error if vectors is empty or have inconsistent dimensions.

Source

pub fn train_owned(&mut self, vectors: &[Vec<f32>]) -> Result<(), &'static str>

Train with owned vectors (convenience method)

§Errors

Returns error if vectors is empty or have inconsistent dimensions.

Source

pub fn quantize(&self, vector: &[f32]) -> QuantizedVector

Quantize a vector using trained parameters

If trained: uses per-dimension min/max for consistent quantization If untrained: falls back to legacy per-vector scaling (deprecated)

Source

pub fn unpack_quantized( &self, packed: &[u8], bits: u8, dimensions: usize, ) -> Vec<u8>

Unpack quantized bytes into individual values

Source

pub fn reconstruct( &self, quantized: &[u8], scale: f32, dimensions: usize, ) -> Vec<f32>

Reconstruct (dequantize) a quantized vector

Algorithm (Extended RaBitQ):

  1. Unpack bytes to quantized values [0, 2^bits-1]
  2. Denormalize: v’ = q / (2^bits - 1)
  3. Unscale: v = v’ / scale
Source

pub fn distance_l2(&self, qv1: &QuantizedVector, qv2: &QuantizedVector) -> f32

Compute L2 (Euclidean) distance between two quantized vectors

This reconstructs both vectors and computes standard L2 distance. For maximum accuracy, use this with original vectors for reranking.

Source

pub fn distance_cosine( &self, qv1: &QuantizedVector, qv2: &QuantizedVector, ) -> f32

Compute cosine distance between two quantized vectors

Cosine distance = 1 - cosine similarity

Source

pub fn distance_dot(&self, qv1: &QuantizedVector, qv2: &QuantizedVector) -> f32

Compute dot product between two quantized vectors

Source

pub fn distance_approximate( &self, qv1: &QuantizedVector, qv2: &QuantizedVector, ) -> f32

Compute approximate distance using quantized values directly (fast path)

This computes distance in the quantized space without full reconstruction. Faster but less accurate than distance_l2.

Source

pub fn distance_asymmetric_l2( &self, query: &[f32], quantized: &QuantizedVector, ) -> f32

Compute asymmetric L2 distance (query vs quantized) without full reconstruction

This is the hot path for search! It unpacks quantized values on the fly and computes distance against the uncompressed query vector.

When trained: Uses per-dimension min/max for correct distance computation. When untrained: Falls back to per-vector scale (deprecated, lower accuracy).

Source

pub fn distance_asymmetric_l2_flat( &self, query: &[f32], data: &[u8], scale: f32, ) -> f32

Asymmetric L2 distance from flat storage (no QuantizedVector wrapper)

This is the preferred method for flat contiguous storage layouts. When trained: Uses per-dimension min/max (scale ignored). When untrained: Falls back to per-vector scale.

Source

pub fn build_adc_table(&self, query: &[f32]) -> Option<ADCTable>

Build an ADC (Asymmetric Distance Computation) lookup table for a query

If trained: uses per-dimension min/max for correct distances If untrained: uses provided scale (deprecated, incorrect distances)

§Example
// Preferred: train first, then build ADC table
quantizer.train(&sample_vectors);
let adc_table = quantizer.build_adc_table(&query);
for candidate in candidates {
    let dist = adc_table.distance(&candidate.data);
}
Source

pub fn build_adc_table_with_scale(&self, query: &[f32], scale: f32) -> ADCTable

Build ADC table with explicit scale

§Note

Prefer build_adc_table() on a trained quantizer for correct ADC distances. This method uses per-vector scale which gives lower accuracy.

Source

pub fn distance_with_adc( &self, query: &[f32], quantized: &QuantizedVector, ) -> Option<f32>

Compute distance using ADC table (convenience wrapper)

Returns None if quantizer is not trained.

Source

pub fn distance_asymmetric_l2_raw( &self, query: &[f32], data: &[u8], scale: f32, bits: u8, ) -> f32

Low-level asymmetric distance computation on raw bytes

Enables zero-copy access from mmap (no QuantizedVector allocation needed). Uses SmallVec to unpack on stack and SIMD for distance computation.

Source

pub fn distance_l2_simd( &self, qv1: &QuantizedVector, qv2: &QuantizedVector, ) -> f32

Compute L2 distance using SIMD acceleration

Uses runtime CPU detection to select the best SIMD implementation:

  • x86_64: AVX2 > SSE2 > scalar
  • aarch64: NEON > scalar
Source

pub fn distance_cosine_simd( &self, qv1: &QuantizedVector, qv2: &QuantizedVector, ) -> f32

Compute cosine distance using SIMD acceleration

Trait Implementations§

Source§

impl Clone for RaBitQ

Source§

fn clone(&self) -> RaBitQ

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RaBitQ

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for RaBitQ

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for RaBitQ

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for RaBitQ

§

impl RefUnwindSafe for RaBitQ

§

impl Send for RaBitQ

§

impl Sync for RaBitQ

§

impl Unpin for RaBitQ

§

impl UnwindSafe for RaBitQ

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Sync + Send>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> Fruit for T
where T: Send + Downcast,