Skip to main content

malachite_nz/gaussian_integer/arithmetic/
abs_squared.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 crate::integer::Integer;
11use malachite_base::num::arithmetic::traits::{AbsSquared, AbsSquaredAssign, Square, SquareAssign};
12
13impl AbsSquared for GaussianInteger {
14    type Output = Integer;
15
16    /// Computes the squared absolute value of a [`GaussianInteger`], taking it by value. This is
17    /// the sum of the squares of the real and imaginary parts, also known as the norm. It is always
18    /// a non-negative [`Integer`].
19    ///
20    /// $$
21    /// f(x) = |x|^2 = \Re(x)^2 + \Im(x)^2.
22    /// $$
23    ///
24    /// # Worst-case complexity
25    /// $T(n) = O(n \log n \log\log n)$
26    ///
27    /// $M(n) = O(n \log n)$
28    ///
29    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
30    /// bits of the real and imaginary parts.
31    ///
32    /// # Examples
33    /// ```
34    /// use malachite_base::num::arithmetic::traits::AbsSquared;
35    /// use malachite_base::num::basic::traits::{I, Zero};
36    /// use malachite_nz::gaussian_integer::GaussianInteger;
37    /// use std::str::FromStr;
38    ///
39    /// assert_eq!(GaussianInteger::ZERO.abs_squared(), 0);
40    /// assert_eq!(GaussianInteger::I.abs_squared(), 1);
41    /// assert_eq!(GaussianInteger::from_str("2-3i").unwrap().abs_squared(), 13);
42    /// assert_eq!(GaussianInteger::from(-123).abs_squared(), 15129);
43    /// ```
44    #[inline]
45    fn abs_squared(self) -> Integer {
46        self.real.square() + self.imaginary.square()
47    }
48}
49
50impl AbsSquared for &GaussianInteger {
51    type Output = Integer;
52
53    /// Computes the squared absolute value of a [`GaussianInteger`], taking it by reference. This
54    /// is the sum of the squares of the real and imaginary parts, also known as the norm. It is
55    /// always a non-negative [`Integer`].
56    ///
57    /// $$
58    /// f(x) = |x|^2 = \Re(x)^2 + \Im(x)^2.
59    /// $$
60    ///
61    /// # Worst-case complexity
62    /// $T(n) = O(n \log n \log\log n)$
63    ///
64    /// $M(n) = O(n \log n)$
65    ///
66    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
67    /// bits of the real and imaginary parts.
68    ///
69    /// # Examples
70    /// ```
71    /// use malachite_base::num::arithmetic::traits::AbsSquared;
72    /// use malachite_base::num::basic::traits::{I, Zero};
73    /// use malachite_nz::gaussian_integer::GaussianInteger;
74    /// use std::str::FromStr;
75    ///
76    /// assert_eq!((&GaussianInteger::ZERO).abs_squared(), 0);
77    /// assert_eq!((&GaussianInteger::I).abs_squared(), 1);
78    /// let x = GaussianInteger::from_str("2-3i").unwrap();
79    /// assert_eq!((&x).abs_squared(), 13);
80    /// ```
81    #[inline]
82    fn abs_squared(self) -> Integer {
83        (&self.real).square() + (&self.imaginary).square()
84    }
85}
86
87impl AbsSquaredAssign for GaussianInteger {
88    /// Replaces a [`GaussianInteger`] with its squared absolute value: the purely real value
89    /// $|x|^2$, embedded in the same type. The real part becomes the sum of the squares of the real
90    /// and imaginary parts (the norm), and the imaginary part becomes zero.
91    ///
92    /// $$
93    /// x \gets |x|^2 = \Re(x)^2 + \Im(x)^2.
94    /// $$
95    ///
96    /// # Worst-case complexity
97    /// $T(n) = O(n \log n \log\log n)$
98    ///
99    /// $M(n) = O(n \log n)$
100    ///
101    /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
102    /// bits of the real and imaginary parts.
103    ///
104    /// # Examples
105    /// ```
106    /// use malachite_base::num::arithmetic::traits::AbsSquaredAssign;
107    /// use malachite_nz::gaussian_integer::GaussianInteger;
108    /// use std::str::FromStr;
109    ///
110    /// let mut x = GaussianInteger::from_str("2-3i").unwrap();
111    /// x.abs_squared_assign();
112    /// assert_eq!(x.to_string(), "13");
113    /// ```
114    fn abs_squared_assign(&mut self) {
115        self.real.square_assign();
116        self.imaginary.square_assign();
117        self.real += core::mem::take(&mut self.imaginary);
118    }
119}