malachite_nz/integer_vector/arithmetic/l1_norm.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::sum_max_bits::vec_sum_abs_significant_bits;
12use crate::natural::Natural;
13use malachite_base::num::arithmetic::traits::{L1Norm, UnsignedAbs};
14
15impl L1Norm for IntegerVector {
16 type Output = Natural;
17
18 /// Returns the $\ell^1$ norm of an [`IntegerVector`]: the sum of the absolute values of its
19 /// elements, taking the vector by reference.
20 ///
21 /// The 0-dimensional vector has no elements, and its norm is 0.
22 ///
23 /// $$
24 /// f(v) = \|v\|_1 = \sum_i |v_i|.
25 /// $$
26 ///
27 /// # Worst-case complexity
28 /// $T(n) = O(n)$
29 ///
30 /// $M(n) = O(n)$
31 ///
32 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
33 /// elements.
34 ///
35 /// # Examples
36 /// ```
37 /// use core::str::FromStr;
38 /// use malachite_base::num::arithmetic::traits::L1Norm;
39 /// use malachite_nz::integer_vector::IntegerVector;
40 ///
41 /// assert_eq!(
42 /// IntegerVector::from_str("(1, -5, 2)").unwrap().to_l1_norm(),
43 /// 8
44 /// );
45 /// assert_eq!(IntegerVector::from_str("()").unwrap().to_l1_norm(), 0);
46 /// ```
47 #[inline]
48 fn to_l1_norm(&self) -> Natural {
49 self.elements.iter().map(Integer::unsigned_abs_ref).sum()
50 }
51
52 /// Returns the $\ell^1$ norm of an [`IntegerVector`]: the sum of the absolute values of its
53 /// elements, taking the vector by value.
54 ///
55 /// # Worst-case complexity
56 /// $T(n) = O(n)$
57 ///
58 /// $M(n) = O(n)$
59 ///
60 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
61 /// elements.
62 ///
63 /// # Examples
64 /// ```
65 /// use core::str::FromStr;
66 /// use malachite_base::num::arithmetic::traits::L1Norm;
67 /// use malachite_nz::integer_vector::IntegerVector;
68 ///
69 /// assert_eq!(
70 /// IntegerVector::from_str("(1, -5, 2)")
71 /// .unwrap()
72 /// .into_l1_norm(),
73 /// 8
74 /// );
75 /// assert_eq!(IntegerVector::from_str("()").unwrap().into_l1_norm(), 0);
76 /// ```
77 #[inline]
78 fn into_l1_norm(self) -> Natural {
79 self.elements.into_iter().map(Integer::unsigned_abs).sum()
80 }
81
82 /// Returns the number of significant bits of the $\ell^1$ norm of an [`IntegerVector`].
83 ///
84 /// While every element fits in one limb, the absolute values are added in two limbs, so nothing
85 /// is allocated, as in FLINT's `_fmpz_vec_sum_max_bits`.
86 ///
87 /// # Worst-case complexity
88 /// $T(n) = O(n)$
89 ///
90 /// $M(n) = O(n)$
91 ///
92 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
93 /// elements.
94 ///
95 /// # Examples
96 /// ```
97 /// use core::str::FromStr;
98 /// use malachite_base::num::arithmetic::traits::L1Norm;
99 /// use malachite_nz::integer_vector::IntegerVector;
100 ///
101 /// assert_eq!(
102 /// IntegerVector::from_str("(1, -5, 2)")
103 /// .unwrap()
104 /// .l1_norm_significant_bits(),
105 /// 4
106 /// );
107 /// assert_eq!(
108 /// IntegerVector::from_str("()")
109 /// .unwrap()
110 /// .l1_norm_significant_bits(),
111 /// 0
112 /// );
113 /// ```
114 #[inline]
115 fn l1_norm_significant_bits(&self) -> u64 {
116 vec_sum_abs_significant_bits(&self.elements)
117 }
118}