use super::qtypes::QuantError;
pub fn quantize_i8_symmetric(input: &[f32], output: &mut [i8]) -> Result<f32, QuantError> {
if input.is_empty() {
return Err(QuantError::Empty);
}
if output.len() < input.len() {
return Err(QuantError::ShapeMismatch);
}
let mut max_abs = 0.0f32;
for &v in input {
let a = v.abs();
if a > max_abs {
max_abs = a;
}
}
let scale = if max_abs <= 0.0 { 1.0 } else { max_abs / 127.0 };
if !scale.is_finite() || scale <= 0.0 {
return Err(QuantError::InvalidScale);
}
for i in 0..input.len() {
let q = crate::math::roundf(input[i] / scale).clamp(-127.0, 127.0);
output[i] = q as i8;
}
Ok(scale)
}
pub fn dequantize_i8_symmetric(input: &[i8], output: &mut [f32], scale: f32) -> Result<(), QuantError> {
if input.is_empty() {
return Err(QuantError::Empty);
}
if output.len() < input.len() {
return Err(QuantError::ShapeMismatch);
}
if !scale.is_finite() || scale <= 0.0 {
return Err(QuantError::InvalidScale);
}
for i in 0..input.len() {
output[i] = input[i] as f32 * scale;
}
Ok(())
}