poulpy/math/src/ring/impl_u64/sampling.rs
math/src/ring/impl_u64/sampling.rsRaw
1use crate::modulus::WordOps;
2use crate::poly::{Poly, PolyRNS};
3use crate::ring::{Ring, RingRNS};
4use num::ToPrimitive;
5use rand_distr::{Normal, Distribution};
6use sampling::source::Source;
7
8impl Ring<u64> {
9 pub fn fill_uniform(&self, source: &mut Source, a: &mut Poly<u64>) {
10 let max: u64 = self.modulus.q;
11 let mask: u64 = max.mask();
12 a.0.iter_mut()
13 .for_each(|a| *a = source.next_u64n(max, mask));
14 }
15
16 pub fn fill_dist_f64<T: Distribution<f64>>(&self, source: &mut Source, dist: T, bound: f64, a: &mut Poly<u64>) {
17 let max: u64 = self.modulus.q;
18 a.0.iter_mut()
19 .for_each(|a| {
20
21 let mut dist_f64: f64 = dist.sample(source);
22
23 while dist_f64.abs() > bound{
24 dist_f64 = dist.sample(source)
25 }
26
27 let dist_u64: u64 = (dist_f64+0.5).abs().to_u64().unwrap();
28 let sign: u64 = dist_f64.to_bits()>>63;
29
30 *a = (dist_u64 * sign) | (max-dist_u64)*(sign^1)
31 });
32 }
33}
34
35impl RingRNS<u64> {
36 pub fn fill_uniform(&self, source: &mut Source, a: &mut PolyRNS<u64>) {
37 self.0
38 .iter()
39 .enumerate()
40 .for_each(|(i, r)| r.fill_uniform(source, a.at_mut(i)));
41 }
42
43 pub fn fill_dist_f64<T: Distribution<f64>>(&self, source: &mut Source, dist: T, bound: f64, a: &mut PolyRNS<u64>) {
44 (0..a.n()).for_each(|j|{
45 let mut dist_f64: f64 = dist.sample(source);
46
47 while dist_f64.abs() > bound{
48 dist_f64 = dist.sample(source)
49 }
50
51 let dist_u64: u64 = (dist_f64+0.5).abs().to_u64().unwrap();
52 let sign: u64 = dist_f64.to_bits()>>63;
53
54 self.0.iter().enumerate().for_each(|(i, r)|{
55 a.at_mut(i).0[j] = (dist_u64 * sign) | (r.modulus.q-dist_u64)*(sign^1);
56 })
57 })
58 }
59}