qfall_math/rational/poly_over_q/arithmetic/
mul_scalar.rs1use super::super::PolyOverQ;
12use crate::integer::Z;
13use crate::macros::arithmetics::{
14 arithmetic_assign_between_types, arithmetic_assign_trait_borrowed_to_owned,
15 arithmetic_trait_borrowed_to_owned, arithmetic_trait_mixed_borrowed_owned,
16 arithmetic_trait_reverse,
17};
18use crate::macros::for_others::implement_for_others;
19use crate::rational::Q;
20use flint_sys::fmpq_poly::{
21 fmpq_poly_scalar_mul_fmpq, fmpq_poly_scalar_mul_fmpz, fmpq_poly_scalar_mul_si,
22 fmpq_poly_scalar_mul_ui,
23};
24use std::ops::{Mul, MulAssign};
25
26impl Mul<&Z> for &PolyOverQ {
27 type Output = PolyOverQ;
28 fn mul(self, scalar: &Z) -> Self::Output {
49 let mut out = PolyOverQ::default();
50 unsafe {
51 fmpq_poly_scalar_mul_fmpz(&mut out.poly, &self.poly, &scalar.value);
52 }
53 out
54 }
55}
56
57arithmetic_trait_reverse!(Mul, mul, Z, PolyOverQ, PolyOverQ);
58
59arithmetic_trait_borrowed_to_owned!(Mul, mul, PolyOverQ, Z, PolyOverQ);
60arithmetic_trait_borrowed_to_owned!(Mul, mul, Z, PolyOverQ, PolyOverQ);
61arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverQ, Z, PolyOverQ);
62arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Z, PolyOverQ, PolyOverQ);
63
64implement_for_others!(Z, PolyOverQ, PolyOverQ, Mul Scalar for i8 i16 i32 i64 u8 u16 u32 u64);
65
66impl Mul<&Q> for &PolyOverQ {
67 type Output = PolyOverQ;
68 fn mul(self, scalar: &Q) -> Self::Output {
88 let mut out = PolyOverQ::default();
89 unsafe {
90 fmpq_poly_scalar_mul_fmpq(&mut out.poly, &self.poly, &scalar.value);
91 }
92 out
93 }
94}
95
96arithmetic_trait_reverse!(Mul, mul, Q, PolyOverQ, PolyOverQ);
97
98arithmetic_trait_borrowed_to_owned!(Mul, mul, PolyOverQ, Q, PolyOverQ);
99arithmetic_trait_borrowed_to_owned!(Mul, mul, Q, PolyOverQ, PolyOverQ);
100arithmetic_trait_mixed_borrowed_owned!(Mul, mul, PolyOverQ, Q, PolyOverQ);
101arithmetic_trait_mixed_borrowed_owned!(Mul, mul, Q, PolyOverQ, PolyOverQ);
102
103implement_for_others!(Q, PolyOverQ, PolyOverQ, Mul Scalar for f32 f64);
104
105impl MulAssign<&Q> for PolyOverQ {
106 fn mul_assign(&mut self, scalar: &Q) {
132 unsafe { fmpq_poly_scalar_mul_fmpq(&mut self.poly, &self.poly, &scalar.value) };
133 }
134}
135
136impl MulAssign<&Z> for PolyOverQ {
137 fn mul_assign(&mut self, other: &Z) {
139 unsafe { fmpq_poly_scalar_mul_fmpz(&mut self.poly, &self.poly, &other.value) };
140 }
141}
142
143impl MulAssign<i64> for PolyOverQ {
144 fn mul_assign(&mut self, other: i64) {
146 unsafe { fmpq_poly_scalar_mul_si(&mut self.poly, &self.poly, other) };
147 }
148}
149
150impl MulAssign<u64> for PolyOverQ {
151 fn mul_assign(&mut self, other: u64) {
153 unsafe { fmpq_poly_scalar_mul_ui(&mut self.poly, &self.poly, other) };
154 }
155}
156
157arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, PolyOverQ, Q);
158arithmetic_assign_trait_borrowed_to_owned!(MulAssign, mul_assign, PolyOverQ, Z);
159arithmetic_assign_between_types!(MulAssign, mul_assign, PolyOverQ, i64, i32 i16 i8);
160arithmetic_assign_between_types!(MulAssign, mul_assign, PolyOverQ, u64, u32 u16 u8);
161arithmetic_assign_between_types!(MulAssign, mul_assign, PolyOverQ, Q, f64 f32);
162
163#[cfg(test)]
164mod test_mul_z {
165 use super::PolyOverQ;
166 use crate::integer::Z;
167 use std::str::FromStr;
168
169 #[test]
171 fn borrowed_correctness() {
172 let poly_1 = PolyOverQ::from_str(&format!("3 1/2 2/5 {}", i64::MAX)).unwrap();
173 let poly_2 = poly_1.clone();
174 let poly_3 = PolyOverQ::from_str(&format!("3 1 4/5 {}", (i64::MAX as u64) * 2)).unwrap();
175 let integer = Z::from(2);
176
177 let poly_1 = &poly_1 * &integer;
178 let poly_2 = &integer * &poly_2;
179
180 assert_eq!(poly_3, poly_1);
181 assert_eq!(poly_3, poly_2);
182 }
183
184 #[test]
186 fn availability() {
187 let poly = PolyOverQ::from_str("3 1/2 2 3/8").unwrap();
188 let z = Z::from(2);
189
190 _ = poly.clone() * z.clone();
191 _ = poly.clone() * 2i8;
192 _ = poly.clone() * 2u8;
193 _ = poly.clone() * 2i16;
194 _ = poly.clone() * 2u16;
195 _ = poly.clone() * 2i32;
196 _ = poly.clone() * 2u32;
197 _ = poly.clone() * 2i64;
198 _ = poly.clone() * 2u64;
199
200 _ = z.clone() * poly.clone();
201 _ = 2i8 * poly.clone();
202 _ = 2u64 * poly.clone();
203
204 _ = &poly * &z;
205 _ = &z * &poly;
206 _ = &poly * z.clone();
207 _ = z.clone() * &poly;
208 _ = &z * poly.clone();
209 _ = poly.clone() * &z;
210 _ = &poly * 2i8;
211 _ = 2i8 * &poly;
212 }
213}
214
215#[cfg(test)]
216mod test_mul_q {
217 use crate::rational::{PolyOverQ, Q};
218 use std::str::FromStr;
219
220 #[test]
222 fn borrowed_correctness() {
223 let poly_1 = PolyOverQ::from_str(&format!("3 1 2 {}", (i64::MAX as u64) * 2)).unwrap();
224 let poly_2 = poly_1.clone();
225 let poly_3 = PolyOverQ::from_str(&format!("3 1/2 1 {}", i64::MAX)).unwrap();
226 let rational = Q::from((1, 2));
227
228 let poly_1 = &poly_1 * &rational;
229 let poly_2 = &rational * &poly_2;
230
231 assert_eq!(poly_3, poly_1);
232 assert_eq!(poly_3, poly_2);
233 }
234
235 #[test]
237 fn availability() {
238 let poly = PolyOverQ::from_str("3 1/2 2 3/7").unwrap();
239 let q = Q::from((1, 2));
240
241 _ = poly.clone() * q.clone();
242 _ = q.clone() * poly.clone();
243 _ = &poly * &q;
244 _ = &q * &poly;
245 _ = &poly * q.clone();
246 _ = q.clone() * &poly;
247 _ = &q * poly.clone();
248 _ = poly.clone() * &q;
249 _ = &poly * 1.0_f32;
250 _ = &poly * 1.0_f64;
251 }
252}
253
254#[cfg(test)]
255mod test_mul_assign {
256 use crate::integer::Z;
257 use crate::rational::{PolyOverQ, Q};
258 use std::str::FromStr;
259
260 #[test]
262 fn correct_small() {
263 let mut a = PolyOverQ::from_str("3 1 2 -3/2").unwrap();
264 let b = Z::from(2);
265 let c = Q::from((2, 5));
266 let d = Z::ZERO;
267
268 a *= &b;
269 assert_eq!(PolyOverQ::from_str("3 2 4 -3").unwrap(), a);
270
271 a *= &c;
272 assert_eq!(PolyOverQ::from_str("3 4/5 8/5 -6/5").unwrap(), a);
273 a *= &d;
274 assert_eq!(PolyOverQ::from(0), a);
275 }
276
277 #[test]
279 fn correct_large() {
280 let mut a = PolyOverQ::from_str("2 2 -1").unwrap();
281 let b = Q::from((1, i32::MAX));
282 let cmp =
283 PolyOverQ::from_str(&format!("2 2/{} 1/{}", i32::MAX, -(i32::MAX as i64))).unwrap();
284
285 a *= b;
286
287 assert_eq!(cmp, a);
288 }
289
290 #[test]
292 fn availability() {
293 let mut a = PolyOverQ::from_str("3 1 2 -1/3").unwrap();
294 let b = Z::from(2);
295 let c = Q::from((2, 3));
296
297 a *= &b;
298 a *= b;
299 a *= &c;
300 a *= c;
301 a *= 1_u8;
302 a *= 1_u16;
303 a *= 1_u32;
304 a *= 1_u64;
305 a *= 1_i8;
306 a *= 1_i16;
307 a *= 1_i32;
308 a *= 1_i64;
309 a *= 1.0_f32;
310 a *= 1.0_f64;
311 }
312}