primitives/algebra/ops/
dot_product.rs1use super::wide_ops::MulAccReduce;
2use crate::{izip_eq, utils::IntoExactSizeIterator};
3
4pub trait DotProduct<Lhs = Self, Rhs = Lhs>: Sized {
5 fn dot<I1, I2>(a: I1, b: I2) -> Self
6 where
7 I1: IntoExactSizeIterator<Item = Lhs>,
8 I2: IntoExactSizeIterator<Item = Rhs>;
9}
10
11pub trait DefaultDotProduct<Lhs = Self, Rhs = Lhs>: MulAccReduce<Lhs, Rhs> {}
15
16impl<T, T1, T2> DotProduct<T1, T2> for T
18where
19 T: DefaultDotProduct<T1, T2>,
20{
21 fn dot<I1, I2>(a: I1, b: I2) -> Self
22 where
23 I1: IntoExactSizeIterator<Item = T1>,
24 I2: IntoExactSizeIterator<Item = T2>,
25 {
26 let tmp = izip_eq!(a, b).fold(
27 <T as MulAccReduce<T1, T2>>::zero_wide(),
28 |mut acc, (ae, be)| {
29 Self::mul_acc(&mut acc, ae, be);
30 acc
31 },
32 );
33
34 Self::reduce_mod_order(tmp)
35 }
36}