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}