algebraeon_rings/integer/
polynomial.rs

1use crate::{integer::*, polynomial::*};
2use std::rc::Rc;
3
4impl<B: BorrowedStructure<IntegerCanonicalStructure>> GreatestCommonDivisorSignature
5    for PolynomialStructure<IntegerCanonicalStructure, B>
6{
7    fn gcd(&self, x: &Self::Set, y: &Self::Set) -> Self::Set {
8        self.gcd_by_primitive_subresultant(x.clone(), y.clone())
9    }
10}
11
12impl<B: BorrowedStructure<IntegerCanonicalStructure>> FactoringMonoidSignature
13    for PolynomialStructure<IntegerCanonicalStructure, B>
14{
15    fn factor_unchecked(&self, p: &Self::Set) -> Factored<Polynomial<Integer>, Natural> {
16        use berlekamp_zassenhaus::factorize_by_berlekamp_zassenhaus_algorithm;
17        // self.factorize_by_kroneckers_method(p)
18        factorize_by_berlekamp_zassenhaus_algorithm(p.clone())
19    }
20}
21
22impl Polynomial<Integer> {
23    //https://en.wikipedia.org/wiki/Landau-Mignotte_bound
24    /// Return the Mignotte bound for the coefficients of any factor of $f(x)$: If
25    /// $$f(x) = \sum_{i=0}^n \lambda_i x^i$$
26    /// then the absolute value of the coefficients of any factor of \(f\) are bounded by
27    /// $${n \choose \lfloor n/2 \rfloor} \max \lbrace |\lambda_i| : i = 0, \dots, n \rbrace$$
28    pub fn mignotte_factor_coefficient_bound(&self) -> Option<Natural> {
29        let deg = self.degree()?;
30        let mut bound = Natural::ZERO;
31        for coeff in self.coeffs() {
32            bound += Abs::abs(coeff);
33        }
34        bound *= choose(Natural::from(deg), Natural::from(deg / 2));
35        Some(bound)
36    }
37
38    //https://en.wikipedia.org/wiki/Geometrical_properties_of_polynomial_roots#Lagrange's_and_Cauchy's_bounds
39    pub fn cauchys_root_bound(&self) -> Option<Rational> {
40        let d = self.degree()?;
41        if d == 0 {
42            None
43        } else {
44            Some(
45                Rational::ONE
46                    + (0..d)
47                        .map(|i| {
48                            Rational::from_integers(self.coeff(i).as_ref(), self.coeff(d).as_ref())
49                                .abs()
50                        })
51                        .max()
52                        .unwrap(),
53            )
54        }
55    }
56}
57
58// #[derive(Debug, Clone, PartialEq, Eq)]
59// struct IrreducibleIntegerMultiPolynomialStructure {}
60
61// impl Signature for IrreducibleIntegerMultiPolynomialStructure {}
62
63// impl SetSignature for IrreducibleIntegerMultiPolynomialStructure {
64//     type Set = MultiPolynomial<Integer>;
65
66//     fn is_element(&self, x: &Self::Set) -> bool {
67//         todo!()
68//     }
69// }
70
71// impl EqSignature for IrreducibleIntegerMultiPolynomialStructure {
72//     fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool {
73//         Integer::structure().multivariable_polynomials().equal(a, b)
74//     }
75// }
76
77// impl OrdSignature for IrreducibleIntegerMultiPolynomialStructure {
78//     fn cmp(&self, a: &Self::Set, b: &Self::Set) -> Ordering {
79//         todo!()
80//     }
81// }
82
83// impl<B: BorrowedStructure<IntegerCanonicalStructure> + 'static> UniqueFactorizationSignature
84//     for MultiPolynomialStructure<IntegerCanonicalStructure, B>
85// {
86//     type Irreducibles = IrreducibleIntegerMultiPolynomialStructure;
87
88//     type Factorizations<SelfB: BorrowedStructure<Self>> = FactoredRingElementStructure<Self, SelfB>;
89
90//     fn factorizations<'a>(&'a self) -> Self::Factorizations<&'a Self> {
91//         FactoredRingElementStructure::new(self)
92//     }
93
94//     fn into_factorizations(self) -> Self::Factorizations<Self> {
95//         FactoredRingElementStructure::new(self)
96//     }
97
98//     fn irreducibles(&self) -> impl std::borrow::Borrow<Self::Irreducibles> {
99//         IrreducibleIntegerMultiPolynomialStructure {}
100//     }
101// }
102
103// impl<B: BorrowedStructure<IntegerCanonicalStructure> + 'static> UniqueFactorizationSignature
104//     for MultiPolynomialStructure<PolynomialStructure<IntegerCanonicalStructure, B>, B>
105// {
106
107// }
108
109impl<B: BorrowedStructure<IntegerCanonicalStructure> + 'static> FactoringMonoidSignature
110    for MultiPolynomialStructure<IntegerCanonicalStructure, B>
111{
112    fn factor_unchecked(&self, p: &Self::Set) -> Factored<Self::Set, Natural> {
113        self.factor_by_yuns_and_kroneckers_inductively(
114            Rc::new(Integer::factor),
115            Rc::new(Polynomial::factor),
116            p,
117        )
118    }
119}
120
121#[cfg(test)]
122mod tests {
123    use algebraeon_sets::structure::EqSignature;
124    use berlekamp_zassenhaus::*;
125
126    use crate::structure::IntoErgonomic;
127
128    use super::*;
129
130    #[test]
131    fn test_zassenhaus_against_kroneckers() {
132        let x = &Polynomial::<Integer>::var().into_ergonomic();
133
134        let f =
135            ((2 * x.pow(3) + 6 * x.pow(2) - 4) * (6 * x.pow(5) + 7 * x.pow(4) - 4)).into_verbose();
136        let fs = Integer::structure()
137            .polynomials()
138            .factorize_by_kroneckers_method(f.clone(), Integer::factor);
139        println!("{}", f);
140        // println!("{}", f.clone().factorize_by_kroneckers_method().unwrap());
141        // println!("{}", f.clone().factorize_by_zassenhaus_algorithm().unwrap());
142        assert!(Polynomial::<Integer>::structure().factorizations().equal(
143            &fs,
144            &factorize_by_berlekamp_zassenhaus_algorithm_naive(f.clone())
145        ));
146        assert!(
147            Polynomial::<Integer>::structure()
148                .factorizations()
149                .equal(&fs, &factorize_by_berlekamp_zassenhaus_algorithm(f.clone()))
150        );
151
152        let f = (49 * x.pow(2) - 10000).into_verbose();
153        let fs = Integer::structure()
154            .polynomials()
155            .factorize_by_kroneckers_method(f.clone(), Integer::factor);
156        println!("{}", f);
157        // println!("{}", f.clone().factorize_by_kroneckers_method().unwrap());
158        // println!("{}", f.clone().factorize_by_zassenhaus_algorithm().unwrap());
159        assert!(Polynomial::<Integer>::structure().factorizations().equal(
160            &fs,
161            &factorize_by_berlekamp_zassenhaus_algorithm_naive(f.clone())
162        ));
163        assert!(
164            Polynomial::<Integer>::structure()
165                .factorizations()
166                .equal(&fs, &factorize_by_berlekamp_zassenhaus_algorithm(f.clone()))
167        );
168    }
169}