algebra/module/
suspension_module.rs

1use std::sync::Arc;
2
3use crate::module::{Module, ZeroModule};
4
5pub struct SuspensionModule<M: Module> {
6    inner: Arc<M>,
7    shift: i32,
8}
9
10impl<M: Module> SuspensionModule<M> {
11    pub fn new(inner: Arc<M>, shift: i32) -> Self {
12        Self { inner, shift }
13    }
14}
15
16impl<M: Module> std::fmt::Display for SuspensionModule<M> {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        if self.shift == 0 {
19            self.inner.fmt(f)
20        } else {
21            self.inner.fmt(f)?;
22            write!(f, "[{}]", self.shift)
23        }
24    }
25}
26
27impl<M: Module> Module for SuspensionModule<M> {
28    type Algebra = M::Algebra;
29
30    fn compute_basis(&self, degree: i32) {
31        self.inner.compute_basis(degree - self.shift);
32    }
33
34    fn is_unit(&self) -> bool {
35        self.shift == 0 && self.inner.is_unit()
36    }
37
38    fn prime(&self) -> fp::prime::ValidPrime {
39        self.inner.prime()
40    }
41
42    fn max_degree(&self) -> Option<i32> {
43        self.inner.max_degree().map(|x| x + self.shift)
44    }
45
46    fn max_generator_degree(&self) -> Option<i32> {
47        self.inner.max_degree().map(|x| x + self.shift)
48    }
49
50    fn total_dimension(&self) -> usize {
51        self.inner.total_dimension()
52    }
53
54    fn act(
55        &self,
56        result: fp::vector::FpSliceMut,
57        coeff: u32,
58        op_degree: i32,
59        op_index: usize,
60        input_degree: i32,
61        input: fp::vector::FpSlice,
62    ) {
63        self.inner.act(
64            result,
65            coeff,
66            op_degree,
67            op_index,
68            input_degree - self.shift,
69            input,
70        );
71    }
72
73    fn act_by_element(
74        &self,
75        result: fp::vector::FpSliceMut,
76        coeff: u32,
77        op_degree: i32,
78        op: fp::vector::FpSlice,
79        input_degree: i32,
80        input: fp::vector::FpSlice,
81    ) {
82        self.inner.act_by_element(
83            result,
84            coeff,
85            op_degree,
86            op,
87            input_degree - self.shift,
88            input,
89        );
90    }
91
92    fn act_by_element_on_basis(
93        &self,
94        result: fp::vector::FpSliceMut,
95        coeff: u32,
96        op_degree: i32,
97        op: fp::vector::FpSlice,
98        input_degree: i32,
99        input_index: usize,
100    ) {
101        self.inner.act_by_element_on_basis(
102            result,
103            coeff,
104            op_degree,
105            op,
106            input_degree - self.shift,
107            input_index,
108        );
109    }
110
111    fn element_to_string(&self, degree: i32, element: fp::vector::FpSlice) -> String {
112        self.inner.element_to_string(degree - self.shift, element)
113    }
114
115    fn algebra(&self) -> std::sync::Arc<Self::Algebra> {
116        self.inner.algebra()
117    }
118
119    fn min_degree(&self) -> i32 {
120        self.inner.min_degree() + self.shift
121    }
122
123    fn max_computed_degree(&self) -> i32 {
124        self.inner.max_computed_degree() + self.shift
125    }
126
127    fn dimension(&self, degree: i32) -> usize {
128        self.inner.dimension(degree - self.shift)
129    }
130
131    fn act_on_basis(
132        &self,
133        result: fp::vector::FpSliceMut,
134        coeff: u32,
135        op_degree: i32,
136        op_index: usize,
137        mod_degree: i32,
138        mod_index: usize,
139    ) {
140        self.inner.act_on_basis(
141            result,
142            coeff,
143            op_degree,
144            op_index,
145            mod_degree - self.shift,
146            mod_index,
147        );
148    }
149
150    fn basis_element_to_string(&self, degree: i32, idx: usize) -> String {
151        self.inner.basis_element_to_string(degree - self.shift, idx)
152    }
153}
154
155impl<M: ZeroModule> ZeroModule for SuspensionModule<M> {
156    fn zero_module(algebra: Arc<Self::Algebra>, min_degree: i32) -> Self {
157        let inner = Arc::new(M::zero_module(algebra, min_degree));
158        Self { inner, shift: 0 }
159    }
160}