Skip to main content

malachite_nz/integer_vector/arithmetic/
entrywise_abs.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::natural_vector::NaturalVector;
12use malachite_base::num::arithmetic::traits::{
13    Abs, AbsAssign, EntrywiseAbs, EntrywiseAbsAssign, EntrywiseUnsignedAbs, UnsignedAbs,
14};
15
16impl EntrywiseAbs for IntegerVector {
17    type Output = Self;
18
19    /// Replaces every element of an [`IntegerVector`] by its absolute value, taking the vector by
20    /// value.
21    ///
22    /// The dimension is unchanged. This is not [`Abs`], which for a vector would be its Euclidean
23    /// length. For the result as a [`NaturalVector`], use [`EntrywiseUnsignedAbs`].
24    ///
25    /// $$
26    /// f(v) = (|v_0|, |v_1|, \ldots, |v_{n-1}|).
27    /// $$
28    ///
29    /// # Worst-case complexity
30    /// $T(n) = O(n)$
31    ///
32    /// $M(n) = O(1)$
33    ///
34    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
35    /// elements.
36    ///
37    /// # Examples
38    /// ```
39    /// use core::str::FromStr;
40    /// use malachite_base::num::arithmetic::traits::EntrywiseAbs;
41    /// use malachite_nz::integer_vector::IntegerVector;
42    ///
43    /// let v = IntegerVector::from_str("(1, -2, 0, -3)").unwrap();
44    /// assert_eq!(v.clone().entrywise_abs().to_string(), "(1, 2, 0, 3)");
45    /// ```
46    ///
47    /// This is equivalent to `_fmpz_vec_scalar_abs` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
48    #[inline]
49    fn entrywise_abs(mut self) -> Self {
50        self.entrywise_abs_assign();
51        self
52    }
53}
54
55impl EntrywiseAbs for &IntegerVector {
56    type Output = IntegerVector;
57
58    /// Replaces every element of an [`IntegerVector`] by its absolute value, taking the vector by
59    /// reference.
60    ///
61    /// See the documentation for the [`EntrywiseAbs`] implementation on [`IntegerVector`] that
62    /// takes the vector by value for details.
63    ///
64    /// # Worst-case complexity
65    /// $T(n) = O(n)$
66    ///
67    /// $M(n) = O(n)$
68    ///
69    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
70    /// elements.
71    ///
72    /// # Examples
73    /// ```
74    /// use core::str::FromStr;
75    /// use malachite_base::num::arithmetic::traits::EntrywiseAbs;
76    /// use malachite_nz::integer_vector::IntegerVector;
77    ///
78    /// let v = IntegerVector::from_str("(1, -2, 0, -3)").unwrap();
79    /// assert_eq!((&v).entrywise_abs().to_string(), "(1, 2, 0, 3)");
80    /// ```
81    ///
82    /// This is equivalent to `_fmpz_vec_scalar_abs` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
83    fn entrywise_abs(self) -> IntegerVector {
84        IntegerVector {
85            elements: self.elements.iter().map(Abs::abs).collect(),
86        }
87    }
88}
89
90impl EntrywiseAbsAssign for IntegerVector {
91    /// Replaces every element of an [`IntegerVector`] by its absolute value, in place.
92    ///
93    /// See the documentation for the [`EntrywiseAbs`] implementation on [`IntegerVector`] that
94    /// takes the vector by value for details.
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::EntrywiseAbsAssign;
108    /// use malachite_nz::integer_vector::IntegerVector;
109    ///
110    /// let mut v = IntegerVector::from_str("(1, -2, 0, -3)").unwrap();
111    /// v.entrywise_abs_assign();
112    /// assert_eq!(v.to_string(), "(1, 2, 0, 3)");
113    /// ```
114    ///
115    /// This is equivalent to `_fmpz_vec_scalar_abs` from `fmpz_vec/scalar.c`, FLINT 3.6.0, with
116    /// `vec1` equal to `vec2`.
117    fn entrywise_abs_assign(&mut self) {
118        for x in &mut self.elements {
119            x.abs_assign();
120        }
121    }
122}
123
124impl EntrywiseUnsignedAbs for IntegerVector {
125    type Output = NaturalVector;
126
127    /// Replaces every element of an [`IntegerVector`] by its absolute value, returning the result
128    /// as a [`NaturalVector`] and taking the vector by value.
129    ///
130    /// Every absolute value is non-negative, so the result fits in a [`NaturalVector`], as
131    /// [`UnsignedAbs`] gives a [`Natural`](crate::natural::Natural) for a single [`Integer`]. The
132    /// dimension is unchanged.
133    ///
134    /// # Worst-case complexity
135    /// $T(n) = O(n)$
136    ///
137    /// $M(n) = O(1)$
138    ///
139    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
140    /// elements.
141    ///
142    /// # Examples
143    /// ```
144    /// use core::str::FromStr;
145    /// use malachite_base::num::arithmetic::traits::EntrywiseUnsignedAbs;
146    /// use malachite_nz::integer_vector::IntegerVector;
147    ///
148    /// let v = IntegerVector::from_str("(1, -2, 0, -3)").unwrap();
149    /// assert_eq!(
150    ///     v.clone().entrywise_unsigned_abs().to_string(),
151    ///     "(1, 2, 0, 3)"
152    /// );
153    /// ```
154    fn entrywise_unsigned_abs(self) -> NaturalVector {
155        NaturalVector {
156            elements: self
157                .elements
158                .into_iter()
159                .map(Integer::unsigned_abs)
160                .collect(),
161        }
162    }
163}
164
165impl EntrywiseUnsignedAbs for &IntegerVector {
166    type Output = NaturalVector;
167
168    /// Replaces every element of an [`IntegerVector`] by its absolute value, returning the result
169    /// as a [`NaturalVector`] and taking the vector by reference.
170    ///
171    /// See the documentation for the [`EntrywiseUnsignedAbs`] implementation on [`IntegerVector`]
172    /// that takes the vector by value for details.
173    ///
174    /// # Worst-case complexity
175    /// $T(n) = O(n)$
176    ///
177    /// $M(n) = O(n)$
178    ///
179    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
180    /// elements.
181    ///
182    /// # Examples
183    /// ```
184    /// use core::str::FromStr;
185    /// use malachite_base::num::arithmetic::traits::EntrywiseUnsignedAbs;
186    /// use malachite_nz::integer_vector::IntegerVector;
187    ///
188    /// let v = IntegerVector::from_str("(1, -2, 0, -3)").unwrap();
189    /// assert_eq!((&v).entrywise_unsigned_abs().to_string(), "(1, 2, 0, 3)");
190    /// ```
191    fn entrywise_unsigned_abs(self) -> NaturalVector {
192        NaturalVector {
193            elements: self
194                .elements
195                .iter()
196                .map(UnsignedAbs::unsigned_abs)
197                .collect(),
198        }
199    }
200}