malachite_q/rational_vector/arithmetic/scalar_mul.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;
10use crate::rational_vector::RationalVector;
11use alloc::vec;
12use core::ops::{Mul, MulAssign};
13use malachite_base::num::basic::traits::{One, Zero};
14
15impl Mul<Rational> for RationalVector {
16 type Output = Self;
17
18 /// Multiplies every element of a [`RationalVector`] by a [`Rational`], taking the vector by
19 /// value and the scalar by value.
20 ///
21 /// The product is taken element by element, so the result has the same dimension as the vector.
22 ///
23 /// $$
24 /// f(v, c) = cv = (cv_0, cv_1, \ldots, cv_{n-1}).
25 /// $$
26 ///
27 /// # Worst-case complexity
28 /// $T(n) = O(n \log n \log\log n)$
29 ///
30 /// $M(n) = O(n \log n)$
31 ///
32 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
33 /// elements and of the scalar.
34 ///
35 /// # Examples
36 /// ```
37 /// use core::str::FromStr;
38 /// use malachite_q::Rational;
39 /// use malachite_q::rational_vector::RationalVector;
40 ///
41 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
42 /// let c = Rational::from_signeds(3, 4);
43 /// assert_eq!((v * c).to_string(), "(3/8, -1/2, 9/4)");
44 /// ```
45 #[inline]
46 fn mul(mut self, c: Rational) -> Self {
47 self *= &c;
48 self
49 }
50}
51
52impl Mul<&Rational> for RationalVector {
53 type Output = Self;
54
55 /// Multiplies every element of a [`RationalVector`] by a [`Rational`], taking the vector by
56 /// value and the scalar by reference.
57 ///
58 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
59 /// value for details.
60 ///
61 /// # Worst-case complexity
62 /// $T(n) = O(n \log n \log\log n)$
63 ///
64 /// $M(n) = O(n \log n)$
65 ///
66 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
67 /// elements and of the scalar.
68 ///
69 /// # Examples
70 /// ```
71 /// use core::str::FromStr;
72 /// use malachite_q::Rational;
73 /// use malachite_q::rational_vector::RationalVector;
74 ///
75 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
76 /// let c = Rational::from_signeds(3, 4);
77 /// assert_eq!((v * &c).to_string(), "(3/8, -1/2, 9/4)");
78 /// ```
79 #[inline]
80 fn mul(mut self, c: &Rational) -> Self {
81 self *= c;
82 self
83 }
84}
85
86impl Mul<Rational> for &RationalVector {
87 type Output = RationalVector;
88
89 /// Multiplies every element of a [`RationalVector`] by a [`Rational`], taking the vector by
90 /// reference and the scalar by value.
91 ///
92 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
93 /// value for details.
94 ///
95 /// # Worst-case complexity
96 /// $T(n) = O(n \log n \log\log n)$
97 ///
98 /// $M(n) = O(n \log n)$
99 ///
100 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
101 /// elements and of the scalar.
102 ///
103 /// # Examples
104 /// ```
105 /// use core::str::FromStr;
106 /// use malachite_q::Rational;
107 /// use malachite_q::rational_vector::RationalVector;
108 ///
109 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
110 /// let c = Rational::from_signeds(3, 4);
111 /// assert_eq!((&v * c).to_string(), "(3/8, -1/2, 9/4)");
112 /// ```
113 #[inline]
114 fn mul(self, c: Rational) -> RationalVector {
115 self * &c
116 }
117}
118
119impl Mul<&Rational> for &RationalVector {
120 type Output = RationalVector;
121
122 /// Multiplies every element of a [`RationalVector`] by a [`Rational`], taking the vector by
123 /// reference and the scalar by reference.
124 ///
125 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
126 /// value for details.
127 ///
128 /// # Worst-case complexity
129 /// $T(n) = O(n \log n \log\log n)$
130 ///
131 /// $M(n) = O(n \log n)$
132 ///
133 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
134 /// elements and of the scalar.
135 ///
136 /// # Examples
137 /// ```
138 /// use core::str::FromStr;
139 /// use malachite_q::Rational;
140 /// use malachite_q::rational_vector::RationalVector;
141 ///
142 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
143 /// let c = Rational::from_signeds(3, 4);
144 /// assert_eq!((&v * &c).to_string(), "(3/8, -1/2, 9/4)");
145 /// ```
146 fn mul(self, c: &Rational) -> RationalVector {
147 RationalVector {
148 elements: match *c {
149 Rational::ZERO => vec![Rational::ZERO; self.elements.len()],
150 Rational::ONE => self.elements.clone(),
151 // Each product is reduced by the cross-cancellation of `Rational`'s `Mul`.
152 _ => self.elements.iter().map(|x| x * c).collect(),
153 },
154 }
155 }
156}
157
158impl Mul<RationalVector> for Rational {
159 type Output = RationalVector;
160
161 /// Multiplies a [`Rational`] by every element of a [`RationalVector`], taking the scalar by
162 /// value and the vector by value.
163 ///
164 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
165 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
166 ///
167 /// # Worst-case complexity
168 /// $T(n) = O(n \log n \log\log n)$
169 ///
170 /// $M(n) = O(n \log n)$
171 ///
172 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
173 /// elements and of the scalar.
174 ///
175 /// # Examples
176 /// ```
177 /// use core::str::FromStr;
178 /// use malachite_q::Rational;
179 /// use malachite_q::rational_vector::RationalVector;
180 ///
181 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
182 /// let c = Rational::from_signeds(3, 4);
183 /// assert_eq!((c * v).to_string(), "(3/8, -1/2, 9/4)");
184 /// ```
185 #[inline]
186 fn mul(self, v: RationalVector) -> RationalVector {
187 v * self
188 }
189}
190
191impl Mul<&RationalVector> for Rational {
192 type Output = RationalVector;
193
194 /// Multiplies a [`Rational`] by every element of a [`RationalVector`], taking the scalar by
195 /// value and the vector by reference.
196 ///
197 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
198 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
199 ///
200 /// # Worst-case complexity
201 /// $T(n) = O(n \log n \log\log n)$
202 ///
203 /// $M(n) = O(n \log n)$
204 ///
205 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
206 /// elements and of the scalar.
207 ///
208 /// # Examples
209 /// ```
210 /// use core::str::FromStr;
211 /// use malachite_q::Rational;
212 /// use malachite_q::rational_vector::RationalVector;
213 ///
214 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
215 /// let c = Rational::from_signeds(3, 4);
216 /// assert_eq!((c * &v).to_string(), "(3/8, -1/2, 9/4)");
217 /// ```
218 #[inline]
219 fn mul(self, v: &RationalVector) -> RationalVector {
220 v * self
221 }
222}
223
224impl Mul<RationalVector> for &Rational {
225 type Output = RationalVector;
226
227 /// Multiplies a [`Rational`] by every element of a [`RationalVector`], taking the scalar by
228 /// reference and the vector by value.
229 ///
230 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
231 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
232 ///
233 /// # Worst-case complexity
234 /// $T(n) = O(n \log n \log\log n)$
235 ///
236 /// $M(n) = O(n \log n)$
237 ///
238 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
239 /// elements and of the scalar.
240 ///
241 /// # Examples
242 /// ```
243 /// use core::str::FromStr;
244 /// use malachite_q::Rational;
245 /// use malachite_q::rational_vector::RationalVector;
246 ///
247 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
248 /// let c = Rational::from_signeds(3, 4);
249 /// assert_eq!((&c * v).to_string(), "(3/8, -1/2, 9/4)");
250 /// ```
251 #[inline]
252 fn mul(self, v: RationalVector) -> RationalVector {
253 v * self
254 }
255}
256
257impl Mul<&RationalVector> for &Rational {
258 type Output = RationalVector;
259
260 /// Multiplies a [`Rational`] by every element of a [`RationalVector`], taking the scalar by
261 /// reference and the vector by reference.
262 ///
263 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
264 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
265 ///
266 /// # Worst-case complexity
267 /// $T(n) = O(n \log n \log\log n)$
268 ///
269 /// $M(n) = O(n \log n)$
270 ///
271 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
272 /// elements and of the scalar.
273 ///
274 /// # Examples
275 /// ```
276 /// use core::str::FromStr;
277 /// use malachite_q::Rational;
278 /// use malachite_q::rational_vector::RationalVector;
279 ///
280 /// let v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
281 /// let c = Rational::from_signeds(3, 4);
282 /// assert_eq!((&c * &v).to_string(), "(3/8, -1/2, 9/4)");
283 /// ```
284 #[inline]
285 fn mul(self, v: &RationalVector) -> RationalVector {
286 v * self
287 }
288}
289
290impl MulAssign<Rational> for RationalVector {
291 /// Multiplies every element of a [`RationalVector`] by a [`Rational`] in place, taking the
292 /// scalar by value.
293 ///
294 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
295 /// value for details.
296 ///
297 /// # Worst-case complexity
298 /// $T(n) = O(n \log n \log\log n)$
299 ///
300 /// $M(n) = O(n \log n)$
301 ///
302 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
303 /// elements and of the scalar.
304 ///
305 /// # Examples
306 /// ```
307 /// use core::str::FromStr;
308 /// use malachite_q::Rational;
309 /// use malachite_q::rational_vector::RationalVector;
310 ///
311 /// let mut v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
312 /// v *= Rational::from_signeds(3, 4);
313 /// assert_eq!(v.to_string(), "(3/8, -1/2, 9/4)");
314 /// ```
315 #[inline]
316 fn mul_assign(&mut self, c: Rational) {
317 *self *= &c;
318 }
319}
320
321impl MulAssign<&Rational> for RationalVector {
322 /// Multiplies every element of a [`RationalVector`] by a [`Rational`] in place, taking the
323 /// scalar by reference.
324 ///
325 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
326 /// value for details.
327 ///
328 /// # Worst-case complexity
329 /// $T(n) = O(n \log n \log\log n)$
330 ///
331 /// $M(n) = O(n \log n)$
332 ///
333 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
334 /// elements and of the scalar.
335 ///
336 /// # Examples
337 /// ```
338 /// use core::str::FromStr;
339 /// use malachite_q::Rational;
340 /// use malachite_q::rational_vector::RationalVector;
341 ///
342 /// let mut v = RationalVector::from_str("(1/2, -2/3, 3)").unwrap();
343 /// v *= &Rational::from_signeds(3, 4);
344 /// assert_eq!(v.to_string(), "(3/8, -1/2, 9/4)");
345 /// ```
346 fn mul_assign(&mut self, c: &Rational) {
347 match *c {
348 Rational::ZERO => self.elements.fill(Rational::ZERO),
349 Rational::ONE => {}
350 _ => {
351 for x in &mut self.elements {
352 *x *= c;
353 }
354 }
355 }
356 }
357}