Skip to main content

malachite_q/rational_vector/arithmetic/
sum.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_vector::RationalVector;
10use core::iter::Sum;
11
12const EMPTY: &str = "cannot sum an empty iterator of vectors: the dimension is unknown";
13
14impl Sum for RationalVector {
15    /// Adds up all the [`RationalVector`]s in an iterator, entry by entry.
16    ///
17    /// The vectors must all have the same dimension, which is also the dimension of the sum. Since
18    /// the dimension of the zero vector cannot be inferred from an empty iterator, an empty
19    /// iterator panics rather than summing to zero.
20    ///
21    /// $$
22    /// f((v_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} v_i.
23    /// $$
24    ///
25    /// # Worst-case complexity
26    /// $T(n) = O(n^2)$
27    ///
28    /// $M(n) = O(n)$
29    ///
30    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
31    /// elements of all the vectors.
32    ///
33    /// # Panics
34    /// Panics if the iterator is empty or if the vectors do not all have the same dimension.
35    ///
36    /// # Examples
37    /// ```
38    /// use core::iter::Sum;
39    /// use core::str::FromStr;
40    /// use malachite_q::rational_vector::RationalVector;
41    ///
42    /// let vs = ["(1/2, -2, 3)", "(1/3, 5, -1/6)", "(1/6, 0, 1/2)"]
43    ///     .map(|s| RationalVector::from_str(s).unwrap());
44    /// assert_eq!(
45    ///     RationalVector::sum(vs.into_iter()).to_string(),
46    ///     "(1, 3, 10/3)"
47    /// );
48    ///
49    /// let vs = ["(18446744073709551615/2, -1/3)", "(1/2, 1/3)"]
50    ///     .map(|s| RationalVector::from_str(s).unwrap());
51    /// assert_eq!(
52    ///     RationalVector::sum(vs.into_iter()).to_string(),
53    ///     "(9223372036854775808, 0)"
54    /// );
55    /// ```
56    fn sum<I>(mut xs: I) -> Self
57    where
58        I: Iterator<Item = Self>,
59    {
60        let mut sum = xs.next().expect(EMPTY);
61        for v in xs {
62            sum += v;
63        }
64        sum
65    }
66}
67
68impl<'a> Sum<&'a Self> for RationalVector {
69    /// Adds up all the [`RationalVector`]s in an iterator of references, entry by entry.
70    ///
71    /// The vectors must all have the same dimension, which is also the dimension of the sum. Since
72    /// the dimension of the zero vector cannot be inferred from an empty iterator, an empty
73    /// iterator panics rather than summing to zero.
74    ///
75    /// $$
76    /// f((v_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} v_i.
77    /// $$
78    ///
79    /// # Worst-case complexity
80    /// $T(n) = O(n^2)$
81    ///
82    /// $M(n) = O(n)$
83    ///
84    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
85    /// elements of all the vectors.
86    ///
87    /// # Panics
88    /// Panics if the iterator is empty or if the vectors do not all have the same dimension.
89    ///
90    /// # Examples
91    /// ```
92    /// use core::iter::Sum;
93    /// use core::str::FromStr;
94    /// use malachite_q::rational_vector::RationalVector;
95    ///
96    /// let vs = ["(1/2, -2, 3)", "(1/3, 5, -1/6)", "(1/6, 0, 1/2)"]
97    ///     .map(|s| RationalVector::from_str(s).unwrap());
98    /// assert_eq!(RationalVector::sum(vs.iter()).to_string(), "(1, 3, 10/3)");
99    ///
100    /// let vs = ["(18446744073709551615/2, -1/3)", "(1/2, 1/3)"]
101    ///     .map(|s| RationalVector::from_str(s).unwrap());
102    /// assert_eq!(
103    ///     RationalVector::sum(vs.iter()).to_string(),
104    ///     "(9223372036854775808, 0)"
105    /// );
106    /// ```
107    fn sum<I>(mut xs: I) -> Self
108    where
109        I: Iterator<Item = &'a Self>,
110    {
111        let mut sum = xs.next().expect(EMPTY).clone();
112        for v in xs {
113            sum += v;
114        }
115        sum
116    }
117}