poulpy/math/src/ring/impl_u64/packing.rs
math/src/ring/impl_u64/packing.rsRaw
1use std::collections::HashMap;
2use crate::poly::Poly;
3use crate::ring::Ring;
4use crate::modulus::ONCE;
5
6
7impl Ring<u64>{
8
9 // Generates a vector storing {X^{2^0}, X^{2^1}, .., X^{2^log_n}}.
10 pub fn gen_x_pow_2<const NTT: bool, const INV: bool>(&self, log_n: usize) -> Vec<Poly<u64>>{
11 let mut x_pow: Vec<Poly<u64>> = Vec::<Poly<u64>>::with_capacity(log_n);
12
13 (0..log_n).for_each(|i|{
14 let mut idx: usize = 1<<i;
15
16 if INV{
17 idx = self.n() - idx;
18 }
19
20 x_pow.push(self.new_poly());
21
22 if i == 0{
23 x_pow[i].0[idx] = self.modulus.montgomery.one();
24 self.ntt_inplace::<false>(&mut x_pow[i]);
25 }else{
26 let (left, right) = x_pow.split_at_mut(i);
27 self.a_mul_b_montgomery_into_c::<ONCE>(&left[i-1], &left[i-1], &mut right[0]);
28 }
29 });
30
31 if INV{
32 self.a_neg_into_a::<1, ONCE>(&mut x_pow[0]);
33 }
34
35 if !NTT{
36 x_pow.iter_mut().for_each(|x| self.intt_inplace::<false>(x));
37 }
38
39 x_pow
40 }
41
42 pub fn pack<const ZEROGARBAGE: bool, const NTT: bool>(&self, polys: HashMap<Poly<u64>, usize>, log_gap: usize) -> Poly<u64>{
43
44 let log_n = self.log_n();
45 let log_start = log_n - log_gap;
46 let log_end = log_n;
47
48 /*
49 if !ZEROGARBAGE{
50 if gap > 0 {
51 log_end -= log_gap;
52 }
53 }
54 */
55
56 let n_inv = self.modulus.inv(1<<(log_end - log_start));
57
58 Poly::<u64>::default()
59 }
60}