algebra/module/homomorphism/
quotient_homomorphism.rs

1use std::sync::Arc;
2
3use fp::vector::{FpSliceMut, FpVector};
4
5use crate::module::{Module, QuotientModule, homomorphism::ModuleHomomorphism};
6
7pub struct QuotientHomomorphism<F: ModuleHomomorphism> {
8    f: Arc<F>,
9    s: Arc<QuotientModule<F::Source>>,
10    t: Arc<QuotientModule<F::Target>>,
11}
12
13impl<F: ModuleHomomorphism> QuotientHomomorphism<F> {
14    pub fn new(
15        f: Arc<F>,
16        s: Arc<QuotientModule<F::Source>>,
17        t: Arc<QuotientModule<F::Target>>,
18    ) -> Self {
19        Self { f, s, t }
20    }
21}
22
23impl<F: ModuleHomomorphism> ModuleHomomorphism for QuotientHomomorphism<F> {
24    type Source = QuotientModule<F::Source>;
25    type Target = QuotientModule<F::Target>;
26
27    fn source(&self) -> Arc<Self::Source> {
28        Arc::clone(&self.s)
29    }
30
31    fn target(&self) -> Arc<Self::Target> {
32        Arc::clone(&self.t)
33    }
34
35    fn degree_shift(&self) -> i32 {
36        self.f.degree_shift()
37    }
38
39    fn apply_to_basis_element(
40        &self,
41        result: FpSliceMut,
42        coeff: u32,
43        input_degree: i32,
44        input_idx: usize,
45    ) {
46        let output_degree = input_degree - self.degree_shift();
47        let mut result_ = FpVector::new(self.prime(), self.t.module.dimension(output_degree));
48        self.f.apply_to_basis_element(
49            result_.as_slice_mut(),
50            coeff,
51            input_degree,
52            self.s.basis_list[input_degree][input_idx],
53        );
54
55        self.t.reduce(output_degree, result_.as_slice_mut());
56        self.t
57            .old_basis_to_new(output_degree, result, result_.as_slice());
58    }
59}
60
61pub struct QuotientHomomorphismSource<F: ModuleHomomorphism> {
62    f: Arc<F>,
63    s: Arc<QuotientModule<F::Source>>,
64}
65
66impl<F: ModuleHomomorphism> QuotientHomomorphismSource<F> {
67    pub fn new(f: Arc<F>, s: Arc<QuotientModule<F::Source>>) -> Self {
68        Self { f, s }
69    }
70}
71
72impl<F: ModuleHomomorphism> ModuleHomomorphism for QuotientHomomorphismSource<F> {
73    type Source = QuotientModule<F::Source>;
74    type Target = F::Target;
75
76    fn source(&self) -> Arc<Self::Source> {
77        Arc::clone(&self.s)
78    }
79
80    fn target(&self) -> Arc<Self::Target> {
81        self.f.target()
82    }
83
84    fn degree_shift(&self) -> i32 {
85        self.f.degree_shift()
86    }
87
88    fn apply_to_basis_element(
89        &self,
90        result: FpSliceMut,
91        coeff: u32,
92        input_degree: i32,
93        input_idx: usize,
94    ) {
95        self.f.apply_to_basis_element(
96            result,
97            coeff,
98            input_degree,
99            self.s.basis_list[input_degree][input_idx],
100        );
101    }
102}