Skip to main content

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