algebra/module/
suspension_module.rs1use 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}