poulpy/poulpy-hal/src/reference/znx/normalization.rs
poulpy-hal/src/reference/znx/normalization.rsRaw
1use itertools::izip;
2
3#[inline(always)]
4pub fn get_digit(basek: usize, x: i64) -> i64 {
5 (x << (u64::BITS - basek as u32)) >> (u64::BITS - basek as u32)
6}
7
8#[inline(always)]
9pub fn get_carry(basek: usize, x: i64, digit: i64) -> i64 {
10 (x.wrapping_sub(digit)) >> basek
11}
12
13#[inline(always)]
14pub fn znx_normalize_first_step_carry_only_ref(basek: usize, lsh: usize, x: &[i64], carry: &mut [i64]) {
15 #[cfg(debug_assertions)]
16 {
17 assert!(x.len() <= carry.len());
18 assert!(lsh < basek);
19 }
20
21 if lsh == 0 {
22 x.iter().zip(carry.iter_mut()).for_each(|(x, c)| {
23 *c = get_carry(basek, *x, get_digit(basek, *x));
24 });
25 } else {
26 let basek_lsh: usize = basek - lsh;
27 x.iter().zip(carry.iter_mut()).for_each(|(x, c)| {
28 *c = get_carry(basek_lsh, *x, get_digit(basek_lsh, *x));
29 });
30 }
31}
32
33#[inline(always)]
34pub fn znx_normalize_first_step_inplace_ref(basek: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
35 #[cfg(debug_assertions)]
36 {
37 assert!(x.len() <= carry.len());
38 assert!(lsh < basek);
39 }
40
41 if lsh == 0 {
42 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
43 let digit: i64 = get_digit(basek, *x);
44 *c = get_carry(basek, *x, digit);
45 *x = digit;
46 });
47 } else {
48 let basek_lsh: usize = basek - lsh;
49 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
50 let digit: i64 = get_digit(basek_lsh, *x);
51 *c = get_carry(basek_lsh, *x, digit);
52 *x = digit << lsh;
53 });
54 }
55}
56
57#[inline(always)]
58pub fn znx_normalize_first_step_ref(basek: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
59 #[cfg(debug_assertions)]
60 {
61 assert_eq!(x.len(), a.len());
62 assert!(x.len() <= carry.len());
63 assert!(lsh < basek);
64 }
65
66 if lsh == 0 {
67 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
68 let digit: i64 = get_digit(basek, *a);
69 *c = get_carry(basek, *a, digit);
70 *x = digit;
71 });
72 } else {
73 let basek_lsh: usize = basek - lsh;
74 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
75 let digit: i64 = get_digit(basek_lsh, *a);
76 *c = get_carry(basek_lsh, *a, digit);
77 *x = digit << lsh;
78 });
79 }
80}
81
82#[inline(always)]
83pub fn znx_normalize_middle_step_carry_only_ref(basek: usize, lsh: usize, x: &[i64], carry: &mut [i64]) {
84 #[cfg(debug_assertions)]
85 {
86 assert!(x.len() <= carry.len());
87 assert!(lsh < basek);
88 }
89 if lsh == 0 {
90 x.iter().zip(carry.iter_mut()).for_each(|(x, c)| {
91 let digit: i64 = get_digit(basek, *x);
92 let carry: i64 = get_carry(basek, *x, digit);
93 let digit_plus_c: i64 = digit + *c;
94 *c = carry + get_carry(basek, digit_plus_c, get_digit(basek, digit_plus_c));
95 });
96 } else {
97 let basek_lsh: usize = basek - lsh;
98 x.iter().zip(carry.iter_mut()).for_each(|(x, c)| {
99 let digit: i64 = get_digit(basek_lsh, *x);
100 let carry: i64 = get_carry(basek_lsh, *x, digit);
101 let digit_plus_c: i64 = (digit << lsh) + *c;
102 *c = carry + get_carry(basek, digit_plus_c, get_digit(basek, digit_plus_c));
103 });
104 }
105}
106
107#[inline(always)]
108pub fn znx_normalize_middle_step_inplace_ref(basek: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
109 #[cfg(debug_assertions)]
110 {
111 assert!(x.len() <= carry.len());
112 assert!(lsh < basek);
113 }
114 if lsh == 0 {
115 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
116 let digit: i64 = get_digit(basek, *x);
117 let carry: i64 = get_carry(basek, *x, digit);
118 let digit_plus_c: i64 = digit + *c;
119 *x = get_digit(basek, digit_plus_c);
120 *c = carry + get_carry(basek, digit_plus_c, *x);
121 });
122 } else {
123 let basek_lsh: usize = basek - lsh;
124 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
125 let digit: i64 = get_digit(basek_lsh, *x);
126 let carry: i64 = get_carry(basek_lsh, *x, digit);
127 let digit_plus_c: i64 = (digit << lsh) + *c;
128 *x = get_digit(basek, digit_plus_c);
129 *c = carry + get_carry(basek, digit_plus_c, *x);
130 });
131 }
132}
133
134#[inline(always)]
135pub fn znx_normalize_middle_step_ref(basek: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
136 #[cfg(debug_assertions)]
137 {
138 assert_eq!(x.len(), a.len());
139 assert!(x.len() <= carry.len());
140 assert!(lsh < basek);
141 }
142 if lsh == 0 {
143 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
144 let digit: i64 = get_digit(basek, *a);
145 let carry: i64 = get_carry(basek, *a, digit);
146 let digit_plus_c: i64 = digit + *c;
147 *x = get_digit(basek, digit_plus_c);
148 *c = carry + get_carry(basek, digit_plus_c, *x);
149 });
150 } else {
151 let basek_lsh: usize = basek - lsh;
152 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
153 let digit: i64 = get_digit(basek_lsh, *a);
154 let carry: i64 = get_carry(basek_lsh, *a, digit);
155 let digit_plus_c: i64 = (digit << lsh) + *c;
156 *x = get_digit(basek, digit_plus_c);
157 *c = carry + get_carry(basek, digit_plus_c, *x);
158 });
159 }
160}
161
162#[inline(always)]
163pub fn znx_normalize_final_step_inplace_ref(basek: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
164 #[cfg(debug_assertions)]
165 {
166 assert!(x.len() <= carry.len());
167 assert!(lsh < basek);
168 }
169
170 if lsh == 0 {
171 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
172 *x = get_digit(basek, get_digit(basek, *x) + *c);
173 });
174 } else {
175 let basek_lsh: usize = basek - lsh;
176 x.iter_mut().zip(carry.iter_mut()).for_each(|(x, c)| {
177 *x = get_digit(basek, (get_digit(basek_lsh, *x) << lsh) + *c);
178 });
179 }
180}
181
182#[inline(always)]
183pub fn znx_normalize_final_step_ref(basek: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
184 #[cfg(debug_assertions)]
185 {
186 assert!(x.len() <= carry.len());
187 assert!(lsh < basek);
188 }
189 if lsh == 0 {
190 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
191 *x = get_digit(basek, get_digit(basek, *a) + *c);
192 });
193 } else {
194 let basek_lsh: usize = basek - lsh;
195 izip!(x.iter_mut(), a.iter(), carry.iter_mut()).for_each(|(x, a, c)| {
196 *x = get_digit(basek, (get_digit(basek_lsh, *a) << lsh) + *c);
197 });
198 }
199}