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}