algebraeon_rings/structure/
modules.rs

1use 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    /// The elementary basis vectors
62    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}