Skip to main content

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}