Skip to main content

malachite_nz/gaussian_integer/arithmetic/
add.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::gaussian_integer::GaussianInteger;
10use core::iter::Sum;
11use core::ops::{Add, AddAssign};
12use malachite_base::num::basic::traits::Zero;
13
14impl Add<Self> for GaussianInteger {
15    type Output = Self;
16
17    /// Adds two [`GaussianInteger`]s, taking both by value.
18    ///
19    /// $$
20    /// f(x, y) = x + y.
21    /// $$
22    ///
23    /// # Worst-case complexity
24    /// $T(n) = O(n)$
25    ///
26    /// $M(n) = O(n)$
27    ///
28    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
29    /// bits of the real and imaginary parts of `self` and `other`.
30    ///
31    /// # Examples
32    /// ```
33    /// use malachite_nz::gaussian_integer::GaussianInteger;
34    /// use std::str::FromStr;
35    ///
36    /// let x = GaussianInteger::from_str("2-3i").unwrap();
37    /// let y = GaussianInteger::from_str("-1+4i").unwrap();
38    /// assert_eq!((x + y).to_string(), "1+i");
39    /// ```
40    #[inline]
41    fn add(mut self, other: Self) -> Self {
42        self += other;
43        self
44    }
45}
46
47impl Add<&Self> for GaussianInteger {
48    type Output = Self;
49
50    /// Adds two [`GaussianInteger`]s, taking the first by value and the second by reference.
51    ///
52    /// $$
53    /// f(x, y) = x + y.
54    /// $$
55    ///
56    /// # Worst-case complexity
57    /// $T(n) = O(n)$
58    ///
59    /// $M(n) = O(n)$
60    ///
61    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
62    /// bits of the real and imaginary parts of `self` and `other`.
63    ///
64    /// # Examples
65    /// ```
66    /// use malachite_nz::gaussian_integer::GaussianInteger;
67    /// use std::str::FromStr;
68    ///
69    /// let x = GaussianInteger::from_str("2-3i").unwrap();
70    /// let y = GaussianInteger::from_str("-1+4i").unwrap();
71    /// assert_eq!((x + &y).to_string(), "1+i");
72    /// ```
73    #[inline]
74    fn add(mut self, other: &Self) -> Self {
75        self += other;
76        self
77    }
78}
79
80impl Add<GaussianInteger> for &GaussianInteger {
81    type Output = GaussianInteger;
82
83    /// Adds two [`GaussianInteger`]s, taking the first by reference and the second by value.
84    ///
85    /// $$
86    /// f(x, y) = x + y.
87    /// $$
88    ///
89    /// # Worst-case complexity
90    /// $T(n) = O(n)$
91    ///
92    /// $M(n) = O(n)$
93    ///
94    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
95    /// bits of the real and imaginary parts of `self` and `other`.
96    ///
97    /// # Examples
98    /// ```
99    /// use malachite_nz::gaussian_integer::GaussianInteger;
100    /// use std::str::FromStr;
101    ///
102    /// let x = GaussianInteger::from_str("2-3i").unwrap();
103    /// let y = GaussianInteger::from_str("-1+4i").unwrap();
104    /// assert_eq!((&x + y).to_string(), "1+i");
105    /// ```
106    #[inline]
107    fn add(self, other: GaussianInteger) -> GaussianInteger {
108        GaussianInteger {
109            real: &self.real + other.real,
110            imaginary: &self.imaginary + other.imaginary,
111        }
112    }
113}
114
115impl Add<&GaussianInteger> for &GaussianInteger {
116    type Output = GaussianInteger;
117
118    /// Adds two [`GaussianInteger`]s, taking both by reference.
119    ///
120    /// $$
121    /// f(x, y) = x + y.
122    /// $$
123    ///
124    /// # Worst-case complexity
125    /// $T(n) = O(n)$
126    ///
127    /// $M(n) = O(n)$
128    ///
129    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
130    /// bits of the real and imaginary parts of `self` and `other`.
131    ///
132    /// # Examples
133    /// ```
134    /// use malachite_nz::gaussian_integer::GaussianInteger;
135    /// use std::str::FromStr;
136    ///
137    /// let x = GaussianInteger::from_str("1000000000000+i").unwrap();
138    /// let y = GaussianInteger::from_str("i").unwrap();
139    /// assert_eq!((&x + &y).to_string(), "1000000000000+2i");
140    /// ```
141    #[inline]
142    fn add(self, other: &GaussianInteger) -> GaussianInteger {
143        GaussianInteger {
144            real: &self.real + &other.real,
145            imaginary: &self.imaginary + &other.imaginary,
146        }
147    }
148}
149
150impl AddAssign<Self> for GaussianInteger {
151    /// Adds a [`GaussianInteger`] to a [`GaussianInteger`] in place, taking the [`GaussianInteger`]
152    /// on the right-hand side by value.
153    ///
154    /// $$
155    /// x \gets x + y.
156    /// $$
157    ///
158    /// # Worst-case complexity
159    /// $T(n) = O(n)$
160    ///
161    /// $M(n) = O(n)$
162    ///
163    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
164    /// bits of the real and imaginary parts of `self` and `other`.
165    ///
166    /// # Examples
167    /// ```
168    /// use malachite_nz::gaussian_integer::GaussianInteger;
169    /// use std::str::FromStr;
170    ///
171    /// let x = GaussianInteger::from_str("2-3i").unwrap();
172    /// let y = GaussianInteger::from_str("-1+4i").unwrap();
173    /// let mut sum = x;
174    /// sum += y;
175    /// assert_eq!(sum.to_string(), "1+i");
176    /// ```
177    #[inline]
178    fn add_assign(&mut self, other: Self) {
179        self.real += other.real;
180        self.imaginary += other.imaginary;
181    }
182}
183
184impl AddAssign<&Self> for GaussianInteger {
185    /// Adds a [`GaussianInteger`] to a [`GaussianInteger`] in place, taking the [`GaussianInteger`]
186    /// on the right-hand side by reference.
187    ///
188    /// $$
189    /// x \gets x + y.
190    /// $$
191    ///
192    /// # Worst-case complexity
193    /// $T(n) = O(n)$
194    ///
195    /// $M(n) = O(n)$
196    ///
197    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
198    /// bits of the real and imaginary parts of `self` and `other`.
199    ///
200    /// # Examples
201    /// ```
202    /// use malachite_nz::gaussian_integer::GaussianInteger;
203    /// use std::str::FromStr;
204    ///
205    /// let x = GaussianInteger::from_str("2-3i").unwrap();
206    /// let y = GaussianInteger::from_str("-1+4i").unwrap();
207    /// let mut sum = x;
208    /// sum += &y;
209    /// assert_eq!(sum.to_string(), "1+i");
210    /// ```
211    #[inline]
212    fn add_assign(&mut self, other: &Self) {
213        self.real += &other.real;
214        self.imaginary += &other.imaginary;
215    }
216}
217
218impl Sum for GaussianInteger {
219    /// Adds up all the [`GaussianInteger`]s in an iterator.
220    ///
221    /// $$
222    /// f((x_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} x_i.
223    /// $$
224    ///
225    /// # Worst-case complexity
226    /// $T(n) = O(n^2)$
227    ///
228    /// $M(n) = O(n)$
229    ///
230    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of significant bits
231    /// of the real and imaginary parts of the [`GaussianInteger`]s.
232    ///
233    /// # Examples
234    /// ```
235    /// use core::iter::Sum;
236    /// use malachite_base::vecs::vec_from_str;
237    /// use malachite_nz::gaussian_integer::GaussianInteger;
238    ///
239    /// assert_eq!(
240    ///     GaussianInteger::sum(
241    ///         vec_from_str::<GaussianInteger>("[2, -3i, 5+i, 7-2i]")
242    ///             .unwrap()
243    ///             .into_iter()
244    ///     )
245    ///     .to_string(),
246    ///     "14-4i"
247    /// );
248    /// ```
249    fn sum<I>(xs: I) -> Self
250    where
251        I: Iterator<Item = Self>,
252    {
253        let mut s = Self::ZERO;
254        for x in xs {
255            s += x;
256        }
257        s
258    }
259}
260
261impl<'a> Sum<&'a Self> for GaussianInteger {
262    /// Adds up all the [`GaussianInteger`]s in an iterator of [`GaussianInteger`] references.
263    ///
264    /// $$
265    /// f((x_i)_ {i=0}^{n-1}) = \sum_ {i=0}^{n-1} x_i.
266    /// $$
267    ///
268    /// # Worst-case complexity
269    /// $T(n) = O(n^2)$
270    ///
271    /// $M(n) = O(n)$
272    ///
273    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of significant bits
274    /// of the real and imaginary parts of the [`GaussianInteger`]s.
275    ///
276    /// # Examples
277    /// ```
278    /// use core::iter::Sum;
279    /// use malachite_base::vecs::vec_from_str;
280    /// use malachite_nz::gaussian_integer::GaussianInteger;
281    ///
282    /// assert_eq!(
283    ///     GaussianInteger::sum(
284    ///         vec_from_str::<GaussianInteger>("[2, -3i, 5+i, 7-2i]")
285    ///             .unwrap()
286    ///             .iter()
287    ///     )
288    ///     .to_string(),
289    ///     "14-4i"
290    /// );
291    /// ```
292    fn sum<I>(xs: I) -> Self
293    where
294        I: Iterator<Item = &'a Self>,
295    {
296        let mut s = Self::ZERO;
297        for x in xs {
298            s += x;
299        }
300        s
301    }
302}