malachite_q/arithmetic/
square.rs

1// Copyright © 2025 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::Rational;
10use malachite_base::num::arithmetic::traits::{Square, SquareAssign};
11
12impl Square for Rational {
13    type Output = Self;
14
15    /// Squares a [`Rational`], taking it by value.
16    ///
17    /// $$
18    /// f(x) = x^2.
19    /// $$
20    ///
21    /// # Worst-case complexity
22    /// $T(n) = O(n \log n \log\log n)$
23    ///
24    /// $M(n) = O(n \log n)$
25    ///
26    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
27    ///
28    /// # Examples
29    /// ```
30    /// use malachite_base::num::arithmetic::traits::Square;
31    /// use malachite_base::num::basic::traits::Zero;
32    /// use malachite_q::Rational;
33    ///
34    /// assert_eq!(Rational::ZERO.square(), 0);
35    /// assert_eq!(Rational::from_signeds(22, 7).square().to_string(), "484/49");
36    /// assert_eq!(
37    ///     Rational::from_signeds(-22, 7).square().to_string(),
38    ///     "484/49"
39    /// );
40    /// ```
41    #[inline]
42    fn square(mut self) -> Self {
43        self.square_assign();
44        self
45    }
46}
47
48impl Square for &Rational {
49    type Output = Rational;
50
51    /// Squares a [`Rational`], taking it by reference.
52    ///
53    /// $$
54    /// f(x) = x^2.
55    /// $$
56    ///
57    /// # Worst-case complexity
58    /// $T(n) = O(n \log n \log\log n)$
59    ///
60    /// $M(n) = O(n \log n)$
61    ///
62    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
63    ///
64    /// # Examples
65    /// ```
66    /// use malachite_base::num::arithmetic::traits::Square;
67    /// use malachite_base::num::basic::traits::Zero;
68    /// use malachite_q::Rational;
69    ///
70    /// assert_eq!((&Rational::ZERO).square(), 0);
71    /// assert_eq!(
72    ///     (&Rational::from_signeds(22, 7)).square().to_string(),
73    ///     "484/49"
74    /// );
75    /// assert_eq!(
76    ///     (&Rational::from_signeds(-22, 7)).square().to_string(),
77    ///     "484/49"
78    /// );
79    /// ```
80    #[inline]
81    fn square(self) -> Rational {
82        Rational {
83            sign: true,
84            numerator: (&self.numerator).square(),
85            denominator: (&self.denominator).square(),
86        }
87    }
88}
89
90impl SquareAssign for Rational {
91    /// Squares a [`Rational`] in place.
92    ///
93    /// $$
94    /// x \gets x^2.
95    /// $$
96    ///
97    /// # Worst-case complexity
98    /// $T(n) = O(n \log n \log\log n)$
99    ///
100    /// $M(n) = O(n \log n)$
101    ///
102    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.significant_bits()`.
103    ///
104    /// # Examples
105    /// ```
106    /// use malachite_base::num::arithmetic::traits::SquareAssign;
107    /// use malachite_base::num::basic::traits::Zero;
108    /// use malachite_q::Rational;
109    ///
110    /// let mut x = Rational::ZERO;
111    /// x.square_assign();
112    /// assert_eq!(x, 0);
113    ///
114    /// let mut x = Rational::from_signeds(22, 7);
115    /// x.square_assign();
116    /// assert_eq!(x.to_string(), "484/49");
117    ///
118    /// let mut x = Rational::from_signeds(-22, 7);
119    /// x.square_assign();
120    /// assert_eq!(x.to_string(), "484/49");
121    /// ```
122    fn square_assign(&mut self) {
123        self.sign = true;
124        self.numerator.square_assign();
125        self.denominator.square_assign();
126    }
127}