malachite_float/float/comparison/partial_cmp_abs_gaussian_rational.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_q::Rational;
15use malachite_q::gaussian_rational::GaussianRational;
16
17impl PartialOrdAbs<GaussianRational> for Float {
18 /// Compares the absolute values of a [`Float`] and a [`GaussianRational`].
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 [`GaussianRational`]; $\infty$ and
24 /// $-\infty$ are greater in absolute value than any [`GaussianRational`].
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_q::gaussian_rational::GaussianRational;
40 /// use std::str::FromStr;
41 ///
42 /// let y = GaussianRational::from_str("3/2+2i").unwrap();
43 /// assert!(Float::from(2.5).eq_abs(&y));
44 /// assert!(Float::from(2).lt_abs(&y));
45 /// assert!(Float::from(-3).gt_abs(&y));
46 /// assert!(Float::INFINITY.gt_abs(&y));
47 /// ```
48 fn partial_cmp_abs(&self, other: &GaussianRational) -> 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 Some(
61 Rational::exact_from(self)
62 .abs_squared()
63 .cmp(&other.abs_squared()),
64 )
65 }
66 }
67}
68
69impl PartialOrdAbs<Float> for GaussianRational {
70 /// Compares the absolute values of a [`GaussianRational`] and a [`Float`].
71 ///
72 /// No [`GaussianRational`] is comparable to NaN, and every [`GaussianRational`] is smaller in
73 /// absolute value than $\infty$ and $-\infty$.
74 ///
75 /// # Worst-case complexity
76 /// $T(n) = O(n \log n \log\log n)$
77 ///
78 /// $M(n) = O(n \log n)$
79 ///
80 /// where $T$ is time, $M$ is additional memory, and $n$ is the maximum number of significant
81 /// bits of `other` and of the real and imaginary parts of `self`.
82 ///
83 /// # Examples
84 /// ```
85 /// use malachite_base::num::basic::traits::Infinity;
86 /// use malachite_base::num::comparison::traits::{EqAbs, PartialOrdAbs};
87 /// use malachite_float::Float;
88 /// use malachite_q::gaussian_rational::GaussianRational;
89 /// use std::str::FromStr;
90 ///
91 /// let x = GaussianRational::from_str("3/2+2i").unwrap();
92 /// assert!(x.eq_abs(&Float::from(2.5)));
93 /// assert!(x.gt_abs(&Float::from(2)));
94 /// assert!(x.lt_abs(&Float::from(-3)));
95 /// assert!(x.lt_abs(&Float::INFINITY));
96 /// ```
97 #[inline]
98 fn partial_cmp_abs(&self, other: &Float) -> Option<Ordering> {
99 other.partial_cmp_abs(self).map(Ordering::reverse)
100 }
101}