use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum UtilError {
#[error("Vectors must have the same length")]
VectorLengthMismatch,
}
pub fn cosine_similarity(vector1: &[f64], vector2: &[f64]) -> Result<f64, UtilError> {
if vector1.len() != vector2.len() {
return Err(UtilError::VectorLengthMismatch);
}
let n = vector1.len();
if n == 0 {
return Ok(0.0);
}
let mut magnitude_squared_1 = 0.0;
let mut magnitude_squared_2 = 0.0;
let mut dot_product = 0.0;
for i in 0..n {
let value1 = vector1[i];
let value2 = vector2[i];
magnitude_squared_1 += value1 * value1;
magnitude_squared_2 += value2 * value2;
dot_product += value1 * value2;
}
if magnitude_squared_1 == 0.0 || magnitude_squared_2 == 0.0 {
Ok(0.0)
} else {
Ok(dot_product / (magnitude_squared_1.sqrt() * magnitude_squared_2.sqrt()))
}
}