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}