Skip to main content

competitive/num/mint/
mint_dot_product.rs

1use super::{DotProduct, MInt, MIntBase};
2
3pub trait MIntDotProduct: MIntBase + Sized {
4    fn try_matrix_product(
5        _a: &[Vec<MInt<Self>>],
6        _b: &[Vec<MInt<Self>>],
7    ) -> Option<Vec<Vec<MInt<Self>>>> {
8        None
9    }
10
11    fn dot_product(x: &[MInt<Self>], y: &[MInt<Self>]) -> MInt<Self> {
12        assert_eq!(x.len(), y.len());
13        x.iter()
14            .zip(y)
15            .fold(MInt::new_unchecked(Self::mod_zero()), |sum, (&x, &y)| {
16                sum + x * y
17            })
18    }
19
20    fn add_scaled_assign(x: &mut [MInt<Self>], y: &[MInt<Self>], a: &MInt<Self>) {
21        assert_eq!(x.len(), y.len());
22        for (x, y) in x.iter_mut().zip(y) {
23            *x += *a * *y;
24        }
25    }
26}
27
28impl<M> DotProduct for MInt<M>
29where
30    M: MIntDotProduct,
31{
32    #[inline]
33    fn try_matrix_product(a: &[Vec<Self>], b: &[Vec<Self>]) -> Option<Vec<Vec<Self>>> {
34        M::try_matrix_product(a, b)
35    }
36
37    #[inline]
38    fn dot_product(x: &[Self], y: &[Self]) -> Self {
39        assert_eq!(x.len(), y.len());
40        M::dot_product(x, y)
41    }
42
43    #[inline]
44    fn add_scaled_assign(x: &mut [Self], y: &[Self], a: &Self) {
45        M::add_scaled_assign(x, y, a);
46    }
47}