poulpy/math/src/ring/impl_u64/ring_switch.rs
math/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}