malachite_nz/integer_vector/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::integer::Integer;
10use crate::integer_vector::IntegerVector;
11use crate::integer_vector::arithmetic::max_bits::vec_max_bits;
12use crate::natural::Natural;
13use crate::natural_vector::ZERO;
14use malachite_base::num::arithmetic::traits::{Height, HeightRef, UnsignedAbs};
15use malachite_base::num::basic::traits::Zero;
16
17impl Height for IntegerVector {
18 type Output = Natural;
19
20 /// Returns the height of an [`IntegerVector`]: the largest of the absolute values of its
21 /// elements, taking the vector by reference and cloning.
22 ///
23 /// The 0-dimensional vector has no elements, and its height is 0.
24 ///
25 /// $$
26 /// f(v) = H(v) = \max_i |v_i|.
27 /// $$
28 ///
29 /// # Worst-case complexity
30 /// $T(n) = O(n)$
31 ///
32 /// $M(n) = O(m)$
33 ///
34 /// where $T$ is time, $M$ is additional memory, $n$ is the total number of bits of the
35 /// elements, and $m$ is the number of bits of the height.
36 ///
37 /// # Examples
38 /// ```
39 /// use core::str::FromStr;
40 /// use malachite_base::num::arithmetic::traits::Height;
41 /// use malachite_nz::integer_vector::IntegerVector;
42 ///
43 /// assert_eq!(
44 /// IntegerVector::from_str("(1, -3, 2)").unwrap().to_height(),
45 /// 3
46 /// );
47 /// assert_eq!(IntegerVector::from_str("()").unwrap().to_height(), 0);
48 /// ```
49 ///
50 /// This is equivalent to `_fmpz_vec_height` from `fmpz_vec/height.c`, FLINT 3.6.0.
51 #[inline]
52 fn to_height(&self) -> Natural {
53 self.height_ref().clone()
54 }
55
56 /// Returns the height of an [`IntegerVector`]: the largest of the absolute values of its
57 /// elements, taking the vector by value.
58 ///
59 /// The element of largest height, or the part of it that is the height, is moved out of the
60 /// vector rather than cloned.
61 ///
62 /// # Worst-case complexity
63 /// $T(n) = O(n)$
64 ///
65 /// $M(n) = O(1)$
66 ///
67 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
68 /// elements.
69 ///
70 /// # Examples
71 /// ```
72 /// use core::str::FromStr;
73 /// use malachite_base::num::arithmetic::traits::Height;
74 /// use malachite_nz::integer_vector::IntegerVector;
75 ///
76 /// assert_eq!(
77 /// IntegerVector::from_str("(1, -3, 2)").unwrap().into_height(),
78 /// 3
79 /// );
80 /// assert_eq!(IntegerVector::from_str("()").unwrap().into_height(), 0);
81 /// ```
82 #[inline]
83 fn into_height(self) -> Natural {
84 self.elements
85 .into_iter()
86 .map(Integer::unsigned_abs)
87 .max()
88 .unwrap_or(Natural::ZERO)
89 }
90
91 /// Returns the number of significant bits of the height of an [`IntegerVector`].
92 ///
93 /// Since bit length is monotone, this is the largest of the elements' heights' bit lengths, and
94 /// 0 for the 0-dimensional vector, without materializing the height.
95 ///
96 /// # Worst-case complexity
97 /// $T(n) = O(n)$
98 ///
99 /// $M(n) = O(1)$
100 ///
101 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
102 /// elements.
103 ///
104 /// # Examples
105 /// ```
106 /// use core::str::FromStr;
107 /// use malachite_base::num::arithmetic::traits::Height;
108 /// use malachite_nz::integer_vector::IntegerVector;
109 ///
110 /// assert_eq!(
111 /// IntegerVector::from_str("(1, -3, 2)")
112 /// .unwrap()
113 /// .height_significant_bits(),
114 /// 2
115 /// );
116 /// assert_eq!(
117 /// IntegerVector::from_str("()")
118 /// .unwrap()
119 /// .height_significant_bits(),
120 /// 0
121 /// );
122 /// ```
123 ///
124 /// This is the absolute value of `_fmpz_vec_max_bits` from `fmpz_vec/max_bits.c`, FLINT 3.6.0.
125 #[inline]
126 fn height_significant_bits(&self) -> u64 {
127 vec_max_bits(&self.elements).0
128 }
129}
130
131impl HeightRef for IntegerVector {
132 /// Returns a reference to the height of an [`IntegerVector`]: the largest of the absolute
133 /// values of its elements.
134 ///
135 /// The height is one of the magnitudes the vector already holds, so it is lent rather than
136 /// built. For the 0-dimensional vector, a reference to 0 is returned.
137 ///
138 /// # Worst-case complexity
139 /// $T(n) = O(n)$
140 ///
141 /// $M(n) = O(1)$
142 ///
143 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
144 /// elements.
145 ///
146 /// # Examples
147 /// ```
148 /// use core::str::FromStr;
149 /// use malachite_base::num::arithmetic::traits::HeightRef;
150 /// use malachite_nz::integer_vector::IntegerVector;
151 ///
152 /// assert_eq!(
153 /// *IntegerVector::from_str("(1, -3, 2)").unwrap().height_ref(),
154 /// 3
155 /// );
156 /// assert_eq!(*IntegerVector::from_str("()").unwrap().height_ref(), 0);
157 /// ```
158 #[inline]
159 fn height_ref(&self) -> &Natural {
160 self.elements
161 .iter()
162 .map(Integer::unsigned_abs_ref)
163 .max()
164 .unwrap_or(&ZERO)
165 }
166}