malachite_nz/gaussian_integer/arithmetic/height.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 crate::natural::Natural;
11use core::cmp::max;
12use malachite_base::num::arithmetic::traits::{Height, HeightRef, UnsignedAbs};
13use malachite_base::num::logic::traits::SignificantBits;
14
15impl Height for GaussianInteger {
16 type Output = Natural;
17
18 /// Returns the height of a [`GaussianInteger`]: the larger of the absolute values of its real
19 /// and imaginary parts, taking the [`GaussianInteger`] by reference and cloning.
20 ///
21 /// $$
22 /// f(a + bi) = H(a + bi) = \max(|a|, |b|).
23 /// $$
24 ///
25 /// # Worst-case complexity
26 /// $T(n) = O(n)$
27 ///
28 /// $M(n) = O(n)$
29 ///
30 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
31 ///
32 /// # Examples
33 /// ```
34 /// use core::str::FromStr;
35 /// use malachite_base::num::arithmetic::traits::Height;
36 /// use malachite_nz::gaussian_integer::GaussianInteger;
37 ///
38 /// assert_eq!(GaussianInteger::from_str("3-5i").unwrap().to_height(), 5);
39 /// assert_eq!(GaussianInteger::from_str("-7").unwrap().to_height(), 7);
40 /// assert_eq!(GaussianInteger::from_str("0").unwrap().to_height(), 0);
41 /// ```
42 #[inline]
43 fn to_height(&self) -> Natural {
44 self.height_ref().clone()
45 }
46
47 /// Returns the height of a [`GaussianInteger`]: the larger of the absolute values of its real
48 /// and imaginary parts, taking the [`GaussianInteger`] by value.
49 ///
50 /// The larger part is moved out rather than cloned.
51 ///
52 /// # Worst-case complexity
53 /// $T(n) = O(n)$
54 ///
55 /// $M(n) = O(1)$
56 ///
57 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
58 ///
59 /// # Examples
60 /// ```
61 /// use core::str::FromStr;
62 /// use malachite_base::num::arithmetic::traits::Height;
63 /// use malachite_nz::gaussian_integer::GaussianInteger;
64 ///
65 /// assert_eq!(GaussianInteger::from_str("3-5i").unwrap().into_height(), 5);
66 /// assert_eq!(GaussianInteger::from_str("0").unwrap().into_height(), 0);
67 /// ```
68 #[inline]
69 fn into_height(self) -> Natural {
70 max(self.real.unsigned_abs(), self.imaginary.unsigned_abs())
71 }
72
73 /// Returns the number of significant bits of the height of a [`GaussianInteger`].
74 ///
75 /// Since bit length is monotone, this is the larger of the two parts' bit lengths, without
76 /// materializing the height.
77 ///
78 /// # Worst-case complexity
79 /// Constant time and additional memory.
80 ///
81 /// # Examples
82 /// ```
83 /// use core::str::FromStr;
84 /// use malachite_base::num::arithmetic::traits::Height;
85 /// use malachite_nz::gaussian_integer::GaussianInteger;
86 ///
87 /// assert_eq!(
88 /// GaussianInteger::from_str("3-5i")
89 /// .unwrap()
90 /// .height_significant_bits(),
91 /// 3
92 /// );
93 /// assert_eq!(
94 /// GaussianInteger::from_str("0")
95 /// .unwrap()
96 /// .height_significant_bits(),
97 /// 0
98 /// );
99 /// ```
100 #[inline]
101 fn height_significant_bits(&self) -> u64 {
102 max(
103 self.real.significant_bits(),
104 self.imaginary.significant_bits(),
105 )
106 }
107}
108
109impl HeightRef for GaussianInteger {
110 /// Returns a reference to the height of a [`GaussianInteger`]: the larger of the absolute
111 /// values of its real and imaginary parts.
112 ///
113 /// An [`Integer`](crate::integer::Integer) holds its magnitude as a [`Natural`], so the height
114 /// is already there to be lent and nothing needs to be built.
115 ///
116 /// # Worst-case complexity
117 /// $T(n) = O(n)$
118 ///
119 /// $M(n) = O(1)$
120 ///
121 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
122 ///
123 /// # Examples
124 /// ```
125 /// use core::str::FromStr;
126 /// use malachite_base::num::arithmetic::traits::HeightRef;
127 /// use malachite_nz::gaussian_integer::GaussianInteger;
128 ///
129 /// assert_eq!(*GaussianInteger::from_str("3-5i").unwrap().height_ref(), 5);
130 /// assert_eq!(*GaussianInteger::from_str("0").unwrap().height_ref(), 0);
131 /// ```
132 #[inline]
133 fn height_ref(&self) -> &Natural {
134 max(
135 self.real.unsigned_abs_ref(),
136 self.imaginary.unsigned_abs_ref(),
137 )
138 }
139}