Skip to main content

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}