Skip to main content

malachite_base/unsigned_polynomial/arithmetic/
exponent_gcd.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::num::basic::unsigneds::PrimitiveUnsigned;
10use crate::polynomial::{ExponentGcd, slice_exponent_gcd};
11use crate::unsigned_polynomial::UnsignedPolynomial;
12
13impl<T: PrimitiveUnsigned> ExponentGcd for UnsignedPolynomial<T> {
14    /// Computes the greatest common divisor of the exponents at which an [`UnsignedPolynomial`] has
15    /// nonzero coefficients.
16    ///
17    /// $$
18    /// f(p) = \gcd \\{i : p_i \neq 0\\}.
19    /// $$
20    ///
21    /// When the polynomial is not constant, this is the largest $k$ such that $p(x) = q(x^k)$ for
22    /// some polynomial $q$, and
23    /// [`compose_power_of_x`](crate::polynomial::ComposePowerOfX::compose_power_of_x) with $k$
24    /// recovers $p$ from $q$. A constant polynomial, including zero, gives 0.
25    ///
26    /// # Worst-case complexity
27    /// $T(n) = O(n)$
28    ///
29    /// $M(n) = O(1)$
30    ///
31    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.len()`.
32    ///
33    /// # Examples
34    /// ```
35    /// use core::str::FromStr;
36    /// use malachite_base::num::basic::traits::Zero;
37    /// use malachite_base::polynomial::ExponentGcd;
38    /// use malachite_base::unsigned_polynomial::UnsignedPolynomial;
39    ///
40    /// assert_eq!(
41    ///     UnsignedPolynomial::<u8>::from_str("x^6+2*x^3+1")
42    ///         .unwrap()
43    ///         .exponent_gcd(),
44    ///     3
45    /// );
46    /// assert_eq!(
47    ///     UnsignedPolynomial::<u8>::from_str("x^4+x")
48    ///         .unwrap()
49    ///         .exponent_gcd(),
50    ///     1
51    /// );
52    /// assert_eq!(
53    ///     UnsignedPolynomial::<u8>::from_str("x^4")
54    ///         .unwrap()
55    ///         .exponent_gcd(),
56    ///     4
57    /// );
58    /// assert_eq!(
59    ///     UnsignedPolynomial::<u8>::from_str("5")
60    ///         .unwrap()
61    ///         .exponent_gcd(),
62    ///     0
63    /// );
64    /// assert_eq!(UnsignedPolynomial::<u8>::ZERO.exponent_gcd(), 0);
65    /// ```
66    ///
67    /// This is equivalent to `nmod_poly_deflation` from `nmod_poly/deflation.c`, FLINT 3.6.0,
68    /// except that a constant gives 0 rather than 1.
69    #[inline]
70    fn exponent_gcd(&self) -> u64 {
71        slice_exponent_gcd(&self.coefficients, |c| *c == T::ZERO)
72    }
73}