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}