Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions src/vectors/angular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,84 @@ pub fn bray_curtis<T: UInt, U: Float>(x: &[T], y: &[T]) -> U {
}
}
}

/// Computes the dot product between two vectors.
///
/// The dot product is defined as the sum of the products of the
/// corresponding entries of the two vectors.
///
/// # Arguments
///
/// * `x`: A slice of numbers.
/// * `y`: A slice of numbers.
///
/// # Examples
///
/// ```
/// use distances::vectors::dot_product;
///
/// let x: Vec<f32> = vec![1.0, 5.0, 4.0];
/// let y: Vec<f32> = vec![2.5, 3.0, 0.5];
///
/// let distance: f32 = dot_product(&x, &y);
///
/// assert!((distance - 19.5).abs() < f32::EPSILON);
/// ```
///
/// # References
///
/// * [Dot product](https://en.wikipedia.org/wiki/Dot_product)
pub fn dot_product<T: Number, U: Float>(x: &[T], y: &[T]) -> U {
let dot_product: T = x.iter().zip(y.iter()).map(|(&a, &b)| a * b).sum();

let dot_product: U = U::from(dot_product);

if dot_product < U::epsilon() {
U::zero()
} else {
dot_product
}
}

/// Computes a distance between two vectors using their dot product.
/// Vectors with greater dot products are considered more similar,
/// and hence have a smaller distance.
///
/// The dot product is defined as the sum of the products of the
/// corresponding entries of the two vectors.
///
/// Thia function is not stable.
///
/// See the [`crate::vectors`] module documentation for information on this
/// function's potentially unexpected behaviors
///
/// # Arguments
///
/// * `x`: A slice of numbers.
/// * `y`: A slice of numbers.
///
/// # Examples
///
/// ```
/// use distances::vectors::dot_product_distance;
///
/// let x: Vec<f32> = vec![1.0, 5.0, 4.0];
/// let y: Vec<f32> = vec![2.5, 3.0, 0.5];
///
/// let distance: f32 = dot_product_distance(&x, &y);
///
/// assert!((distance - 0.05128205128).abs() < f32::EPSILON);
/// ```
///
/// # References
///
/// * [Dot product](https://en.wikipedia.org/wiki/Dot_product)
pub fn dot_product_distance<T: Number, U: Float>(x: &[T], y: &[T]) -> U {
let dot_product: U = dot_product(x, y);

if dot_product < U::epsilon() {
dot_product
} else {
U::one() / dot_product
}
Comment on lines +265 to +269
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dot_product function already tests for a comparison with epsilon. The check here is unnecessary.

}
2 changes: 1 addition & 1 deletion src/vectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod angular;
mod lp_norms;
pub(crate) mod utils;

pub use angular::{bray_curtis, canberra, cosine, hamming};
pub use angular::{bray_curtis, canberra, cosine, dot_product_distance, hamming};
pub use lp_norms::{
chebyshev, euclidean, euclidean_sq, l3_norm, l4_norm, manhattan, minkowski, minkowski_p,
};