Skip to main content

malachite_nz/integer_vector/arithmetic/
element_product.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::integer::Integer;
10use crate::integer_vector::IntegerVector;
11use malachite_base::num::arithmetic::traits::ElementProduct;
12
13impl ElementProduct for IntegerVector {
14    type Output = Integer;
15
16    /// Returns the product of the elements of an [`IntegerVector`], taking the vector by reference.
17    ///
18    /// The 0-dimensional vector has no elements, and their product is 1. The elements are
19    /// multiplied in a balanced tree, so that the operands of each multiplication have similar
20    /// sizes, and multiplication stops as soon as a zero element is found.
21    ///
22    /// $$
23    /// f(v) = \prod_i v_i.
24    /// $$
25    ///
26    /// # Worst-case complexity
27    /// $T(n) = O(n (\log n)^2 \log\log n)$
28    ///
29    /// $M(n) = O(n \log n)$
30    ///
31    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
32    /// elements.
33    ///
34    /// # Examples
35    /// ```
36    /// use core::str::FromStr;
37    /// use malachite_base::num::arithmetic::traits::ElementProduct;
38    /// use malachite_nz::integer_vector::IntegerVector;
39    ///
40    /// assert_eq!(
41    ///     IntegerVector::from_str("(2, -3, 7)")
42    ///         .unwrap()
43    ///         .to_element_product(),
44    ///     -42
45    /// );
46    /// assert_eq!(
47    ///     IntegerVector::from_str("()").unwrap().to_element_product(),
48    ///     1
49    /// );
50    /// ```
51    ///
52    /// This is equivalent to `_fmpz_vec_prod` from `fmpz_vec/prod.c`, FLINT 3.6.0.
53    #[inline]
54    fn to_element_product(&self) -> Integer {
55        self.elements.iter().product()
56    }
57
58    /// Returns the product of the elements of an [`IntegerVector`], taking the vector by value.
59    ///
60    /// The 0-dimensional vector has no elements, and their product is 1. The elements are
61    /// multiplied in a balanced tree, so that the operands of each multiplication have similar
62    /// sizes, and multiplication stops as soon as a zero element is found.
63    ///
64    /// $$
65    /// f(v) = \prod_i v_i.
66    /// $$
67    ///
68    /// # Worst-case complexity
69    /// $T(n) = O(n (\log n)^2 \log\log n)$
70    ///
71    /// $M(n) = O(n \log n)$
72    ///
73    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
74    /// elements.
75    ///
76    /// # Examples
77    /// ```
78    /// use core::str::FromStr;
79    /// use malachite_base::num::arithmetic::traits::ElementProduct;
80    /// use malachite_nz::integer_vector::IntegerVector;
81    ///
82    /// assert_eq!(
83    ///     IntegerVector::from_str("(2, -3, 7)")
84    ///         .unwrap()
85    ///         .into_element_product(),
86    ///     -42
87    /// );
88    /// assert_eq!(
89    ///     IntegerVector::from_str("()")
90    ///         .unwrap()
91    ///         .into_element_product(),
92    ///     1
93    /// );
94    /// ```
95    ///
96    /// This is equivalent to `_fmpz_vec_prod` from `fmpz_vec/prod.c`, FLINT 3.6.0.
97    #[inline]
98    fn into_element_product(self) -> Integer {
99        self.elements.into_iter().product()
100    }
101}