malachite_nz/integer/arithmetic/mul_add_mul.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 malachite_base::num::arithmetic::traits::{AddMul, AddMulAssign, MulAddMul, MulAddMulAssign};
11
12impl MulAddMul<Self, Self, Self> for Integer {
13 type Output = Self;
14
15 /// Adds the products of two pairs of [`Integer`]s, taking all four by value.
16 ///
17 /// $f(x, y, z, w) = xy + zw$.
18 ///
19 /// # Worst-case complexity
20 /// $T(n) = O(n \log n \log\log n)$
21 ///
22 /// $M(n) = O(n \log n)$
23 ///
24 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
25 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
26 ///
27 /// # Examples
28 /// ```
29 /// use malachite_base::num::arithmetic::traits::MulAddMul;
30 /// use malachite_nz::integer::Integer;
31 ///
32 /// assert_eq!(
33 /// Integer::from(-10).mul_add_mul(Integer::from(3), Integer::from(4), Integer::from(5)),
34 /// -10
35 /// );
36 /// ```
37 #[inline]
38 fn mul_add_mul(self, y: Self, z: Self, w: Self) -> Self {
39 (self * y).add_mul(z, w)
40 }
41}
42
43impl MulAddMul<Self, Self, &Self> for Integer {
44 type Output = Self;
45
46 /// Adds the products of two pairs of [`Integer`]s, taking $x$, $y$ and $z$ by value and $w$ by
47 /// reference.
48 ///
49 /// $f(x, y, z, w) = xy + zw$.
50 ///
51 /// # Worst-case complexity
52 /// $T(n) = O(n \log n \log\log n)$
53 ///
54 /// $M(n) = O(n \log n)$
55 ///
56 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
57 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
58 ///
59 /// # Examples
60 /// ```
61 /// use malachite_base::num::arithmetic::traits::MulAddMul;
62 /// use malachite_nz::integer::Integer;
63 ///
64 /// assert_eq!(
65 /// Integer::from(-10).mul_add_mul(Integer::from(3), Integer::from(4), &Integer::from(5)),
66 /// -10
67 /// );
68 /// ```
69 #[inline]
70 fn mul_add_mul(self, y: Self, z: Self, w: &Self) -> Self {
71 (self * y).add_mul(z, w)
72 }
73}
74
75impl MulAddMul<Self, &Self, Self> for Integer {
76 type Output = Self;
77
78 /// Adds the products of two pairs of [`Integer`]s, taking $x$, $y$ and $w$ by value and $z$ by
79 /// reference.
80 ///
81 /// $f(x, y, z, w) = xy + zw$.
82 ///
83 /// # Worst-case complexity
84 /// $T(n) = O(n \log n \log\log n)$
85 ///
86 /// $M(n) = O(n \log n)$
87 ///
88 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
89 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
90 ///
91 /// # Examples
92 /// ```
93 /// use malachite_base::num::arithmetic::traits::MulAddMul;
94 /// use malachite_nz::integer::Integer;
95 ///
96 /// assert_eq!(
97 /// Integer::from(-10).mul_add_mul(Integer::from(3), &Integer::from(4), Integer::from(5)),
98 /// -10
99 /// );
100 /// ```
101 #[inline]
102 fn mul_add_mul(self, y: Self, z: &Self, w: Self) -> Self {
103 (self * y).add_mul(z, w)
104 }
105}
106
107impl MulAddMul<Self, &Self, &Self> for Integer {
108 type Output = Self;
109
110 /// Adds the products of two pairs of [`Integer`]s, taking $x$ and $y$ by value and $z$ and $w$
111 /// by reference.
112 ///
113 /// $f(x, y, z, w) = xy + zw$.
114 ///
115 /// # Worst-case complexity
116 /// $T(n) = O(n \log n \log\log n)$
117 ///
118 /// $M(n) = O(n \log n)$
119 ///
120 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
121 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
122 ///
123 /// # Examples
124 /// ```
125 /// use malachite_base::num::arithmetic::traits::MulAddMul;
126 /// use malachite_nz::integer::Integer;
127 ///
128 /// assert_eq!(
129 /// Integer::from(-10).mul_add_mul(Integer::from(3), &Integer::from(4), &Integer::from(5)),
130 /// -10
131 /// );
132 /// ```
133 #[inline]
134 fn mul_add_mul(self, y: Self, z: &Self, w: &Self) -> Self {
135 (self * y).add_mul(z, w)
136 }
137}
138
139impl MulAddMul<&Self, Self, Self> for Integer {
140 type Output = Self;
141
142 /// Adds the products of two pairs of [`Integer`]s, taking $x$, $z$ and $w$ by value and $y$ by
143 /// reference.
144 ///
145 /// $f(x, y, z, w) = xy + zw$.
146 ///
147 /// # Worst-case complexity
148 /// $T(n) = O(n \log n \log\log n)$
149 ///
150 /// $M(n) = O(n \log n)$
151 ///
152 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
153 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
154 ///
155 /// # Examples
156 /// ```
157 /// use malachite_base::num::arithmetic::traits::MulAddMul;
158 /// use malachite_nz::integer::Integer;
159 ///
160 /// assert_eq!(
161 /// Integer::from(-10).mul_add_mul(&Integer::from(3), Integer::from(4), Integer::from(5)),
162 /// -10
163 /// );
164 /// ```
165 #[inline]
166 fn mul_add_mul(self, y: &Self, z: Self, w: Self) -> Self {
167 (self * y).add_mul(z, w)
168 }
169}
170
171impl MulAddMul<&Self, Self, &Self> for Integer {
172 type Output = Self;
173
174 /// Adds the products of two pairs of [`Integer`]s, taking $x$ and $z$ by value and $y$ and $w$
175 /// by reference.
176 ///
177 /// $f(x, y, z, w) = xy + zw$.
178 ///
179 /// # Worst-case complexity
180 /// $T(n) = O(n \log n \log\log n)$
181 ///
182 /// $M(n) = O(n \log n)$
183 ///
184 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
185 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
186 ///
187 /// # Examples
188 /// ```
189 /// use malachite_base::num::arithmetic::traits::MulAddMul;
190 /// use malachite_nz::integer::Integer;
191 ///
192 /// assert_eq!(
193 /// Integer::from(-10).mul_add_mul(&Integer::from(3), Integer::from(4), &Integer::from(5)),
194 /// -10
195 /// );
196 /// ```
197 #[inline]
198 fn mul_add_mul(self, y: &Self, z: Self, w: &Self) -> Self {
199 (self * y).add_mul(z, w)
200 }
201}
202
203impl MulAddMul<&Self, &Self, Self> for Integer {
204 type Output = Self;
205
206 /// Adds the products of two pairs of [`Integer`]s, taking $x$ and $w$ by value and $y$ and $z$
207 /// by reference.
208 ///
209 /// $f(x, y, z, w) = xy + zw$.
210 ///
211 /// # Worst-case complexity
212 /// $T(n) = O(n \log n \log\log n)$
213 ///
214 /// $M(n) = O(n \log n)$
215 ///
216 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
217 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
218 ///
219 /// # Examples
220 /// ```
221 /// use malachite_base::num::arithmetic::traits::MulAddMul;
222 /// use malachite_nz::integer::Integer;
223 ///
224 /// assert_eq!(
225 /// Integer::from(-10).mul_add_mul(&Integer::from(3), &Integer::from(4), Integer::from(5)),
226 /// -10
227 /// );
228 /// ```
229 #[inline]
230 fn mul_add_mul(self, y: &Self, z: &Self, w: Self) -> Self {
231 (self * y).add_mul(z, w)
232 }
233}
234
235impl MulAddMul<&Self, &Self, &Self> for Integer {
236 type Output = Self;
237
238 /// Adds the products of two pairs of [`Integer`]s, taking $x$ by value and $y$, $z$ and $w$ by
239 /// reference.
240 ///
241 /// $f(x, y, z, w) = xy + zw$.
242 ///
243 /// # Worst-case complexity
244 /// $T(n) = O(n \log n \log\log n)$
245 ///
246 /// $M(n) = O(n \log n)$
247 ///
248 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
249 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
250 ///
251 /// # Examples
252 /// ```
253 /// use malachite_base::num::arithmetic::traits::MulAddMul;
254 /// use malachite_nz::integer::Integer;
255 ///
256 /// assert_eq!(
257 /// Integer::from(-10).mul_add_mul(&Integer::from(3), &Integer::from(4), &Integer::from(5)),
258 /// -10
259 /// );
260 /// ```
261 #[inline]
262 fn mul_add_mul(self, y: &Self, z: &Self, w: &Self) -> Self {
263 (self * y).add_mul(z, w)
264 }
265}
266
267impl MulAddMul<&Integer, &Integer, &Integer> for &Integer {
268 type Output = Integer;
269
270 /// Adds the products of two pairs of [`Integer`]s, taking all four by reference.
271 ///
272 /// $f(x, y, z, w) = xy + zw$.
273 ///
274 /// # Worst-case complexity
275 /// $T(n) = O(n \log n \log\log n)$
276 ///
277 /// $M(n) = O(n \log n)$
278 ///
279 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
280 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
281 ///
282 /// # Examples
283 /// ```
284 /// use malachite_base::num::arithmetic::traits::MulAddMul;
285 /// use malachite_nz::integer::Integer;
286 ///
287 /// assert_eq!(
288 /// (&Integer::from(-10)).mul_add_mul(
289 /// &Integer::from(3),
290 /// &Integer::from(4),
291 /// &Integer::from(5)
292 /// ),
293 /// -10
294 /// );
295 /// ```
296 #[inline]
297 fn mul_add_mul(self, y: &Integer, z: &Integer, w: &Integer) -> Integer {
298 (self * y).add_mul(z, w)
299 }
300}
301
302impl MulAddMulAssign<Self, Self, Self> for Integer {
303 /// Adds the products of two pairs of [`Integer`]s, in place, taking all four by value.
304 ///
305 /// $x \gets xy + zw$.
306 ///
307 /// # Worst-case complexity
308 /// $T(n) = O(n \log n \log\log n)$
309 ///
310 /// $M(n) = O(n \log n)$
311 ///
312 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
313 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
314 ///
315 /// # Examples
316 /// ```
317 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
318 /// use malachite_nz::integer::Integer;
319 ///
320 /// let mut x = Integer::from(-10);
321 /// x.mul_add_mul_assign(Integer::from(3), Integer::from(4), Integer::from(5));
322 /// assert_eq!(x, -10);
323 /// ```
324 #[inline]
325 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: Self) {
326 *self *= y;
327 self.add_mul_assign(z, w);
328 }
329}
330
331impl MulAddMulAssign<Self, Self, &Self> for Integer {
332 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$, $y$ and $z$ by value
333 /// and $w$ by reference.
334 ///
335 /// $x \gets xy + zw$.
336 ///
337 /// # Worst-case complexity
338 /// $T(n) = O(n \log n \log\log n)$
339 ///
340 /// $M(n) = O(n \log n)$
341 ///
342 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
343 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
344 ///
345 /// # Examples
346 /// ```
347 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
348 /// use malachite_nz::integer::Integer;
349 ///
350 /// let mut x = Integer::from(-10);
351 /// x.mul_add_mul_assign(Integer::from(3), Integer::from(4), &Integer::from(5));
352 /// assert_eq!(x, -10);
353 /// ```
354 #[inline]
355 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: &Self) {
356 *self *= y;
357 self.add_mul_assign(z, w);
358 }
359}
360
361impl MulAddMulAssign<Self, &Self, Self> for Integer {
362 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$, $y$ and $w$ by value
363 /// and $z$ by reference.
364 ///
365 /// $x \gets xy + zw$.
366 ///
367 /// # Worst-case complexity
368 /// $T(n) = O(n \log n \log\log n)$
369 ///
370 /// $M(n) = O(n \log n)$
371 ///
372 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
373 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
374 ///
375 /// # Examples
376 /// ```
377 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
378 /// use malachite_nz::integer::Integer;
379 ///
380 /// let mut x = Integer::from(-10);
381 /// x.mul_add_mul_assign(Integer::from(3), &Integer::from(4), Integer::from(5));
382 /// assert_eq!(x, -10);
383 /// ```
384 #[inline]
385 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: Self) {
386 *self *= y;
387 self.add_mul_assign(z, w);
388 }
389}
390
391impl MulAddMulAssign<Self, &Self, &Self> for Integer {
392 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$ and $y$ by value and
393 /// $z$ and $w$ by reference.
394 ///
395 /// $x \gets xy + zw$.
396 ///
397 /// # Worst-case complexity
398 /// $T(n) = O(n \log n \log\log n)$
399 ///
400 /// $M(n) = O(n \log n)$
401 ///
402 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
403 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
404 ///
405 /// # Examples
406 /// ```
407 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
408 /// use malachite_nz::integer::Integer;
409 ///
410 /// let mut x = Integer::from(-10);
411 /// x.mul_add_mul_assign(Integer::from(3), &Integer::from(4), &Integer::from(5));
412 /// assert_eq!(x, -10);
413 /// ```
414 #[inline]
415 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: &Self) {
416 *self *= y;
417 self.add_mul_assign(z, w);
418 }
419}
420
421impl MulAddMulAssign<&Self, Self, Self> for Integer {
422 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$, $z$ and $w$ by value
423 /// and $y$ by reference.
424 ///
425 /// $x \gets xy + zw$.
426 ///
427 /// # Worst-case complexity
428 /// $T(n) = O(n \log n \log\log n)$
429 ///
430 /// $M(n) = O(n \log n)$
431 ///
432 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
433 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
434 ///
435 /// # Examples
436 /// ```
437 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
438 /// use malachite_nz::integer::Integer;
439 ///
440 /// let mut x = Integer::from(-10);
441 /// x.mul_add_mul_assign(&Integer::from(3), Integer::from(4), Integer::from(5));
442 /// assert_eq!(x, -10);
443 /// ```
444 #[inline]
445 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: Self) {
446 *self *= y;
447 self.add_mul_assign(z, w);
448 }
449}
450
451impl MulAddMulAssign<&Self, Self, &Self> for Integer {
452 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$ and $z$ by value and
453 /// $y$ and $w$ by reference.
454 ///
455 /// $x \gets xy + zw$.
456 ///
457 /// # Worst-case complexity
458 /// $T(n) = O(n \log n \log\log n)$
459 ///
460 /// $M(n) = O(n \log n)$
461 ///
462 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
463 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
464 ///
465 /// # Examples
466 /// ```
467 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
468 /// use malachite_nz::integer::Integer;
469 ///
470 /// let mut x = Integer::from(-10);
471 /// x.mul_add_mul_assign(&Integer::from(3), Integer::from(4), &Integer::from(5));
472 /// assert_eq!(x, -10);
473 /// ```
474 #[inline]
475 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: &Self) {
476 *self *= y;
477 self.add_mul_assign(z, w);
478 }
479}
480
481impl MulAddMulAssign<&Self, &Self, Self> for Integer {
482 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$ and $w$ by value and
483 /// $y$ and $z$ by reference.
484 ///
485 /// $x \gets xy + zw$.
486 ///
487 /// # Worst-case complexity
488 /// $T(n) = O(n \log n \log\log n)$
489 ///
490 /// $M(n) = O(n \log n)$
491 ///
492 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
493 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
494 ///
495 /// # Examples
496 /// ```
497 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
498 /// use malachite_nz::integer::Integer;
499 ///
500 /// let mut x = Integer::from(-10);
501 /// x.mul_add_mul_assign(&Integer::from(3), &Integer::from(4), Integer::from(5));
502 /// assert_eq!(x, -10);
503 /// ```
504 #[inline]
505 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: Self) {
506 *self *= y;
507 self.add_mul_assign(z, w);
508 }
509}
510
511impl MulAddMulAssign<&Self, &Self, &Self> for Integer {
512 /// Adds the products of two pairs of [`Integer`]s, in place, taking $x$ by value and $y$, $z$
513 /// and $w$ by reference.
514 ///
515 /// $x \gets xy + zw$.
516 ///
517 /// # Worst-case complexity
518 /// $T(n) = O(n \log n \log\log n)$
519 ///
520 /// $M(n) = O(n \log n)$
521 ///
522 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
523 /// y.significant_bits(), z.significant_bits(), w.significant_bits())`.
524 ///
525 /// # Examples
526 /// ```
527 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
528 /// use malachite_nz::integer::Integer;
529 ///
530 /// let mut x = Integer::from(-10);
531 /// x.mul_add_mul_assign(&Integer::from(3), &Integer::from(4), &Integer::from(5));
532 /// assert_eq!(x, -10);
533 /// ```
534 #[inline]
535 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: &Self) {
536 *self *= y;
537 self.add_mul_assign(z, w);
538 }
539}