use std::ops::{Add, Mul};
use num_traits::Zero;
use ordered_iter::OrderedMapIterator;
use Dot;
use super::SparseVector;
impl<T> Dot for SparseVector<T>
where
T: Copy + Add<T, Output = T> + Mul<T, Output = T> + Zero,
{
type Scalar = T;
fn dot(&self, rhs: &Self) -> Self::Scalar {
let lhs_iter = self.iter();
let rhs_iter = rhs.iter();
lhs_iter.inner_join_map(rhs_iter).fold(T::zero(), |sum, (_, (lhs, rhs))| {
sum + (lhs * rhs)
})
}
}
#[cfg(test)]
mod test {
use super::*;
use expectest::prelude::*;
#[test]
fn dot() {
let subject = SparseVector::from(vec![(0, 0.2), (1, 0.5), (2, 1.0), (4, 2.0), (5, 4.0)]);
let other = SparseVector::from(vec![(1, 0.1), (2, 0.2), (3, 0.3), (5, 0.4), (6, 0.5)]);
let dot = subject.dot(&other);
expect!(dot).to(be_close_to(1.85));
}
}