use anyhow::Result;
pub fn vector_to_blob(v: &[f32]) -> Vec<u8> {
bytemuck::cast_slice(v).to_vec()
}
pub fn blob_to_vector(blob: &[u8]) -> Result<Vec<f32>> {
let v = bytemuck::cast_slice::<u8, f32>(blob).to_vec();
Ok(v)
}
pub fn dot(a: &[f32], b: &[f32]) -> f32 {
a.iter().zip(b.iter()).map(|(x, y)| x * y).sum()
}
pub fn norm(v: &[f32]) -> f32 {
v.iter().map(|x| x * x).sum::<f32>().sqrt()
}
#[allow(dead_code)]
pub fn normalize(v: &[f32]) -> Vec<f32> {
let n = norm(v);
if n == 0.0 {
v.to_vec()
} else {
v.iter().map(|x| x / n).collect()
}
}
#[allow(dead_code)]
pub fn cosine_similarity(a: &[f32], b: &[f32]) -> f32 {
dot(a, b)
}
#[allow(dead_code)]
pub fn cosine_similarity_raw(a: &[f32], b: &[f32]) -> f32 {
let na = norm(a);
let nb = norm(b);
if na == 0.0 || nb == 0.0 {
return 0.0;
}
dot(a, b) / (na * nb)
}