competitive/num/mint/
mint_dot_product.rs1use 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}