malachite_q/arithmetic/
abs_diff.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MP Library.
4//
5//      Copyright © 1991-2018, 2020 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::Rational;
14use malachite_base::num::arithmetic::traits::{Abs, AbsAssign, AbsDiff, AbsDiffAssign};
15
16impl AbsDiff<Self> for Rational {
17    type Output = Self;
18
19    /// Computes the absolute value of the difference between two [`Rational`]s, taking both by
20    /// value.
21    ///
22    /// $$
23    /// f(x, y) = |x - y|.
24    /// $$
25    ///
26    /// # Worst-case complexity
27    /// $T(n) = O(n (\log n)^2 \log\log n)$
28    ///
29    /// $M(n) = O(n \log n)$
30    ///
31    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
32    /// other.significant_bits())`.
33    ///
34    /// # Examples
35    /// ```
36    /// use malachite_base::num::arithmetic::traits::AbsDiff;
37    /// use malachite_base::num::basic::traits::OneHalf;
38    /// use malachite_q::Rational;
39    ///
40    /// assert_eq!(Rational::ONE_HALF.abs_diff(Rational::ONE_HALF), 0);
41    /// assert_eq!(
42    ///     Rational::from_signeds(22, 7)
43    ///         .abs_diff(Rational::from_signeds(99, 100))
44    ///         .to_string(),
45    ///     "1507/700"
46    /// );
47    /// assert_eq!(
48    ///     Rational::from_signeds(22, 7)
49    ///         .abs_diff(Rational::from_signeds(99, 100))
50    ///         .to_string(),
51    ///     "1507/700"
52    /// );
53    /// ```
54    #[inline]
55    fn abs_diff(self, other: Self) -> Self {
56        (self - other).abs()
57    }
58}
59
60impl AbsDiff<&Self> for Rational {
61    type Output = Self;
62
63    /// Computes the absolute value of the difference between two [`Rational`]s, taking the first by
64    /// value and the second by reference.
65    ///
66    /// $$
67    /// f(x, y) = |x - y|.
68    /// $$
69    ///
70    /// # Worst-case complexity
71    /// $T(n) = O(n (\log n)^2 \log\log n)$
72    ///
73    /// $M(n) = O(n \log n)$
74    ///
75    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
76    /// other.significant_bits())`.
77    ///
78    /// # Examples
79    /// ```
80    /// use malachite_base::num::arithmetic::traits::AbsDiff;
81    /// use malachite_base::num::basic::traits::OneHalf;
82    /// use malachite_q::Rational;
83    ///
84    /// assert_eq!(Rational::ONE_HALF.abs_diff(&Rational::ONE_HALF), 0);
85    /// assert_eq!(
86    ///     Rational::from_signeds(22, 7)
87    ///         .abs_diff(&Rational::from_signeds(99, 100))
88    ///         .to_string(),
89    ///     "1507/700"
90    /// );
91    /// assert_eq!(
92    ///     Rational::from_signeds(22, 7)
93    ///         .abs_diff(&Rational::from_signeds(99, 100))
94    ///         .to_string(),
95    ///     "1507/700"
96    /// );
97    /// ```
98    #[inline]
99    fn abs_diff(self, other: &Self) -> Self {
100        (self - other).abs()
101    }
102}
103
104impl AbsDiff<Rational> for &Rational {
105    type Output = Rational;
106
107    /// Computes the absolute value of the difference between two [`Rational`]s, taking the first by
108    /// reference and the second by value.
109    ///
110    /// $$
111    /// f(x, y) = |x - y|.
112    /// $$
113    ///
114    /// # Worst-case complexity
115    /// $T(n) = O(n (\log n)^2 \log\log n)$
116    ///
117    /// $M(n) = O(n \log n)$
118    ///
119    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
120    /// other.significant_bits())`.
121    ///
122    /// # Examples
123    /// ```
124    /// use malachite_base::num::arithmetic::traits::AbsDiff;
125    /// use malachite_base::num::basic::traits::OneHalf;
126    /// use malachite_q::Rational;
127    ///
128    /// assert_eq!(Rational::ONE_HALF.abs_diff(Rational::ONE_HALF), 0);
129    /// assert_eq!(
130    ///     (&Rational::from_signeds(22, 7))
131    ///         .abs_diff(Rational::from_signeds(99, 100))
132    ///         .to_string(),
133    ///     "1507/700"
134    /// );
135    /// assert_eq!(
136    ///     (&Rational::from_signeds(22, 7))
137    ///         .abs_diff(Rational::from_signeds(99, 100))
138    ///         .to_string(),
139    ///     "1507/700"
140    /// );
141    /// ```
142    #[inline]
143    fn abs_diff(self, other: Rational) -> Rational {
144        (self - other).abs()
145    }
146}
147
148impl AbsDiff<&Rational> for &Rational {
149    type Output = Rational;
150
151    /// Computes the absolute value of the difference between two [`Rational`]s, taking both by
152    /// reference.
153    ///
154    /// $$
155    /// f(x, y) = |x - y|.
156    /// $$
157    ///
158    /// # Worst-case complexity
159    /// $T(n) = O(n (\log n)^2 \log\log n)$
160    ///
161    /// $M(n) = O(n \log n)$
162    ///
163    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
164    /// other.significant_bits())`.
165    ///
166    /// # Examples
167    /// ```
168    /// use malachite_base::num::arithmetic::traits::AbsDiff;
169    /// use malachite_base::num::basic::traits::OneHalf;
170    /// use malachite_q::Rational;
171    ///
172    /// assert_eq!(Rational::ONE_HALF.abs_diff(Rational::ONE_HALF), 0);
173    /// assert_eq!(
174    ///     (&Rational::from_signeds(22, 7))
175    ///         .abs_diff(&Rational::from_signeds(99, 100))
176    ///         .to_string(),
177    ///     "1507/700"
178    /// );
179    /// assert_eq!(
180    ///     (&Rational::from_signeds(22, 7))
181    ///         .abs_diff(&Rational::from_signeds(99, 100))
182    ///         .to_string(),
183    ///     "1507/700"
184    /// );
185    /// ```
186    #[inline]
187    fn abs_diff(self, other: &Rational) -> Rational {
188        (self - other).abs()
189    }
190}
191
192impl AbsDiffAssign<Self> for Rational {
193    /// Subtracts a [`Rational`] by another [`Rational`] in place and takes the absolute value,
194    /// taking the [`Rational`] on the right-hand side by value.
195    ///
196    /// $$
197    /// x \gets |x - y|.
198    /// $$
199    ///
200    /// # Worst-case complexity
201    /// $T(n) = O(n (\log n)^2 \log\log n)$
202    ///
203    /// $M(n) = O(n \log n)$
204    ///
205    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
206    /// other.significant_bits())`.
207    ///
208    /// # Panics
209    /// Panics if `other` is greater than `self`.
210    ///
211    /// # Examples
212    /// ```
213    /// use malachite_base::num::arithmetic::traits::AbsDiffAssign;
214    /// use malachite_base::num::basic::traits::OneHalf;
215    /// use malachite_q::Rational;
216    ///
217    /// let mut x = Rational::ONE_HALF;
218    /// x.abs_diff_assign(Rational::ONE_HALF);
219    /// assert_eq!(x, 0);
220    ///
221    /// let mut x = Rational::from_signeds(22, 7);
222    /// x.abs_diff_assign(Rational::from_signeds(99, 100));
223    /// assert_eq!(x.to_string(), "1507/700");
224    ///
225    /// let mut x = Rational::from_signeds(99, 100);
226    /// x.abs_diff_assign(Rational::from_signeds(22, 7));
227    /// assert_eq!(x.to_string(), "1507/700");
228    /// ```
229    #[inline]
230    fn abs_diff_assign(&mut self, other: Self) {
231        *self -= other;
232        self.abs_assign();
233    }
234}
235
236impl<'a> AbsDiffAssign<&'a Self> for Rational {
237    /// Subtracts a [`Rational`] by another [`Rational`] in place and takes the absolute value,
238    /// taking the [`Rational`] on the right-hand side by reference.
239    ///
240    /// $$
241    /// x \gets |x - y|.
242    /// $$
243    ///
244    /// # Worst-case complexity
245    /// $T(n) = O(n (\log n)^2 \log\log n)$
246    ///
247    /// $M(n) = O(n \log n)$
248    ///
249    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
250    /// other.significant_bits())`.
251    ///
252    /// # Panics
253    /// Panics if `other` is greater than `self`.
254    ///
255    /// # Examples
256    /// ```
257    /// use malachite_base::num::arithmetic::traits::AbsDiffAssign;
258    /// use malachite_base::num::basic::traits::OneHalf;
259    /// use malachite_q::Rational;
260    ///
261    /// let mut x = Rational::ONE_HALF;
262    /// x.abs_diff_assign(&Rational::ONE_HALF);
263    /// assert_eq!(x, 0);
264    ///
265    /// let mut x = Rational::from_signeds(22, 7);
266    /// x.abs_diff_assign(&Rational::from_signeds(99, 100));
267    /// assert_eq!(x.to_string(), "1507/700");
268    ///
269    /// let mut x = Rational::from_signeds(99, 100);
270    /// x.abs_diff_assign(&Rational::from_signeds(22, 7));
271    /// assert_eq!(x.to_string(), "1507/700");
272    /// ```
273    #[inline]
274    fn abs_diff_assign(&mut self, other: &'a Self) {
275        *self -= other;
276        self.abs_assign();
277    }
278}