arnaucube
arnaucube/poulpyPublic Self-hosted repository
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}