malachite_nz/integer_vector/select_coordinates.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_vector::IntegerVector;
10use malachite_base::vector::{
11 SelectCoordinates, SelectCoordinatesAssign, select_elements, select_elements_in_place,
12};
13
14impl SelectCoordinates for IntegerVector {
15 type Output = Self;
16
17 /// Selects coordinates of an [`IntegerVector`] by index, taking the vector by value.
18 ///
19 /// Element $j$ of the result is element `indices[j]` of the original, so the result's dimension
20 /// is the number of indices. The indices may repeat and may appear in any order.
21 ///
22 /// Elements are moved rather than cloned wherever possible: when the indices are strictly
23 /// increasing, nothing is cloned or allocated, and otherwise an element is cloned only once for
24 /// each extra time it is selected.
25 ///
26 /// # Worst-case complexity
27 /// $T(n) = O(n)$
28 ///
29 /// $M(n) = O(n)$
30 ///
31 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()` plus
32 /// `indices.len()`, plus the total size of the elements that are cloned.
33 ///
34 /// # Panics
35 /// Panics if any index is greater than or equal to `self.dimension()`.
36 ///
37 /// # Examples
38 /// ```
39 /// use core::str::FromStr;
40 /// use malachite_base::vector::SelectCoordinates;
41 /// use malachite_nz::integer_vector::IntegerVector;
42 ///
43 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
44 /// assert_eq!(v.clone().select_coordinates(&[2, 0]).to_string(), "(3, 1)");
45 /// assert_eq!(
46 /// v.clone().select_coordinates(&[1, 1, 1]).to_string(),
47 /// "(-2, -2, -2)"
48 /// );
49 /// assert_eq!(v.select_coordinates(&[0, 2]).to_string(), "(1, 3)");
50 /// ```
51 #[inline]
52 fn select_coordinates(mut self, indices: &[u64]) -> Self {
53 self.select_coordinates_assign(indices);
54 self
55 }
56}
57
58impl SelectCoordinates for &IntegerVector {
59 type Output = IntegerVector;
60
61 /// Selects coordinates of an [`IntegerVector`] by index, taking the vector by reference.
62 ///
63 /// Element $j$ of the result is element `indices[j]` of the original, so the result's dimension
64 /// is the number of indices. The indices may repeat and may appear in any order.
65 ///
66 /// The selected elements are cloned.
67 ///
68 /// # Worst-case complexity
69 /// $T(n) = O(n)$
70 ///
71 /// $M(n) = O(n)$
72 ///
73 /// where $T$ is time, $M$ is additional memory, and $n$ is `indices.len()` plus the total size
74 /// of the selected elements.
75 ///
76 /// # Panics
77 /// Panics if any index is greater than or equal to `self.dimension()`.
78 ///
79 /// # Examples
80 /// ```
81 /// use core::str::FromStr;
82 /// use malachite_base::vector::SelectCoordinates;
83 /// use malachite_nz::integer_vector::IntegerVector;
84 ///
85 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
86 /// assert_eq!((&v).select_coordinates(&[2, 0]).to_string(), "(3, 1)");
87 /// assert_eq!(
88 /// (&v).select_coordinates(&[1, 1, 1]).to_string(),
89 /// "(-2, -2, -2)"
90 /// );
91 /// assert_eq!((&v).select_coordinates(&[]).to_string(), "()");
92 /// ```
93 #[inline]
94 fn select_coordinates(self, indices: &[u64]) -> IntegerVector {
95 IntegerVector {
96 elements: select_elements(&self.elements, indices),
97 }
98 }
99}
100
101impl SelectCoordinatesAssign for IntegerVector {
102 /// Selects coordinates of an [`IntegerVector`] by index, in place.
103 ///
104 /// Afterwards, element $j$ of the vector is what element `indices[j]` was before, so its
105 /// dimension is the number of indices. The indices may repeat and may appear in any order.
106 ///
107 /// Elements are moved rather than cloned wherever possible: when the indices are strictly
108 /// increasing, nothing is cloned or allocated, and otherwise an element is cloned only once for
109 /// each extra time it is selected.
110 ///
111 /// # Worst-case complexity
112 /// $T(n) = O(n)$
113 ///
114 /// $M(n) = O(n)$
115 ///
116 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()` plus
117 /// `indices.len()`, plus the total size of the elements that are cloned.
118 ///
119 /// # Panics
120 /// Panics if any index is greater than or equal to `self.dimension()`.
121 ///
122 /// # Examples
123 /// ```
124 /// use core::str::FromStr;
125 /// use malachite_base::vector::SelectCoordinatesAssign;
126 /// use malachite_nz::integer_vector::IntegerVector;
127 ///
128 /// let mut v = IntegerVector::from_str("(1, -2, 3)").unwrap();
129 /// v.select_coordinates_assign(&[2, 0]);
130 /// assert_eq!(v.to_string(), "(3, 1)");
131 /// v.select_coordinates_assign(&[1, 1]);
132 /// assert_eq!(v.to_string(), "(1, 1)");
133 /// ```
134 #[inline]
135 fn select_coordinates_assign(&mut self, indices: &[u64]) {
136 select_elements_in_place(&mut self.elements, indices);
137 }
138}