algebraeon_rings/structure/
modules.rs1use crate::{matrix::Matrix, structure::*};
2use algebraeon_sets::structure::*;
3use std::borrow::{Borrow, Cow};
4
5pub trait SemiModuleSignature<Ring: SemiRingSignature>: AdditiveMonoidSignature {
6 fn ring(&self) -> &Ring;
7 fn scalar_mul(&self, a: &Self::Set, x: &Ring::Set) -> Self::Set;
8}
9
10pub trait MetaSemiModule<Ring: SemiRingSignature>: MetaType
11where
12 Self::Signature: SemiModuleSignature<Ring>,
13{
14 fn scalar_mul(&self, x: &Ring::Set) -> Self {
15 Self::structure().scalar_mul(self, x)
16 }
17}
18impl<Ring: SemiRingSignature, T: MetaType> MetaSemiModule<Ring> for T where
19 Self::Signature: SemiModuleSignature<Ring>
20{
21}
22
23pub trait ModuleSignature<Ring: RingSignature>:
24 SemiModuleSignature<Ring> + AdditiveGroupSignature
25{
26}
27impl<Ring: RingSignature, Module: SemiModuleSignature<Ring> + AdditiveGroupSignature>
28 ModuleSignature<Ring> for Module
29{
30}
31
32pub trait FinitelyGeneratedModuleSignature<Ring: RingSignature>: ModuleSignature<Ring> {}
33
34pub trait FreeModuleSignature<Ring: RingSignature>: ModuleSignature<Ring> {
35 type Basis: SetSignature;
36
37 fn basis_set(&self) -> impl Borrow<Self::Basis>;
38
39 fn to_component<'a>(
40 &self,
41 b: &<Self::Basis as SetSignature>::Set,
42 v: &'a Self::Set,
43 ) -> Cow<'a, Ring::Set>;
44
45 fn from_component(&self, b: &<Self::Basis as SetSignature>::Set, r: &Ring::Set) -> Self::Set;
46}
47
48pub trait FinitelyFreeModuleSignature<Ring: RingSignature>:
49 FreeModuleSignature<Ring> + FinitelyGeneratedModuleSignature<Ring>
50where
51 Self::Basis: FiniteSetSignature,
52{
53 fn basis(&self) -> Vec<<Self::Basis as SetSignature>::Set> {
54 self.basis_set().borrow().list_all_elements()
55 }
56
57 fn rank(&self) -> usize {
58 self.basis_set().borrow().size()
59 }
60
61 fn basis_vecs(&self) -> Vec<Self::Set> {
63 let zero = self.ring().zero();
64 let one = self.ring().one();
65 (0..self.rank())
66 .map(|j| {
67 self.from_vec(
68 (0..self.rank())
69 .map(|i| if i == j { &one } else { &zero })
70 .collect(),
71 )
72 })
73 .collect()
74 }
75
76 fn to_vec(&self, a: &Self::Set) -> Vec<Ring::Set> {
77 self.basis()
78 .iter()
79 .map(|b| self.to_component(b, a).as_ref().clone())
80 .collect()
81 }
82
83 fn from_vec(&self, v: Vec<impl Borrow<Ring::Set>>) -> Self::Set {
84 let n = self.rank();
85 debug_assert_eq!(v.len(), n);
86 let basis = self.basis();
87 debug_assert_eq!(basis.len(), n);
88 let mut t = self.zero();
89 for i in 0..n {
90 self.add_mut(
91 &mut t,
92 &self.scalar_mul(
93 &self.from_component(&basis[i], &self.ring().one()),
94 v[i].borrow(),
95 ),
96 );
97 }
98 t
99 }
100
101 fn to_col(&self, a: &Self::Set) -> Matrix<Ring::Set> {
102 let basis = self.basis();
103 Matrix::construct(self.rank(), 1, |r, _c| {
104 self.to_component(&basis[r], a).into_owned()
105 })
106 }
107
108 fn from_col(&self, v: Matrix<Ring::Set>) -> Self::Set {
109 assert_eq!(v.cols(), 1);
110 assert_eq!(v.rows(), self.rank());
111 self.from_vec((0..self.rank()).map(|r| v.at(r, 0).unwrap()).collect())
112 }
113
114 fn to_row(&self, a: &Self::Set) -> Matrix<Ring::Set> {
115 self.to_col(a).transpose()
116 }
117
118 fn from_row(&self, v: Matrix<Ring::Set>) -> Self::Set {
119 self.from_col(v.transpose())
120 }
121}
122
123impl<Ring: RingSignature, Module: FreeModuleSignature<Ring>> FinitelyGeneratedModuleSignature<Ring>
124 for Module
125where
126 Module::Basis: FiniteSetSignature,
127{
128}
129
130impl<Ring: RingSignature, Module: FreeModuleSignature<Ring>> FinitelyFreeModuleSignature<Ring>
131 for Module
132where
133 Module::Basis: FiniteSetSignature,
134{
135}
136
137pub trait LinearTransformation<
138 Ring: RingSignature,
139 Domain: ModuleSignature<Ring>,
140 Range: ModuleSignature<Ring>,
141>: Function<Domain, Range>
142{
143}