Skip to main content

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}