malachite_nz/integer_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/>.
8use crate::integer::Integer;
9use crate::integer_vector::IntegerVector;
10use crate::natural::Natural;
11use alloc::vec::Vec;
12use core::ops::{Mul, MulAssign};
13use malachite_base::num::arithmetic::traits::NegAssign;
14use malachite_base::num::basic::traits::{One, Zero};
15
16// Multiplies every element of `xs` by `c`, in place.
17//
18// Nothing is trimmed: when `c` is zero, every element becomes zero, and a caller holding the
19// coefficients of a polynomial must trim them.
20//
21// # Worst-case complexity
22// $T(n) = O(n \log n \log\log n)$
23//
24// $M(n) = O(n \log n)$
25//
26// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the elements
27// of `xs` and of `c`.
28//
29// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0, where
30// `poly1 == poly2`.
31#[doc(hidden)]
32pub fn integers_mul_scalar_assign(xs: &mut [Integer], c: &Integer) {
33 match *c {
34 integer_zero!() => xs.fill(Integer::ZERO),
35 integer_one!() => {}
36 integer_negative_one!() => {
37 for x in xs {
38 x.neg_assign();
39 }
40 }
41 _ => {
42 for x in xs {
43 *x *= c;
44 }
45 }
46 }
47}
48
49// Returns a `Vec` holding every element of `xs` multiplied by `c`.
50//
51// Nothing is trimmed: when `c` is zero, every element is zero, and a caller holding the
52// coefficients of a polynomial must trim them.
53//
54// # Worst-case complexity
55// $T(n) = O(n \log n \log\log n)$
56//
57// $M(n) = O(n \log n)$
58//
59// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the elements
60// of `xs` and of `c`.
61//
62// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
63crate_test_fn! {
64#[doc(hidden)]
65integers_mul_scalar(xs: &[Integer], c: &Integer) -> Vec<Integer> {
66 match *c {
67 integer_zero!() => alloc::vec![Integer::ZERO; xs.len()],
68 integer_one!() => xs.to_vec(),
69 integer_negative_one!() => xs.iter().map(|x| -x).collect(),
70 _ => xs.iter().map(|x| x * c).collect(),
71 }
72}
73}
74
75// Sets each element of `out` to the element of `xs` at the same index multiplied by `c`. `xs` must
76// be at least as long as `out`.
77//
78// # Worst-case complexity
79// $T(n) = O(n \log n \log\log n)$
80//
81// $M(n) = O(n \log n)$
82//
83// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the first
84// `out.len()` elements of `xs` and of `c`.
85//
86// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0, where
87// the output is separate from the input.
88crate_test_fn! {
89#[doc(hidden)]
90integers_mul_scalar_to_out(out: &mut [Integer], xs: &[Integer], c: &Integer) {
91 let xs = &xs[..out.len()];
92 match *c {
93 integer_zero!() => out.fill(Integer::ZERO),
94 integer_one!() => out.clone_from_slice(xs),
95 integer_negative_one!() => {
96 for (o, x) in out.iter_mut().zip(xs) {
97 *o = -x;
98 }
99 }
100 _ => {
101 for (o, x) in out.iter_mut().zip(xs) {
102 *o = x * c;
103 }
104 }
105 }
106}}
107
108impl Mul<Integer> for IntegerVector {
109 type Output = Self;
110
111 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
112 /// value and the scalar by value.
113 ///
114 /// The product is taken element by element, so the result has the same dimension as the vector.
115 ///
116 /// $$
117 /// f(v, c) = cv = (cv_0, cv_1, \ldots, cv_{n-1}).
118 /// $$
119 ///
120 /// # Worst-case complexity
121 /// $T(n) = O(n \log n \log\log n)$
122 ///
123 /// $M(n) = O(n \log n)$
124 ///
125 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
126 /// elements and of the scalar.
127 ///
128 /// # Examples
129 /// ```
130 /// use core::str::FromStr;
131 /// use malachite_nz::integer::Integer;
132 /// use malachite_nz::integer_vector::IntegerVector;
133 ///
134 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
135 /// let c = Integer::from(-3);
136 /// assert_eq!((v * c).to_string(), "(-3, 6, -9)");
137 /// ```
138 ///
139 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
140 #[inline]
141 fn mul(mut self, c: Integer) -> Self {
142 self *= &c;
143 self
144 }
145}
146
147impl Mul<&Integer> for IntegerVector {
148 type Output = Self;
149
150 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
151 /// value and the scalar by reference.
152 ///
153 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
154 /// value for details.
155 ///
156 /// # Worst-case complexity
157 /// $T(n) = O(n \log n \log\log n)$
158 ///
159 /// $M(n) = O(n \log n)$
160 ///
161 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
162 /// elements and of the scalar.
163 ///
164 /// # Examples
165 /// ```
166 /// use core::str::FromStr;
167 /// use malachite_nz::integer::Integer;
168 /// use malachite_nz::integer_vector::IntegerVector;
169 ///
170 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
171 /// let c = Integer::from(-3);
172 /// assert_eq!((v * &c).to_string(), "(-3, 6, -9)");
173 /// ```
174 ///
175 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
176 #[inline]
177 fn mul(mut self, c: &Integer) -> Self {
178 self *= c;
179 self
180 }
181}
182
183impl Mul<Integer> for &IntegerVector {
184 type Output = IntegerVector;
185
186 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
187 /// reference and the scalar by value.
188 ///
189 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
190 /// value for details.
191 ///
192 /// # Worst-case complexity
193 /// $T(n) = O(n \log n \log\log n)$
194 ///
195 /// $M(n) = O(n \log n)$
196 ///
197 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
198 /// elements and of the scalar.
199 ///
200 /// # Examples
201 /// ```
202 /// use core::str::FromStr;
203 /// use malachite_nz::integer::Integer;
204 /// use malachite_nz::integer_vector::IntegerVector;
205 ///
206 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
207 /// let c = Integer::from(-3);
208 /// assert_eq!((&v * c).to_string(), "(-3, 6, -9)");
209 /// ```
210 ///
211 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
212 #[inline]
213 fn mul(self, c: Integer) -> IntegerVector {
214 self * &c
215 }
216}
217
218impl Mul<&Integer> for &IntegerVector {
219 type Output = IntegerVector;
220
221 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`], taking the vector by
222 /// reference and the scalar by reference.
223 ///
224 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
225 /// value for details.
226 ///
227 /// # Worst-case complexity
228 /// $T(n) = O(n \log n \log\log n)$
229 ///
230 /// $M(n) = O(n \log n)$
231 ///
232 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
233 /// elements and of the scalar.
234 ///
235 /// # Examples
236 /// ```
237 /// use core::str::FromStr;
238 /// use malachite_nz::integer::Integer;
239 /// use malachite_nz::integer_vector::IntegerVector;
240 ///
241 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
242 /// let c = Integer::from(-3);
243 /// assert_eq!((&v * &c).to_string(), "(-3, 6, -9)");
244 /// ```
245 ///
246 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
247 fn mul(self, c: &Integer) -> IntegerVector {
248 IntegerVector {
249 elements: integers_mul_scalar(&self.elements, c),
250 }
251 }
252}
253
254impl Mul<IntegerVector> for Integer {
255 type Output = IntegerVector;
256
257 /// Multiplies an [`Integer`] by every element of an [`IntegerVector`], taking the scalar by
258 /// value and the vector by value.
259 ///
260 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
261 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
262 ///
263 /// # Worst-case complexity
264 /// $T(n) = O(n \log n \log\log n)$
265 ///
266 /// $M(n) = O(n \log n)$
267 ///
268 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
269 /// elements and of the scalar.
270 ///
271 /// # Examples
272 /// ```
273 /// use core::str::FromStr;
274 /// use malachite_nz::integer::Integer;
275 /// use malachite_nz::integer_vector::IntegerVector;
276 ///
277 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
278 /// let c = Integer::from(-3);
279 /// assert_eq!((c * v).to_string(), "(-3, 6, -9)");
280 /// ```
281 ///
282 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
283 #[inline]
284 fn mul(self, v: IntegerVector) -> IntegerVector {
285 v * self
286 }
287}
288
289impl Mul<&IntegerVector> for Integer {
290 type Output = IntegerVector;
291
292 /// Multiplies an [`Integer`] by every element of an [`IntegerVector`], taking the scalar by
293 /// value and the vector by reference.
294 ///
295 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
296 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
297 ///
298 /// # Worst-case complexity
299 /// $T(n) = O(n \log n \log\log n)$
300 ///
301 /// $M(n) = O(n \log n)$
302 ///
303 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
304 /// elements and of the scalar.
305 ///
306 /// # Examples
307 /// ```
308 /// use core::str::FromStr;
309 /// use malachite_nz::integer::Integer;
310 /// use malachite_nz::integer_vector::IntegerVector;
311 ///
312 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
313 /// let c = Integer::from(-3);
314 /// assert_eq!((c * &v).to_string(), "(-3, 6, -9)");
315 /// ```
316 ///
317 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
318 #[inline]
319 fn mul(self, v: &IntegerVector) -> IntegerVector {
320 v * self
321 }
322}
323
324impl Mul<IntegerVector> for &Integer {
325 type Output = IntegerVector;
326
327 /// Multiplies an [`Integer`] by every element of an [`IntegerVector`], taking the scalar by
328 /// reference and the vector by value.
329 ///
330 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
331 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
332 ///
333 /// # Worst-case complexity
334 /// $T(n) = O(n \log n \log\log n)$
335 ///
336 /// $M(n) = O(n \log n)$
337 ///
338 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
339 /// elements and of the scalar.
340 ///
341 /// # Examples
342 /// ```
343 /// use core::str::FromStr;
344 /// use malachite_nz::integer::Integer;
345 /// use malachite_nz::integer_vector::IntegerVector;
346 ///
347 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
348 /// let c = Integer::from(-3);
349 /// assert_eq!((&c * v).to_string(), "(-3, 6, -9)");
350 /// ```
351 ///
352 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
353 #[inline]
354 fn mul(self, v: IntegerVector) -> IntegerVector {
355 v * self
356 }
357}
358
359impl Mul<&IntegerVector> for &Integer {
360 type Output = IntegerVector;
361
362 /// Multiplies an [`Integer`] by every element of an [`IntegerVector`], taking the scalar by
363 /// reference and the vector by reference.
364 ///
365 /// Scalar multiplication is commutative, so this is `v * c`; see the documentation for the
366 /// [`Mul`] implementation that takes the vector and the scalar by value for details.
367 ///
368 /// # Worst-case complexity
369 /// $T(n) = O(n \log n \log\log n)$
370 ///
371 /// $M(n) = O(n \log n)$
372 ///
373 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
374 /// elements and of the scalar.
375 ///
376 /// # Examples
377 /// ```
378 /// use core::str::FromStr;
379 /// use malachite_nz::integer::Integer;
380 /// use malachite_nz::integer_vector::IntegerVector;
381 ///
382 /// let v = IntegerVector::from_str("(1, -2, 3)").unwrap();
383 /// let c = Integer::from(-3);
384 /// assert_eq!((&c * &v).to_string(), "(-3, 6, -9)");
385 /// ```
386 ///
387 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0.
388 #[inline]
389 fn mul(self, v: &IntegerVector) -> IntegerVector {
390 v * self
391 }
392}
393
394impl MulAssign<Integer> for IntegerVector {
395 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`] in place, taking the
396 /// scalar by value.
397 ///
398 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
399 /// value for details.
400 ///
401 /// # Worst-case complexity
402 /// $T(n) = O(n \log n \log\log n)$
403 ///
404 /// $M(n) = O(n \log n)$
405 ///
406 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
407 /// elements and of the scalar.
408 ///
409 /// # Examples
410 /// ```
411 /// use core::str::FromStr;
412 /// use malachite_nz::integer::Integer;
413 /// use malachite_nz::integer_vector::IntegerVector;
414 ///
415 /// let mut v = IntegerVector::from_str("(1, -2, 3)").unwrap();
416 /// v *= Integer::from(-3);
417 /// assert_eq!(v.to_string(), "(-3, 6, -9)");
418 /// ```
419 ///
420 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0,
421 /// with `vec1` equal to `vec2`.
422 #[inline]
423 fn mul_assign(&mut self, c: Integer) {
424 *self *= &c;
425 }
426}
427
428impl MulAssign<&Integer> for IntegerVector {
429 /// Multiplies every element of an [`IntegerVector`] by an [`Integer`] in place, taking the
430 /// scalar by reference.
431 ///
432 /// See the documentation for the [`Mul`] implementation that takes the vector and the scalar by
433 /// value for details.
434 ///
435 /// # Worst-case complexity
436 /// $T(n) = O(n \log n \log\log n)$
437 ///
438 /// $M(n) = O(n \log n)$
439 ///
440 /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
441 /// elements and of the scalar.
442 ///
443 /// # Examples
444 /// ```
445 /// use core::str::FromStr;
446 /// use malachite_nz::integer::Integer;
447 /// use malachite_nz::integer_vector::IntegerVector;
448 ///
449 /// let mut v = IntegerVector::from_str("(1, -2, 3)").unwrap();
450 /// v *= &Integer::from(-3);
451 /// assert_eq!(v.to_string(), "(-3, 6, -9)");
452 /// ```
453 ///
454 /// This is equivalent to `_fmpz_vec_scalar_mul_fmpz` from `fmpz_vec/scalar.c`, FLINT 3.6.0,
455 /// with `vec1` equal to `vec2`.
456 fn mul_assign(&mut self, c: &Integer) {
457 integers_mul_scalar_assign(&mut self.elements, c);
458 }
459}