malachite_nz/integer_polynomial/arithmetic/mod_op.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::integer::Integer;
10use crate::integer_polynomial::IntegerPolynomial;
11use crate::natural::Natural;
12use crate::natural_polynomial::NaturalPolynomial;
13use alloc::vec::Vec;
14use core::ops::{Rem, RemAssign};
15use malachite_base::num::arithmetic::traits::{Mod, NegMod};
16use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
17use malachite_base::num::conversion::traits::ExactFrom;
18use malachite_base::polynomial::Polynomial;
19use malachite_base::unsigned_polynomial::UnsignedPolynomial;
20
21impl Mod<Natural> for IntegerPolynomial {
22 type Output = NaturalPolynomial;
23
24 /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
25 /// remainders as a [`NaturalPolynomial`], taking the polynomial by value and the modulus by
26 /// value.
27 ///
28 /// Each remainder is taken in $[0, m)$, the way [`Mod`] does for [`Integer`]s, so a negative
29 /// coefficient $c$ that is not a multiple of $m$ becomes $m - (-c \bmod m)$. The result is
30 /// therefore reduced modulo $m$, which is to say that
31 /// [`mod_is_reduced`](malachite_base::num::arithmetic::traits::ModIsReduced::mod_is_reduced)
32 /// returns `true` for it, and every coefficient of the result is congruent to the corresponding
33 /// coefficient of the input.
34 ///
35 /// Reducing can lower the degree, and can even give the zero polynomial: a leading coefficient
36 /// that is a multiple of $m$ becomes zero, and a polynomial does not hold trailing zero
37 /// coefficients. So $-6x^2 + 3x - 1$ modulo $3$ is the constant $2$.
38 ///
39 /// $$
40 /// f(p, m) = q, \quad \text{where} \quad q_i = p_i - m \left \lfloor \frac{p_i}{m}
41 /// \right \rfloor.
42 /// $$
43 ///
44 /// # Worst-case complexity
45 /// $T(n) = O(n \log n \log\log n)$
46 ///
47 /// $M(n) = O(n \log n)$
48 ///
49 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
50 /// polynomial's coefficients.
51 ///
52 /// # Panics
53 /// Panics if `m` is zero.
54 ///
55 /// # Examples
56 /// ```
57 /// use core::str::FromStr;
58 /// use malachite_base::num::arithmetic::traits::Mod;
59 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
60 /// use malachite_nz::natural::Natural;
61 ///
62 /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
63 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
64 /// assert_eq!(
65 /// p.clone().mod_op(Natural::from(3u32)).to_string(),
66 /// "x^2+2*x+1"
67 /// );
68 ///
69 /// // Reducing the leading coefficient to zero lowers the degree.
70 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
71 /// assert_eq!(p.clone().mod_op(Natural::from(3u32)).to_string(), "2");
72 /// ```
73 #[inline]
74 fn mod_op(self, m: Natural) -> NaturalPolynomial {
75 self.mod_op(&m)
76 }
77}
78
79impl<'a> Mod<&'a Natural> for IntegerPolynomial {
80 type Output = NaturalPolynomial;
81
82 /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
83 /// remainders as a [`NaturalPolynomial`], taking the polynomial by value and the modulus by
84 /// reference.
85 ///
86 /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
87 /// both arguments by value for details, including how negative coefficients are handled and how
88 /// reducing can lower the degree.
89 ///
90 /// # Worst-case complexity
91 /// $T(n) = O(n \log n \log\log n)$
92 ///
93 /// $M(n) = O(n \log n)$
94 ///
95 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
96 /// polynomial's coefficients.
97 ///
98 /// # Panics
99 /// Panics if `m` is zero.
100 ///
101 /// # Examples
102 /// ```
103 /// use core::str::FromStr;
104 /// use malachite_base::num::arithmetic::traits::Mod;
105 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
106 /// use malachite_nz::natural::Natural;
107 ///
108 /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
109 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
110 /// assert_eq!(
111 /// p.clone().mod_op(&Natural::from(3u32)).to_string(),
112 /// "x^2+2*x+1"
113 /// );
114 ///
115 /// // Reducing the leading coefficient to zero lowers the degree.
116 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
117 /// assert_eq!(p.clone().mod_op(&Natural::from(3u32)).to_string(), "2");
118 /// ```
119 fn mod_op(self, m: &'a Natural) -> NaturalPolynomial {
120 assert_ne!(*m, 0u32, "division by zero");
121 NaturalPolynomial::from_coefficients_asc(
122 self.coefficients
123 .into_iter()
124 .map(|Integer { sign, abs }| if sign { abs % m } else { abs.neg_mod(m) })
125 .collect::<Vec<_>>(),
126 )
127 }
128}
129
130impl Mod<Natural> for &IntegerPolynomial {
131 type Output = NaturalPolynomial;
132
133 /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
134 /// remainders as a [`NaturalPolynomial`], taking the polynomial by reference and the modulus by
135 /// value.
136 ///
137 /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
138 /// both arguments by value for details, including how negative coefficients are handled and how
139 /// reducing can lower the degree.
140 ///
141 /// # Worst-case complexity
142 /// $T(n) = O(n \log n \log\log n)$
143 ///
144 /// $M(n) = O(n \log n)$
145 ///
146 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
147 /// polynomial's coefficients.
148 ///
149 /// # Panics
150 /// Panics if `m` is zero.
151 ///
152 /// # Examples
153 /// ```
154 /// use core::str::FromStr;
155 /// use malachite_base::num::arithmetic::traits::Mod;
156 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
157 /// use malachite_nz::natural::Natural;
158 ///
159 /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
160 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
161 /// assert_eq!((&p).mod_op(Natural::from(3u32)).to_string(), "x^2+2*x+1");
162 ///
163 /// // Reducing the leading coefficient to zero lowers the degree.
164 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
165 /// assert_eq!((&p).mod_op(Natural::from(3u32)).to_string(), "2");
166 /// ```
167 #[inline]
168 fn mod_op(self, m: Natural) -> NaturalPolynomial {
169 self.mod_op(&m)
170 }
171}
172
173impl<'a> Mod<&'a Natural> for &IntegerPolynomial {
174 type Output = NaturalPolynomial;
175
176 /// Divides every coefficient of an [`IntegerPolynomial`] by a [`Natural`], keeping the
177 /// remainders as a [`NaturalPolynomial`], taking the polynomial by reference and the modulus by
178 /// reference.
179 ///
180 /// See the documentation for the [`Mod`] implementation on [`IntegerPolynomial`] that takes
181 /// both arguments by value for details, including how negative coefficients are handled and how
182 /// reducing can lower the degree.
183 ///
184 /// # Worst-case complexity
185 /// $T(n) = O(n \log n \log\log n)$
186 ///
187 /// $M(n) = O(n \log n)$
188 ///
189 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
190 /// polynomial's coefficients.
191 ///
192 /// # Panics
193 /// Panics if `m` is zero.
194 ///
195 /// # Examples
196 /// ```
197 /// use core::str::FromStr;
198 /// use malachite_base::num::arithmetic::traits::Mod;
199 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
200 /// use malachite_nz::natural::Natural;
201 ///
202 /// // Every coefficient is taken modulo 3, and negative ones become non-negative.
203 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
204 /// assert_eq!((&p).mod_op(&Natural::from(3u32)).to_string(), "x^2+2*x+1");
205 ///
206 /// // Reducing the leading coefficient to zero lowers the degree.
207 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
208 /// assert_eq!((&p).mod_op(&Natural::from(3u32)).to_string(), "2");
209 /// ```
210 fn mod_op(self, m: &'a Natural) -> NaturalPolynomial {
211 assert_ne!(*m, 0u32, "division by zero");
212 // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
213 // coefficient reduces to zero.
214 NaturalPolynomial::from_coefficients_asc(
215 self.coefficients
216 .iter()
217 .map(|c| {
218 if c.sign {
219 &c.abs % m
220 } else {
221 (&c.abs).neg_mod(m)
222 }
223 })
224 .collect::<Vec<_>>(),
225 )
226 }
227}
228
229impl<T: PrimitiveUnsigned + for<'a> ExactFrom<&'a Natural>> Mod<T> for &IntegerPolynomial
230where
231 Natural: From<T>,
232{
233 type Output = UnsignedPolynomial<T>;
234
235 /// Divides every coefficient of an [`IntegerPolynomial`] by a value of an unsigned primitive
236 /// integer type, keeping the remainders as an [`UnsignedPolynomial`] with that coefficient
237 /// type, taking the polynomial by reference.
238 ///
239 /// Each remainder is taken in $[0, m)$, so negative coefficients become non-negative, and every
240 /// remainder fits in `m`'s type. Apart from the result's type, this is the same operation as
241 /// reducing modulo `Natural::from(m)`; see the documentation for the [`Mod`] implementation on
242 /// [`IntegerPolynomial`] that takes both arguments by value for details, including how reducing
243 /// can lower the degree.
244 ///
245 /// The result is reduced modulo $m$, which is to say that
246 /// [`mod_is_reduced`](malachite_base::num::arithmetic::traits::ModIsReduced::mod_is_reduced)
247 /// returns `true` for it.
248 ///
249 /// # Worst-case complexity
250 /// $T(n) = O(n)$
251 ///
252 /// $M(n) = O(m)$
253 ///
254 /// where $T$ is time, $M$ is additional memory, $n$ is the total number of bits in the
255 /// polynomial's coefficients, and $m$ is the number of coefficients.
256 ///
257 /// # Panics
258 /// Panics if `m` is zero.
259 ///
260 /// # Examples
261 /// ```
262 /// use core::str::FromStr;
263 /// use malachite_base::num::arithmetic::traits::Mod;
264 /// use malachite_base::unsigned_polynomial::UnsignedPolynomial;
265 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
266 ///
267 /// let p = IntegerPolynomial::from_str("-1000000000001*x^2+2000000000003*x-5").unwrap();
268 /// let q: UnsignedPolynomial<u8> = (&p).mod_op(7u8);
269 /// assert_eq!(q.to_string(), "5*x^2+5*x+2");
270 ///
271 /// // Reducing the leading coefficient to zero lowers the degree.
272 /// let p = IntegerPolynomial::from_str("-1024*x^2-3").unwrap();
273 /// assert_eq!((&p).mod_op(4u64).to_string(), "1");
274 /// ```
275 fn mod_op(self, m: T) -> UnsignedPolynomial<T> {
276 assert_ne!(m, T::ZERO, "division by zero");
277 let m = Natural::from(m);
278 // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
279 // coefficient reduces to zero.
280 UnsignedPolynomial::from_coefficients_asc(
281 self.coefficients
282 .iter()
283 .map(|c| {
284 T::exact_from(&if c.sign {
285 &c.abs % &m
286 } else {
287 (&c.abs).neg_mod(&m)
288 })
289 })
290 .collect::<Vec<_>>(),
291 )
292 }
293}
294
295impl<T: PrimitiveUnsigned + for<'a> ExactFrom<&'a Natural>> Mod<T> for IntegerPolynomial
296where
297 Natural: From<T>,
298{
299 type Output = UnsignedPolynomial<T>;
300
301 /// Divides every coefficient of an [`IntegerPolynomial`] by a value of an unsigned primitive
302 /// integer type, keeping the remainders as an [`UnsignedPolynomial`] with that coefficient
303 /// type, taking the polynomial by value.
304 ///
305 /// Taking the polynomial by value saves nothing, since the remainders go into new storage
306 /// either way. See the documentation for the [`Mod`] implementation that takes the polynomial
307 /// by reference for details.
308 ///
309 /// # Worst-case complexity
310 /// $T(n) = O(n)$
311 ///
312 /// $M(n) = O(m)$
313 ///
314 /// where $T$ is time, $M$ is additional memory, $n$ is the total number of bits in the
315 /// polynomial's coefficients, and $m$ is the number of coefficients.
316 ///
317 /// # Panics
318 /// Panics if `m` is zero.
319 ///
320 /// # Examples
321 /// ```
322 /// use core::str::FromStr;
323 /// use malachite_base::num::arithmetic::traits::Mod;
324 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
325 ///
326 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
327 /// assert_eq!(p.mod_op(3u32).to_string(), "x^2+2*x+1");
328 /// ```
329 #[inline]
330 fn mod_op(self, m: T) -> UnsignedPolynomial<T> {
331 (&self).mod_op(m)
332 }
333}
334
335impl Rem<Integer> for IntegerPolynomial {
336 type Output = Self;
337
338 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
339 /// remainders, taking the polynomial by value and the modulus by value.
340 ///
341 /// Each remainder has the sign of its coefficient and a smaller absolute value than $m$, as
342 /// with [`Rem`] for [`Integer`]s, so the sign of $m$ makes no difference. This is the remainder
343 /// of truncating division: with the coefficient-wise quotient $q_i = \operatorname{
344 /// sgn}(p_im)\lfloor |p_i/m| \rfloor$, $p = mq + r$ holds exactly. For a remainder that is
345 /// always non-negative, and a [`NaturalPolynomial`] result, use [`Mod`].
346 ///
347 /// Reducing can lower the degree, and can even give the zero polynomial: a leading coefficient
348 /// that is a multiple of $m$ becomes zero, and a polynomial does not hold trailing zero
349 /// coefficients. So $-6x^2 + 3x - 1$ modulo $3$ is the constant $-1$.
350 ///
351 /// $$
352 /// f(p, m) = r, \quad \text{where} \quad r_i = p_i - m \operatorname{sgn}(p_im)
353 /// \left \lfloor \left | \frac{p_i}{m} \right | \right \rfloor.
354 /// $$
355 ///
356 /// # Worst-case complexity
357 /// $T(n) = O(n \log n \log\log n)$
358 ///
359 /// $M(n) = O(n \log n)$
360 ///
361 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
362 /// polynomial's coefficients.
363 ///
364 /// # Panics
365 /// Panics if `m` is zero.
366 ///
367 /// # Examples
368 /// ```
369 /// use core::str::FromStr;
370 /// use malachite_nz::integer::Integer;
371 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
372 ///
373 /// // Every coefficient is taken modulo 3, keeping its sign.
374 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
375 /// assert_eq!((p.clone() % Integer::from(3)).to_string(), "x^2-x-2");
376 ///
377 /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
378 /// // lowers the degree.
379 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
380 /// assert_eq!((p % Integer::from(-3)).to_string(), "-1");
381 /// ```
382 #[inline]
383 fn rem(mut self, m: Integer) -> Self {
384 self %= m;
385 self
386 }
387}
388
389impl<'a> Rem<&'a Integer> for IntegerPolynomial {
390 type Output = Self;
391
392 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
393 /// remainders, taking the polynomial by value and the modulus by reference.
394 ///
395 /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
396 /// both arguments by value for details, including the signs of the remainders and how reducing
397 /// can lower the degree.
398 ///
399 /// # Worst-case complexity
400 /// $T(n) = O(n \log n \log\log n)$
401 ///
402 /// $M(n) = O(n \log n)$
403 ///
404 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
405 /// polynomial's coefficients.
406 ///
407 /// # Panics
408 /// Panics if `m` is zero.
409 ///
410 /// # Examples
411 /// ```
412 /// use core::str::FromStr;
413 /// use malachite_nz::integer::Integer;
414 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
415 ///
416 /// // Every coefficient is taken modulo 3, keeping its sign.
417 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
418 /// assert_eq!((p.clone() % &Integer::from(3)).to_string(), "x^2-x-2");
419 ///
420 /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
421 /// // lowers the degree.
422 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
423 /// assert_eq!((p % &Integer::from(-3)).to_string(), "-1");
424 /// ```
425 #[inline]
426 fn rem(mut self, m: &'a Integer) -> Self {
427 self %= m;
428 self
429 }
430}
431
432impl Rem<Integer> for &IntegerPolynomial {
433 type Output = IntegerPolynomial;
434
435 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
436 /// remainders, taking the polynomial by reference and the modulus by value.
437 ///
438 /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
439 /// both arguments by value for details, including the signs of the remainders and how reducing
440 /// can lower the degree.
441 ///
442 /// # Worst-case complexity
443 /// $T(n) = O(n \log n \log\log n)$
444 ///
445 /// $M(n) = O(n \log n)$
446 ///
447 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
448 /// polynomial's coefficients.
449 ///
450 /// # Panics
451 /// Panics if `m` is zero.
452 ///
453 /// # Examples
454 /// ```
455 /// use core::str::FromStr;
456 /// use malachite_nz::integer::Integer;
457 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
458 ///
459 /// // Every coefficient is taken modulo 3, keeping its sign.
460 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
461 /// assert_eq!((&p % Integer::from(3)).to_string(), "x^2-x-2");
462 ///
463 /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
464 /// // lowers the degree.
465 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
466 /// assert_eq!((&p % Integer::from(-3)).to_string(), "-1");
467 /// // The polynomial is left alone.
468 /// assert_eq!(p.to_string(), "-6*x^2+3*x-1");
469 /// ```
470 #[inline]
471 fn rem(self, m: Integer) -> IntegerPolynomial {
472 self % &m
473 }
474}
475
476impl<'a> Rem<&'a Integer> for &IntegerPolynomial {
477 type Output = IntegerPolynomial;
478
479 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], keeping the
480 /// remainders, taking the polynomial by reference and the modulus by reference.
481 ///
482 /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
483 /// both arguments by value for details, including the signs of the remainders and how reducing
484 /// can lower the degree.
485 ///
486 /// # Worst-case complexity
487 /// $T(n) = O(n \log n \log\log n)$
488 ///
489 /// $M(n) = O(n \log n)$
490 ///
491 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
492 /// polynomial's coefficients.
493 ///
494 /// # Panics
495 /// Panics if `m` is zero.
496 ///
497 /// # Examples
498 /// ```
499 /// use core::str::FromStr;
500 /// use malachite_nz::integer::Integer;
501 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
502 ///
503 /// // Every coefficient is taken modulo 3, keeping its sign.
504 /// let p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
505 /// assert_eq!((&p % &Integer::from(3)).to_string(), "x^2-x-2");
506 ///
507 /// // The sign of the modulus makes no difference, and reducing the leading coefficient to zero
508 /// // lowers the degree.
509 /// let p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
510 /// assert_eq!((&p % &Integer::from(-3)).to_string(), "-1");
511 /// // The polynomial is left alone.
512 /// assert_eq!(p.to_string(), "-6*x^2+3*x-1");
513 /// ```
514 fn rem(self, m: &'a Integer) -> IntegerPolynomial {
515 assert_ne!(*m, 0u32, "division by zero");
516 // `from_coefficients_asc` trims, which is what makes the degree fall when the leading
517 // coefficient reduces to zero.
518 IntegerPolynomial::from_coefficients_asc(
519 self.coefficients.iter().map(|c| c % m).collect::<Vec<_>>(),
520 )
521 }
522}
523
524impl RemAssign<Integer> for IntegerPolynomial {
525 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], replacing the
526 /// polynomial by the one whose coefficients are the remainders, taking the modulus by value.
527 ///
528 /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
529 /// both arguments by value for details, including the signs of the remainders and how reducing
530 /// can lower the degree.
531 ///
532 /// # Worst-case complexity
533 /// $T(n) = O(n \log n \log\log n)$
534 ///
535 /// $M(n) = O(n \log n)$
536 ///
537 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
538 /// polynomial's coefficients.
539 ///
540 /// # Panics
541 /// Panics if `m` is zero.
542 ///
543 /// # Examples
544 /// ```
545 /// use core::str::FromStr;
546 /// use malachite_nz::integer::Integer;
547 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
548 ///
549 /// let mut p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
550 /// p %= Integer::from(3);
551 /// assert_eq!(p.to_string(), "x^2-x-2");
552 ///
553 /// let mut p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
554 /// p %= Integer::from(-3);
555 /// assert_eq!(p.to_string(), "-1");
556 /// ```
557 #[inline]
558 fn rem_assign(&mut self, m: Integer) {
559 *self %= &m;
560 }
561}
562
563impl<'a> RemAssign<&'a Integer> for IntegerPolynomial {
564 /// Divides every coefficient of an [`IntegerPolynomial`] by an [`Integer`], replacing the
565 /// polynomial by the one whose coefficients are the remainders, taking the modulus by
566 /// reference.
567 ///
568 /// See the documentation for the [`Rem`] implementation on [`IntegerPolynomial`] that takes
569 /// both arguments by value for details, including the signs of the remainders and how reducing
570 /// can lower the degree.
571 ///
572 /// # Worst-case complexity
573 /// $T(n) = O(n \log n \log\log n)$
574 ///
575 /// $M(n) = O(n \log n)$
576 ///
577 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits in the
578 /// polynomial's coefficients.
579 ///
580 /// # Panics
581 /// Panics if `m` is zero.
582 ///
583 /// # Examples
584 /// ```
585 /// use core::str::FromStr;
586 /// use malachite_nz::integer::Integer;
587 /// use malachite_nz::integer_polynomial::IntegerPolynomial;
588 ///
589 /// let mut p = IntegerPolynomial::from_str("x^2-4*x-5").unwrap();
590 /// p %= &Integer::from(3);
591 /// assert_eq!(p.to_string(), "x^2-x-2");
592 ///
593 /// let mut p = IntegerPolynomial::from_str("-6*x^2+3*x-1").unwrap();
594 /// p %= &Integer::from(-3);
595 /// assert_eq!(p.to_string(), "-1");
596 /// ```
597 fn rem_assign(&mut self, m: &'a Integer) {
598 assert_ne!(*m, 0u32, "division by zero");
599 for c in &mut self.coefficients {
600 *c %= m;
601 }
602 self.trim();
603 }
604}