qfall_math/integer/poly_over_z/arithmetic/
mul.rs1use super::super::PolyOverZ;
12use crate::macros::arithmetics::{
13 arithmetic_assign_trait_borrowed_to_owned, arithmetic_trait_borrowed_to_owned,
14 arithmetic_trait_mixed_borrowed_owned,
15};
16use flint_sys::fmpz_poly::fmpz_poly_mul;
17use std::ops::{Mul, MulAssign};
18
19impl MulAssign<&PolyOverZ> for PolyOverZ {
20 fn mul_assign(&mut self, other: &Self) {
40 unsafe { fmpz_poly_mul(&mut self.poly, &self.poly, &other.poly) };
41 }
42}
43
44arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, PolyOverZ, PolyOverZ);
45
46impl Mul for &PolyOverZ {
47 type Output = PolyOverZ;
48 fn mul(self, other: Self) -> Self::Output {
70 let mut out = PolyOverZ::default();
71 unsafe {
72 fmpz_poly_mul(&mut out.poly, &self.poly, &other.poly);
73 }
74 out
75 }
76}
77
78arithmetic_trait_borrowed_to_owned!(Mul, mul, PolyOverZ, PolyOverZ, PolyOverZ);
79arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverZ, PolyOverZ, PolyOverZ);
80
81#[cfg(test)]
82mod test_mul_assign {
83 use super::PolyOverZ;
84 use std::str::FromStr;
85
86 #[test]
88 fn correct_small() {
89 let mut a = PolyOverZ::from_str("3 -1 2 -3").unwrap();
90 let b = PolyOverZ::from_str("2 5 2").unwrap();
91 let cmp = PolyOverZ::from_str("4 -5 8 -11 -6").unwrap();
92
93 a *= b;
94
95 assert_eq!(cmp, a);
96 }
97
98 #[test]
100 fn correct_large() {
101 let mut a = PolyOverZ::from_str(&format!("1 {}", i32::MIN)).unwrap();
102 let b = PolyOverZ::from_str(&format!("2 {} {}", i32::MAX, i32::MIN)).unwrap();
103 let cmp = PolyOverZ::from_str(&format!(
104 "2 {} {}",
105 i32::MIN as i64 * i32::MAX as i64,
106 i32::MIN as i64 * i32::MIN as i64
107 ))
108 .unwrap();
109
110 a *= b;
111
112 assert_eq!(cmp, a);
113 }
114
115 #[test]
117 fn availability() {
118 let mut a = PolyOverZ::from_str("3 1 2 -3").unwrap();
119 let b = PolyOverZ::from_str("3 -1 -2 3").unwrap();
120
121 a *= &b;
122 a *= b;
123 }
124}
125
126#[cfg(test)]
127mod test_mul {
128 use super::PolyOverZ;
129 use std::str::FromStr;
130
131 #[test]
133 fn mul() {
134 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
135 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
136 let c: PolyOverZ = a * b;
137 assert_eq!(c, PolyOverZ::from_str("7 1 4 6 5 -11 1 -6").unwrap());
138 }
139
140 #[test]
142 fn mul_borrow() {
143 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
144 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
145 let c: PolyOverZ = &a * &b;
146 assert_eq!(c, PolyOverZ::from_str("7 1 4 6 5 -11 1 -6").unwrap());
147 }
148
149 #[test]
151 fn mul_first_borrowed() {
152 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
153 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
154 let c: PolyOverZ = &a * b;
155 assert_eq!(c, PolyOverZ::from_str("7 1 4 6 5 -11 1 -6").unwrap());
156 }
157
158 #[test]
160 fn mul_second_borrowed() {
161 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
162 let b: PolyOverZ = PolyOverZ::from_str("5 1 2 5 1 2").unwrap();
163 let c: PolyOverZ = a * &b;
164 assert_eq!(c, PolyOverZ::from_str("7 1 4 6 5 -11 1 -6").unwrap());
165 }
166
167 #[test]
169 fn mul_constant() {
170 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
171 let b: PolyOverZ = PolyOverZ::from(4);
172 let c: PolyOverZ = a * b;
173 assert_eq!(c, PolyOverZ::from_str("3 4 8 -12").unwrap());
174 }
175
176 #[test]
178 fn mul_zero() {
179 let a: PolyOverZ = PolyOverZ::from_str("3 1 2 -3").unwrap();
180 let b: PolyOverZ = PolyOverZ::default();
181 let c: PolyOverZ = a * b;
182 assert_eq!(c, PolyOverZ::default());
183 }
184
185 #[test]
187 fn mul_large_numbers() {
188 let a: PolyOverZ = PolyOverZ::from_str(&format!("2 {} {}", u16::MAX, i32::MIN)).unwrap();
189 let b: PolyOverZ = PolyOverZ::from_str(&format!("2 {} {}", u32::MAX, i32::MAX)).unwrap();
190 let c: PolyOverZ = a * b;
191 assert_eq!(
192 c,
193 PolyOverZ::from_str(&format!(
194 "3 {} {} {}",
195 i64::from(u16::MAX) * i64::from(u32::MAX),
196 i64::from(u16::MAX) * i64::from(i32::MAX)
197 + i64::from(u32::MAX) * i64::from(i32::MIN),
198 i64::from(i32::MAX) * i64::from(i32::MIN)
199 ))
200 .unwrap()
201 );
202 }
203}