Asymmetric distance estimate: `q` is a prepared [`RaBitQQuery`], `v` is a stored quantized vector. Uses `query_norm` (exact ‖q−c‖) against `v.residual_norm` (exact ‖v−c‖) for higher fidelity than the symmetric variant. If `self.bias_correct = true`, subtract `v.dot_quantized` as a first- order IP-bias correction term (TurboQuant-style).
(&self, q: &Self::Query, v: &Self::Quantized)
| 354 | /// If `self.bias_correct = true`, subtract `v.dot_quantized` as a first- |
| 355 | /// order IP-bias correction term (TurboQuant-style). |
| 356 | fn exact_asymmetric_distance(&self, q: &Self::Query, v: &Self::Quantized) -> f32 { |
| 357 | let vh = v.0.header(); |
| 358 | let vb = v.0.packed_bits(); |
| 359 | let h = hamming_distance(&q.rotated_signs, vb); |
| 360 | let dim = self.dim as f32; |
| 361 | let dot_estimate = 1.0 - 2.0 * h as f32 / dim; |
| 362 | let mut approx = q.query_norm * q.query_norm + vh.residual_norm * vh.residual_norm |
| 363 | - 2.0 * q.query_norm * vh.residual_norm * dot_estimate; |
| 364 | if self.bias_correct { |
| 365 | approx -= vh.dot_quantized; |
| 366 | } |
| 367 | approx.max(0.0) |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | // ── Tests ───────────────────────────────────────────────────────────────────── |