arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/rns/src/ring/impl_u64/ring_switch.rs
rns/src/ring/impl_u64/ring_switch.rsRaw
 1use crate::poly::Poly;
 2use crate::ring::Ring;
 3
 4impl Ring<u64> {
 5    pub fn switch_degree<const NTT: bool>(
 6        &self,
 7        a: &Poly<u64>,
 8        buf: &mut Poly<u64>,
 9        b: &mut Poly<u64>,
10    ) {
11        let (n_in, n_out) = (a.n(), b.n());
12
13        if n_in > n_out {
14            let (gap_in, gap_out) = (1, n_in / n_out);
15            if NTT {
16                self.intt::<false>(&a, buf);
17                b.0.iter_mut()
18                    .step_by(gap_in)
19                    .zip(buf.0.iter().step_by(gap_out))
20                    .for_each(|(x_out, x_in)| *x_out = *x_in);
21                self.ntt_inplace::<false>(b);
22            } else {
23                b.0.iter_mut()
24                    .step_by(gap_in)
25                    .zip(a.0.iter().step_by(gap_out))
26                    .for_each(|(x_out, x_in)| *x_out = *x_in);
27            }
28        } else {
29            let gap: usize = n_out / n_in;
30
31            if NTT {
32                a.0.iter()
33                    .enumerate()
34                    .for_each(|(i, &c)| (0..gap).for_each(|j| b.0[i * gap + j] = c));
35            } else {
36                b.0.iter_mut()
37                    .step_by(gap)
38                    .zip(a.0.iter())
39                    .for_each(|(x_out, x_in)| *x_out = *x_in);
40            }
41        }
42    }
43}