malachite_float/float/comparison/partial_cmp_abs_gaussian_integer.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::Float;
10use core::cmp::Ordering::{self, Greater, Less};
11use malachite_base::num::arithmetic::traits::AbsSquared;
12use malachite_base::num::comparison::traits::PartialOrdAbs;
13use malachite_base::num::conversion::traits::ExactFrom;
14use malachite_nz::gaussian_integer::GaussianInteger;
15use malachite_q::Rational;
16
17impl PartialOrdAbs<GaussianInteger> for Float {
18 /// Compares the absolute values of a [`Float`] and a [`GaussianInteger`].
19 ///
20 /// The absolute value of a complex number is its distance from the origin, so this is
21 /// equivalent to comparing squared absolute values. The [`Float`] is smaller in absolute value
22 /// unless it exceeds both components in absolute value, so the squared absolute values are only
23 /// computed in that case. NaN is not comparable to any [`GaussianInteger`]; $\infty$ and
24 /// $-\infty$ are greater in absolute value than any [`GaussianInteger`].
25 ///
26 /// # Worst-case complexity
27 /// $T(n) = O(n \log n \log\log n)$
28 ///
29 /// $M(n) = O(n \log n)$
30 ///
31 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
32 /// bits of `self` and of the real and imaginary parts of `other`.
33 ///
34 /// # Examples
35 /// ```
36 /// use malachite_base::num::basic::traits::Infinity;
37 /// use malachite_base::num::comparison::traits::{EqAbs, PartialOrdAbs};
38 /// use malachite_float::Float;
39 /// use malachite_nz::gaussian_integer::GaussianInteger;
40 /// use std::str::FromStr;
41 ///
42 /// let y = GaussianInteger::from_str("3+4i").unwrap();
43 /// assert!(Float::from(-5).eq_abs(&y));
44 /// assert!(Float::from(4).lt_abs(&y));
45 /// assert!(Float::from(-6).gt_abs(&y));
46 /// assert!(Float::INFINITY.gt_abs(&y));
47 /// ```
48 fn partial_cmp_abs(&self, other: &GaussianInteger) -> Option<Ordering> {
49 if self.is_nan() {
50 None
51 } else if !self.is_finite() {
52 Some(Greater)
53 } else if other.imaginary == 0u32 {
54 self.partial_cmp_abs(&other.real)
55 } else if other.real == 0u32 {
56 self.partial_cmp_abs(&other.imaginary)
57 } else if !self.gt_abs(&other.real) || !self.gt_abs(&other.imaginary) {
58 Some(Less)
59 } else {
60 Rational::exact_from(self)
61 .abs_squared()
62 .partial_cmp(&other.abs_squared())
63 }
64 }
65}
66
67impl PartialOrdAbs<Float> for GaussianInteger {
68 /// Compares the absolute values of a [`GaussianInteger`] and a [`Float`].
69 ///
70 /// No [`GaussianInteger`] is comparable to NaN, and every [`GaussianInteger`] is smaller in
71 /// absolute value than $\infty$ and $-\infty$.
72 ///
73 /// # Worst-case complexity
74 /// $T(n) = O(n \log n \log\log n)$
75 ///
76 /// $M(n) = O(n \log n)$
77 ///
78 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
79 /// bits of `other` and of the real and imaginary parts of `self`.
80 ///
81 /// # Examples
82 /// ```
83 /// use malachite_base::num::basic::traits::Infinity;
84 /// use malachite_base::num::comparison::traits::{EqAbs, PartialOrdAbs};
85 /// use malachite_float::Float;
86 /// use malachite_nz::gaussian_integer::GaussianInteger;
87 /// use std::str::FromStr;
88 ///
89 /// let x = GaussianInteger::from_str("3+4i").unwrap();
90 /// assert!(x.eq_abs(&Float::from(-5)));
91 /// assert!(x.gt_abs(&Float::from(4)));
92 /// assert!(x.lt_abs(&Float::from(-6)));
93 /// assert!(x.lt_abs(&Float::INFINITY));
94 /// ```
95 #[inline]
96 fn partial_cmp_abs(&self, other: &Float) -> Option<Ordering> {
97 other.partial_cmp_abs(self).map(Ordering::reverse)
98 }
99}