Skip to main content

malachite_nz/gaussian_integer/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::gaussian_integer::GaussianInteger;
10use malachite_base::num::arithmetic::traits::{
11    CanonicalUnitIPow, CanonicalizeUnit, CanonicalizeUnitAssign, MulIPowAssign,
12};
13
14impl CanonicalizeUnit for GaussianInteger {
15    type Output = Self;
16
17    /// Brings a [`GaussianInteger`] into canonical unit form, taking it by value.
18    ///
19    /// The result is the associate $x i^k$ whose argument lies in $(-\pi/4, \pi/4]$, where $k$ is
20    /// given by
21    /// [`canonical_unit_i_pow`](malachite_base::num::arithmetic::traits::CanonicalUnitIPow); zero
22    /// is its own canonical form.
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 the maximum number of significant
30    /// bits of the real and imaginary parts.
31    ///
32    /// # Examples
33    /// ```
34    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
35    /// use malachite_nz::gaussian_integer::GaussianInteger;
36    /// use std::str::FromStr;
37    ///
38    /// assert_eq!(
39    ///     GaussianInteger::from_str("-1+2i")
40    ///         .unwrap()
41    ///         .canonicalize_unit()
42    ///         .to_string(),
43    ///     "2+i"
44    /// );
45    /// assert_eq!(
46    ///     GaussianInteger::from_str("1-i")
47    ///         .unwrap()
48    ///         .canonicalize_unit()
49    ///         .to_string(),
50    ///     "1+i"
51    /// );
52    /// assert_eq!(
53    ///     GaussianInteger::from_str("-3")
54    ///         .unwrap()
55    ///         .canonicalize_unit()
56    ///         .to_string(),
57    ///     "3"
58    /// );
59    /// ```
60    #[inline]
61    fn canonicalize_unit(mut self) -> Self {
62        self.canonicalize_unit_assign();
63        self
64    }
65}
66
67impl CanonicalizeUnit for &GaussianInteger {
68    type Output = GaussianInteger;
69
70    /// Brings a [`GaussianInteger`] into canonical unit form, taking it by reference.
71    ///
72    /// The result is the associate $x i^k$ whose argument lies in $(-\pi/4, \pi/4]$, where $k$ is
73    /// given by
74    /// [`canonical_unit_i_pow`](malachite_base::num::arithmetic::traits::CanonicalUnitIPow); zero
75    /// is its own canonical form.
76    ///
77    /// # Worst-case complexity
78    /// $T(n) = O(n)$
79    ///
80    /// $M(n) = O(n)$
81    ///
82    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
83    /// bits of the real and imaginary parts.
84    ///
85    /// # Examples
86    /// ```
87    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnit;
88    /// use malachite_nz::gaussian_integer::GaussianInteger;
89    /// use std::str::FromStr;
90    ///
91    /// let x = GaussianInteger::from_str("-1+2i").unwrap();
92    /// assert_eq!((&x).canonicalize_unit().to_string(), "2+i");
93    /// ```
94    #[inline]
95    fn canonicalize_unit(self) -> GaussianInteger {
96        self.clone().canonicalize_unit()
97    }
98}
99
100impl CanonicalizeUnitAssign for GaussianInteger {
101    /// Brings a [`GaussianInteger`] into canonical unit form in place.
102    ///
103    /// The result is the associate $x i^k$ whose argument lies in $(-\pi/4, \pi/4]$, where $k$ is
104    /// given by
105    /// [`canonical_unit_i_pow`](malachite_base::num::arithmetic::traits::CanonicalUnitIPow); zero
106    /// is its own canonical form.
107    ///
108    /// # Worst-case complexity
109    /// $T(n) = O(n)$
110    ///
111    /// $M(n) = O(1)$
112    ///
113    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
114    /// bits of the real and imaginary parts.
115    ///
116    /// # Examples
117    /// ```
118    /// use malachite_base::num::arithmetic::traits::CanonicalizeUnitAssign;
119    /// use malachite_nz::gaussian_integer::GaussianInteger;
120    /// use std::str::FromStr;
121    ///
122    /// let mut x = GaussianInteger::from_str("-1+2i").unwrap();
123    /// x.canonicalize_unit_assign();
124    /// assert_eq!(x.to_string(), "2+i");
125    /// ```
126    fn canonicalize_unit_assign(&mut self) {
127        let k = self.canonical_unit_i_pow();
128        self.mul_i_pow_assign(k);
129    }
130}