Skip to main content

malachite_nz/integer_polynomial/arithmetic/
canonicalize_unit.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_polynomial::IntegerPolynomial;
10use malachite_base::num::arithmetic::traits::{
11    CanonicalizeUnit, CanonicalizeUnitAssign, NegAssign,
12};
13use malachite_base::polynomial::Polynomial;
14
15impl CanonicalizeUnit for IntegerPolynomial {
16    type Output = Self;
17
18    /// Brings an [`IntegerPolynomial`] into canonical unit form, taking it by value.
19    ///
20    /// The canonical associate is the one whose leading coefficient is non-negative, so a
21    /// polynomial with a negative leading coefficient is negated and any other is left alone. The
22    /// zero polynomial is its own canonical associate.
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n)$
26    ///
27    /// $M(n) = O(1)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.len()`.
30    ///
31    /// # Examples
32    /// ```
33    /// use core::str::FromStr;
34    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
35    /// use malachite_base::num::basic::traits::Zero;
36    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
37    ///
38    /// assert_eq!(
39    ///     IntegerPolynomial::from_str("-3*x^2+2")
40    ///         .unwrap()
41    ///         .canonicalize_unit()
42    ///         .to_string(),
43    ///     "3*x^2-2"
44    /// );
45    /// assert_eq!(
46    ///     IntegerPolynomial::from_str("3*x^2-2")
47    ///         .unwrap()
48    ///         .canonicalize_unit()
49    ///         .to_string(),
50    ///     "3*x^2-2"
51    /// );
52    /// assert_eq!(
53    ///     IntegerPolynomial::ZERO.canonicalize_unit(),
54    ///     IntegerPolynomial::ZERO
55    /// );
56    /// ```
57    #[inline]
58    fn canonicalize_unit(mut self) -> Self {
59        self.canonicalize_unit_assign();
60        self
61    }
62}
63
64impl CanonicalizeUnit for &IntegerPolynomial {
65    type Output = IntegerPolynomial;
66
67    /// Brings an [`IntegerPolynomial`] into canonical unit form, taking it by reference.
68    ///
69    /// The canonical associate is the one whose leading coefficient is non-negative, so a
70    /// polynomial with a negative leading coefficient is negated and any other is left alone. The
71    /// zero polynomial is its own canonical associate.
72    ///
73    /// # Worst-case complexity
74    /// $T(n) = O(n)$
75    ///
76    /// $M(n) = O(n)$
77    ///
78    /// where $T$ is time, $M$ is additional memory, and $n$ is the total size of the coefficients.
79    ///
80    /// # Examples
81    /// ```
82    /// use core::str::FromStr;
83    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
84    /// use malachite_base::num::basic::traits::Zero;
85    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
86    ///
87    /// assert_eq!(
88    ///     (&IntegerPolynomial::from_str("-3*x^2+2").unwrap())
89    ///         .canonicalize_unit()
90    ///         .to_string(),
91    ///     "3*x^2-2"
92    /// );
93    /// assert_eq!(
94    ///     (&IntegerPolynomial::from_str("3*x^2-2").unwrap())
95    ///         .canonicalize_unit()
96    ///         .to_string(),
97    ///     "3*x^2-2"
98    /// );
99    /// assert_eq!(
100    ///     (&IntegerPolynomial::ZERO).canonicalize_unit(),
101    ///     IntegerPolynomial::ZERO
102    /// );
103    /// ```
104    #[inline]
105    fn canonicalize_unit(self) -> IntegerPolynomial {
106        if *self.leading_coefficient() < 0u32 {
107            -self
108        } else {
109            self.clone()
110        }
111    }
112}
113
114impl CanonicalizeUnitAssign for IntegerPolynomial {
115    /// Brings an [`IntegerPolynomial`] into canonical unit form, in place.
116    ///
117    /// See [`canonicalize_unit`](CanonicalizeUnit::canonicalize_unit).
118    ///
119    /// # Worst-case complexity
120    /// $T(n) = O(n)$
121    ///
122    /// $M(n) = O(1)$
123    ///
124    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.len()`.
125    ///
126    /// # Examples
127    /// ```
128    /// use core::str::FromStr;
129    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnitAssign;
130    /// use malachite_nz::integer_polynomial::IntegerPolynomial;
131    ///
132    /// let mut p = IntegerPolynomial::from_str("-3*x^2+2").unwrap();
133    /// p.canonicalize_unit_assign();
134    /// assert_eq!(p.to_string(), "3*x^2-2");
135    /// ```
136    #[inline]
137    fn canonicalize_unit_assign(&mut self) {
138        if *self.leading_coefficient() < 0u32 {
139            self.neg_assign();
140        }
141    }
142}