Apply the randomised WHT rotation to a residual vector. Steps: 1. Apply signed-diagonal `D` (deterministic from `rotation_seed`). 2. Zero-pad to the next power of two if `dim` is not pow2. 3. WHT in-place. 4. Truncate back to `dim`.
(&self, v: &[f32])
| 183 | /// 3. WHT in-place. |
| 184 | /// 4. Truncate back to `dim`. |
| 185 | pub fn apply_rotation(&self, v: &[f32]) -> Vec<f32> { |
| 186 | let dim = self.dim; |
| 187 | let pow2 = next_pow2(dim); |
| 188 | |
| 189 | // Signed-diagonal multiply: generate ±1 per dim from seed. |
| 190 | let mut seed = self.rotation_seed; |
| 191 | let mut buf = vec![0.0f32; pow2]; |
| 192 | for (i, &vi) in v.iter().take(dim).enumerate() { |
| 193 | let flip = if xorshift64(&mut seed) & 1 == 0 { |
| 194 | 1.0f32 |
| 195 | } else { |
| 196 | -1.0f32 |
| 197 | }; |
| 198 | buf[i] = vi * flip; |
| 199 | } |
| 200 | // Trailing elements remain zero (pad). |
| 201 | |
| 202 | wht_inplace(&mut buf); |
| 203 | buf.truncate(dim); |
| 204 | buf |
| 205 | } |
| 206 | |
| 207 | /// Encode a single vector into a [`UnifiedQuantizedVector`] with |
| 208 | /// `QuantMode::RaBitQ`. |