use crate::codec::quantize::{scalar_dequantize, scalar_quantize};
use crate::codec::residual::apply_residual_into as residual_apply_impl;
use crate::errors::CodecError;
use half::f16;
#[inline]
pub fn quantize_into(
entries: &[f32],
values: &[f32],
indices: &mut [u8],
) -> Result<(), CodecError> {
scalar_quantize(entries, values, indices)
}
#[inline]
pub fn dequantize_into(
entries: &[f32],
indices: &[u8],
values: &mut [f32],
) -> Result<(), CodecError> {
scalar_dequantize(entries, indices, values)
}
#[cfg_attr(not(feature = "simd"), allow(dead_code))]
#[inline]
pub fn cosine(a: &[f32], b: &[f32]) -> f32 {
debug_assert_eq!(a.len(), b.len());
if a.iter().any(|x| x.is_nan()) || b.iter().any(|x| x.is_nan()) {
return 0.0;
}
let mut dot: f32 = 0.0;
let mut na: f32 = 0.0;
let mut nb: f32 = 0.0;
for (&x, &y) in a.iter().zip(b.iter()) {
dot += x * y;
na += x * x;
nb += y * y;
}
let denom = libm::sqrtf(na * nb);
if denom == 0.0 {
0.0
} else {
dot / denom
}
}
#[cfg_attr(not(feature = "simd"), allow(dead_code))]
pub fn compute_residual_into(original: &[f32], reconstructed: &[f32], out: &mut [u8]) {
debug_assert_eq!(original.len(), reconstructed.len());
debug_assert_eq!(out.len(), original.len() * 2);
for ((o, r), chunk) in original
.iter()
.zip(reconstructed.iter())
.zip(out.chunks_exact_mut(2))
{
let diff = f16::from_f32(*o - *r);
let bytes = diff.to_le_bytes();
if let Some(first) = chunk.first_mut() {
*first = bytes[0];
}
if let Some(second) = chunk.get_mut(1) {
*second = bytes[1];
}
}
}
#[cfg_attr(not(feature = "simd"), allow(dead_code))]
#[inline]
pub fn apply_residual_into(values: &mut [f32], residual: &[u8]) -> Result<(), CodecError> {
residual_apply_impl(values, residual)
}