arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/math/src/lib.rs
math/src/lib.rsRaw
  1#![feature(bigint_helper_methods)]
  2#![feature(test)]
  3
  4pub mod dft;
  5pub mod modulus;
  6pub mod poly;
  7pub mod ring;
  8pub mod scalar;
  9
 10pub const CHUNK: usize = 8;
 11
 12pub mod macros {
 13
 14    #[macro_export]
 15    macro_rules! apply_v {
 16        ($self:expr, $f:expr, $a:expr, $CHUNK:expr) => {
 17            match CHUNK {
 18                8 => {
 19                    $a.chunks_exact_mut(8).for_each(|a| {
 20                        $f(&$self, &mut a[0]);
 21                        $f(&$self, &mut a[1]);
 22                        $f(&$self, &mut a[2]);
 23                        $f(&$self, &mut a[3]);
 24                        $f(&$self, &mut a[4]);
 25                        $f(&$self, &mut a[5]);
 26                        $f(&$self, &mut a[6]);
 27                        $f(&$self, &mut a[7]);
 28                    });
 29
 30                    let n: usize = $a.len();
 31                    let m = n - (n & (CHUNK - 1));
 32                    $a[m..].iter_mut().for_each(|a| {
 33                        $f(&$self, a);
 34                    });
 35                }
 36                _ => {
 37                    $a.iter_mut().for_each(|a| {
 38                        $f(&$self, a);
 39                    });
 40                }
 41            }
 42        };
 43    }
 44
 45    #[macro_export]
 46    macro_rules! apply_vv {
 47        ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
 48            let n: usize = $a.len();
 49            debug_assert!(
 50                $b.len() == n,
 51                "invalid argument b: b.len() = {} != a.len() = {}",
 52                $b.len(),
 53                n
 54            );
 55            debug_assert!(
 56                CHUNK & (CHUNK - 1) == 0,
 57                "invalid CHUNK const: not a power of two"
 58            );
 59
 60            match CHUNK {
 61                8 => {
 62                    izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
 63                        $f(&$self, &a[0], &mut b[0]);
 64                        $f(&$self, &a[1], &mut b[1]);
 65                        $f(&$self, &a[2], &mut b[2]);
 66                        $f(&$self, &a[3], &mut b[3]);
 67                        $f(&$self, &a[4], &mut b[4]);
 68                        $f(&$self, &a[5], &mut b[5]);
 69                        $f(&$self, &a[6], &mut b[6]);
 70                        $f(&$self, &a[7], &mut b[7]);
 71                    });
 72
 73                    let m = n - (n & (CHUNK - 1));
 74                    izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
 75                        $f(&$self, a, b);
 76                    });
 77                }
 78                _ => {
 79                    izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
 80                        $f(&$self, a, b);
 81                    });
 82                }
 83            }
 84        };
 85    }
 86
 87    #[macro_export]
 88    macro_rules! apply_vvv {
 89        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
 90            let n: usize = $a.len();
 91            debug_assert!(
 92                $b.len() == n,
 93                "invalid argument b: b.len() = {} != a.len() = {}",
 94                $b.len(),
 95                n
 96            );
 97            debug_assert!(
 98                $c.len() == n,
 99                "invalid argument c: b.len() = {} != a.len() = {}",
100                $c.len(),
101                n
102            );
103            debug_assert!(
104                CHUNK & (CHUNK - 1) == 0,
105                "invalid CHUNK const: not a power of two"
106            );
107
108            match CHUNK {
109                8 => {
110                    izip!(
111                        $a.chunks_exact(8),
112                        $b.chunks_exact(8),
113                        $c.chunks_exact_mut(8)
114                    )
115                    .for_each(|(a, b, c)| {
116                        $f(&$self, &a[0], &b[0], &mut c[0]);
117                        $f(&$self, &a[1], &b[1], &mut c[1]);
118                        $f(&$self, &a[2], &b[2], &mut c[2]);
119                        $f(&$self, &a[3], &b[3], &mut c[3]);
120                        $f(&$self, &a[4], &b[4], &mut c[4]);
121                        $f(&$self, &a[5], &b[5], &mut c[5]);
122                        $f(&$self, &a[6], &b[6], &mut c[6]);
123                        $f(&$self, &a[7], &b[7], &mut c[7]);
124                    });
125
126                    let m = n - (n & 7);
127                    izip!($a[m..].iter(), $b[m..].iter(), $c[m..].iter_mut()).for_each(
128                        |(a, b, c)| {
129                            $f(&$self, a, b, c);
130                        },
131                    );
132                }
133                _ => {
134                    izip!($a.iter(), $b.iter(), $c.iter_mut()).for_each(|(a, b, c)| {
135                        $f(&$self, a, b, c);
136                    });
137                }
138            }
139        };
140    }
141
142    #[macro_export]
143    macro_rules! apply_sv {
144        ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
145            let n: usize = $b.len();
146
147            debug_assert!(
148                CHUNK & (CHUNK - 1) == 0,
149                "invalid CHUNK const: not a power of two"
150            );
151
152            match CHUNK {
153                8 => {
154                    izip!($b.chunks_exact_mut(8)).for_each(|b| {
155                        $f(&$self, $a, &mut b[0]);
156                        $f(&$self, $a, &mut b[1]);
157                        $f(&$self, $a, &mut b[2]);
158                        $f(&$self, $a, &mut b[3]);
159                        $f(&$self, $a, &mut b[4]);
160                        $f(&$self, $a, &mut b[5]);
161                        $f(&$self, $a, &mut b[6]);
162                        $f(&$self, $a, &mut b[7]);
163                    });
164
165                    let m = n - (n & 7);
166                    izip!($b[m..].iter_mut()).for_each(|b| {
167                        $f(&$self, $a, b);
168                    });
169                }
170                _ => {
171                    izip!($b.iter_mut()).for_each(|b| {
172                        $f(&$self, $a, b);
173                    });
174                }
175            }
176        };
177    }
178
179    #[macro_export]
180    macro_rules! apply_svv {
181        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
182            let n: usize = $b.len();
183            debug_assert!(
184                $c.len() == n,
185                "invalid argument c: c.len() = {} != b.len() = {}",
186                $c.len(),
187                n
188            );
189            debug_assert!(
190                CHUNK & (CHUNK - 1) == 0,
191                "invalid CHUNK const: not a power of two"
192            );
193
194            match CHUNK {
195                8 => {
196                    izip!($b.chunks_exact(8), $c.chunks_exact_mut(8)).for_each(|(b, c)| {
197                        $f(&$self, $a, &b[0], &mut c[0]);
198                        $f(&$self, $a, &b[1], &mut c[1]);
199                        $f(&$self, $a, &b[2], &mut c[2]);
200                        $f(&$self, $a, &b[3], &mut c[3]);
201                        $f(&$self, $a, &b[4], &mut c[4]);
202                        $f(&$self, $a, &b[5], &mut c[5]);
203                        $f(&$self, $a, &b[6], &mut c[6]);
204                        $f(&$self, $a, &b[7], &mut c[7]);
205                    });
206
207                    let m = n - (n & 7);
208                    izip!($b[m..].iter(), $c[m..].iter_mut()).for_each(|(b, c)| {
209                        $f(&$self, $a, b, c);
210                    });
211                }
212                _ => {
213                    izip!($b.iter(), $c.iter_mut()).for_each(|(b, c)| {
214                        $f(&$self, $a, b, c);
215                    });
216                }
217            }
218        };
219    }
220
221    #[macro_export]
222    macro_rules! apply_vvsv {
223        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
224            let n: usize = $a.len();
225            debug_assert!(
226                $b.len() == n,
227                "invalid argument b: b.len() = {} != a.len() = {}",
228                $b.len(),
229                n
230            );
231            debug_assert!(
232                $d.len() == n,
233                "invalid argument d: d.len() = {} != a.len() = {}",
234                $d.len(),
235                n
236            );
237            debug_assert!(
238                CHUNK & (CHUNK - 1) == 0,
239                "invalid CHUNK const: not a power of two"
240            );
241
242            match CHUNK {
243                8 => {
244                    izip!(
245                        $a.chunks_exact(8),
246                        $b.chunks_exact(8),
247                        $d.chunks_exact_mut(8)
248                    )
249                    .for_each(|(a, b, d)| {
250                        $f(&$self, &a[0], &b[0], $c, &mut d[0]);
251                        $f(&$self, &a[1], &b[1], $c, &mut d[1]);
252                        $f(&$self, &a[2], &b[2], $c, &mut d[2]);
253                        $f(&$self, &a[3], &b[3], $c, &mut d[3]);
254                        $f(&$self, &a[4], &b[4], $c, &mut d[4]);
255                        $f(&$self, &a[5], &b[5], $c, &mut d[5]);
256                        $f(&$self, &a[6], &b[6], $c, &mut d[6]);
257                        $f(&$self, &a[7], &b[7], $c, &mut d[7]);
258                    });
259
260                    let m = n - (n & 7);
261                    izip!($a[m..].iter(), $b[m..].iter(), $d[m..].iter_mut()).for_each(
262                        |(a, b, d)| {
263                            $f(&$self, a, b, $c, d);
264                        },
265                    );
266                }
267                _ => {
268                    izip!($a.iter(), $b.iter(), $d.iter_mut()).for_each(|(a, b, d)| {
269                        $f(&$self, a, b, $c, d);
270                    });
271                }
272            }
273        };
274    }
275
276    #[macro_export]
277    macro_rules! apply_vsv {
278        ($self:expr, $f:expr, $a:expr, $c:expr, $b:expr, $CHUNK:expr) => {
279            let n: usize = $a.len();
280            debug_assert!(
281                $b.len() == n,
282                "invalid argument b: b.len() = {} != a.len() = {}",
283                $b.len(),
284                n
285            );
286            debug_assert!(
287                CHUNK & (CHUNK - 1) == 0,
288                "invalid CHUNK const: not a power of two"
289            );
290
291            match CHUNK {
292                8 => {
293                    izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
294                        $f(&$self, &a[0], $c, &mut b[0]);
295                        $f(&$self, &a[1], $c, &mut b[1]);
296                        $f(&$self, &a[2], $c, &mut b[2]);
297                        $f(&$self, &a[3], $c, &mut b[3]);
298                        $f(&$self, &a[4], $c, &mut b[4]);
299                        $f(&$self, &a[5], $c, &mut b[5]);
300                        $f(&$self, &a[6], $c, &mut b[6]);
301                        $f(&$self, &a[7], $c, &mut b[7]);
302                    });
303
304                    let m = n - (n & 7);
305                    izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
306                        $f(&$self, a, $c, b);
307                    });
308                }
309                _ => {
310                    izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
311                        $f(&$self, a, $c, b);
312                    });
313                }
314            }
315        };
316    }
317}