algebraeon_rings/matrix/
primitive.rs1use super::*;
2
3impl<RS: GreatestCommonDivisorSignature, RSB: BorrowedStructure<RS>> MatrixStructure<RS, RSB> {
4 pub fn factor_primitive(&self, mut mat: Matrix<RS::Set>) -> Option<(RS::Set, Matrix<RS::Set>)> {
5 let entries = mat.entries_list();
6 let g = self.ring().gcd_list(entries);
7 if self.ring().is_zero(&g) {
8 None
9 } else {
10 for r in 0..mat.rows() {
11 for c in 0..mat.cols() {
12 *mat.at_mut(r, c).unwrap() =
13 self.ring().try_divide(mat.at(r, c).unwrap(), &g).unwrap();
14 }
15 }
16 Some((g, mat))
17 }
18 }
19
20 pub fn primitive_part(&self, mat: Matrix<RS::Set>) -> Option<Matrix<RS::Set>> {
21 self.factor_primitive(mat).map(|(_unit, prim)| prim)
22 }
23}
24
25pub fn factor_primitive_fof<
26 Ring: GreatestCommonDivisorSignature,
27 Field: FieldSignature,
28 Fof: FieldOfFractionsInclusion<Ring, Field>,
29>(
30 fof_inclusion: &Fof,
31 mat: &Matrix<Field::Set>,
32) -> (Field::Set, Matrix<Ring::Set>) {
33 let ring = fof_inclusion.domain();
34 let field = fof_inclusion.range();
35 let mat_ring = MatrixStructure::new(ring.clone());
36
37 let div = ring.lcm_list(
38 mat.entries_list()
39 .into_iter()
40 .map(|c| fof_inclusion.denominator(c))
41 .collect(),
42 );
43
44 let (mul, prim) = mat_ring
45 .factor_primitive(mat.apply_map(|c| {
46 fof_inclusion
47 .try_preimage(&field.mul(&fof_inclusion.image(&div), c))
48 .unwrap()
49 }))
50 .unwrap();
51
52 (
53 field
54 .try_divide(&fof_inclusion.image(&mul), &fof_inclusion.image(&div))
55 .unwrap(),
56 prim,
57 )
58}
59
60impl<R: MetaType> Matrix<R>
61where
62 R::Signature: GreatestCommonDivisorSignature,
63{
64 pub fn factor_primitive(self) -> Option<(R, Matrix<R>)> {
65 Self::structure().factor_primitive(self)
66 }
67
68 pub fn primitive_part(self) -> Option<Matrix<R>> {
69 Self::structure().primitive_part(self)
70 }
71}
72
73impl<Field: MetaType> Matrix<Field>
74where
75 Field::Signature: FieldSignature,
76 PrincipalIntegerMap<Field::Signature, Field::Signature>:
77 FieldOfFractionsInclusion<IntegerCanonicalStructure, Field::Signature>,
78{
79 pub fn factor_primitive_fof(&self) -> (Field, Matrix<Integer>) {
80 factor_primitive_fof(&PrincipalIntegerMap::new(Field::structure()), self)
81 }
82}