algebraeon_rings/finite_fields/
extension.rs1use crate::{polynomial::*, structure::*};
2use algebraeon_nzq::*;
3use algebraeon_sets::structure::*;
4use itertools::Itertools;
5
6use super::modulo::ModuloCanonicalStructure;
7
8impl<
9 FS: FiniteFieldSignature,
10 FSB: BorrowedStructure<FS>,
11 FSPB: BorrowedStructure<PolynomialStructure<FS, FSB>>,
12 B: BorrowedStructure<PolynomialQuotientRingStructure<FS, FSB, FSPB, true>>,
13> CountableSetSignature
14 for MultiplicativeMonoidUnitsStructure<PolynomialQuotientRingStructure<FS, FSB, FSPB, true>, B>
15{
16 fn generate_all_elements(&self) -> impl Iterator<Item = Self::Set> + Clone {
17 self.list_all_elements().into_iter()
18 }
19}
20
21impl<
22 FS: FiniteFieldSignature,
23 FSB: BorrowedStructure<FS>,
24 FSPB: BorrowedStructure<PolynomialStructure<FS, FSB>>,
25 B: BorrowedStructure<PolynomialQuotientRingStructure<FS, FSB, FSPB, true>>,
26> FiniteSetSignature
27 for MultiplicativeMonoidUnitsStructure<PolynomialQuotientRingStructure<FS, FSB, FSPB, true>, B>
28{
29 fn list_all_elements(&self) -> Vec<Self::Set> {
30 let mut all_base_elements = vec![self.monoid().ring().coeff_ring().zero()];
31 for unit in self.monoid().ring().coeff_ring().all_units() {
32 all_base_elements.push(unit);
33 }
34
35 let mut all_base_elements_product = (0..self.monoid().degree())
36 .map(|_| &all_base_elements)
37 .multi_cartesian_product();
38
39 all_base_elements_product.next().unwrap();
41
42 all_base_elements_product
44 .map(|coeffs| {
45 self.monoid().ring().reduce_poly(Polynomial::from_coeffs(
46 coeffs.into_iter().cloned().collect(),
47 ))
48 })
49 .collect()
50 }
51}
52
53impl<
54 FS: FiniteFieldSignature,
55 FSB: BorrowedStructure<FS>,
56 FSPB: BorrowedStructure<PolynomialStructure<FS, FSB>>,
57> FiniteFieldSignature for PolynomialQuotientRingStructure<FS, FSB, FSPB, true>
58{
59 fn characteristic_and_power(&self) -> (Natural, Natural) {
60 let (p, t) = self.ring().coeff_ring().characteristic_and_power();
61 let d = Natural::from(self.degree());
62 (p, d * t)
63 }
64}
65
66pub fn new_finite_field_extension<FS: FiniteFieldSignature>(
67 finite_field: FS,
68 poly: Polynomial<FS::Set>,
69) -> PolynomialQuotientRingStructure<FS, FS, PolynomialStructure<FS, FS>, true>
70where
71 PolynomialStructure<FS, FS>: FactoringMonoidSignature<Set = Polynomial<FS::Set>>,
72{
73 finite_field
74 .into_polynomials()
75 .into_quotient_field_unchecked(poly)
76}
77
78#[allow(unused)]
79pub(crate) fn f9() -> PolynomialQuotientRingStructure<
80 ModuloCanonicalStructure<3>,
81 ModuloCanonicalStructure<3>,
82 PolynomialStructure<ModuloCanonicalStructure<3>, ModuloCanonicalStructure<3>>,
83 true,
84> {
85 use crate::finite_fields::modulo::*;
86 new_finite_field_extension::<ModuloCanonicalStructure<3>>(
87 Modulo::<3>::structure(),
88 Polynomial::from_coeffs(vec![1, 1, 2]),
89 )
90}
91
92#[cfg(test)]
93mod tests {
94
95 use super::*;
96
97 #[test]
98 fn test_f9_elements() {
99 let f9 = f9();
100
101 let (p, t) = f9.characteristic_and_power();
102 assert_eq!(p, 3u32.into());
103 assert_eq!(t, 2u32.into());
104
105 let mut c = 0;
106 for x in f9.list_all_elements() {
107 println!("{:?}", x);
108 c += 1;
109 }
110 assert_eq!(c, 9);
111 }
112}