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 num_bigint;
  7pub mod poly;
  8pub mod ring;
  9pub mod scalar;
 10
 11pub const CHUNK: usize = 8;
 12
 13pub mod macros {
 14
 15    #[macro_export]
 16    macro_rules! apply_v {
 17        ($self:expr, $f:expr, $a:expr, $CHUNK:expr) => {
 18            match CHUNK {
 19                8 => {
 20                    $a.chunks_exact_mut(8).for_each(|a| {
 21                        $f(&$self, &mut a[0]);
 22                        $f(&$self, &mut a[1]);
 23                        $f(&$self, &mut a[2]);
 24                        $f(&$self, &mut a[3]);
 25                        $f(&$self, &mut a[4]);
 26                        $f(&$self, &mut a[5]);
 27                        $f(&$self, &mut a[6]);
 28                        $f(&$self, &mut a[7]);
 29                    });
 30
 31                    let n: usize = $a.len();
 32                    let m = n - (n & (CHUNK - 1));
 33                    $a[m..].iter_mut().for_each(|a| {
 34                        $f(&$self, a);
 35                    });
 36                }
 37                _ => {
 38                    $a.iter_mut().for_each(|a| {
 39                        $f(&$self, a);
 40                    });
 41                }
 42            }
 43        };
 44    }
 45
 46    #[macro_export]
 47    macro_rules! apply_vv {
 48        ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
 49            let n: usize = $a.len();
 50            debug_assert!(
 51                $b.len() == n,
 52                "invalid argument b: b.len() = {} != a.len() = {}",
 53                $b.len(),
 54                n
 55            );
 56            debug_assert!(
 57                CHUNK & (CHUNK - 1) == 0,
 58                "invalid CHUNK const: not a power of two"
 59            );
 60
 61            match CHUNK {
 62                8 => {
 63                    izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
 64                        $f(&$self, &a[0], &mut b[0]);
 65                        $f(&$self, &a[1], &mut b[1]);
 66                        $f(&$self, &a[2], &mut b[2]);
 67                        $f(&$self, &a[3], &mut b[3]);
 68                        $f(&$self, &a[4], &mut b[4]);
 69                        $f(&$self, &a[5], &mut b[5]);
 70                        $f(&$self, &a[6], &mut b[6]);
 71                        $f(&$self, &a[7], &mut b[7]);
 72                    });
 73
 74                    let m = n - (n & (CHUNK - 1));
 75                    izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
 76                        $f(&$self, a, b);
 77                    });
 78                }
 79                _ => {
 80                    izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
 81                        $f(&$self, a, b);
 82                    });
 83                }
 84            }
 85        };
 86    }
 87
 88    #[macro_export]
 89    macro_rules! apply_vvv {
 90        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
 91            let n: usize = $a.len();
 92            debug_assert!(
 93                $b.len() == n,
 94                "invalid argument b: b.len() = {} != a.len() = {}",
 95                $b.len(),
 96                n
 97            );
 98            debug_assert!(
 99                $c.len() == n,
100                "invalid argument c: b.len() = {} != a.len() = {}",
101                $c.len(),
102                n
103            );
104            debug_assert!(
105                CHUNK & (CHUNK - 1) == 0,
106                "invalid CHUNK const: not a power of two"
107            );
108
109            match CHUNK {
110                8 => {
111                    izip!(
112                        $a.chunks_exact(8),
113                        $b.chunks_exact(8),
114                        $c.chunks_exact_mut(8)
115                    )
116                    .for_each(|(a, b, c)| {
117                        $f(&$self, &a[0], &b[0], &mut c[0]);
118                        $f(&$self, &a[1], &b[1], &mut c[1]);
119                        $f(&$self, &a[2], &b[2], &mut c[2]);
120                        $f(&$self, &a[3], &b[3], &mut c[3]);
121                        $f(&$self, &a[4], &b[4], &mut c[4]);
122                        $f(&$self, &a[5], &b[5], &mut c[5]);
123                        $f(&$self, &a[6], &b[6], &mut c[6]);
124                        $f(&$self, &a[7], &b[7], &mut c[7]);
125                    });
126
127                    let m = n - (n & 7);
128                    izip!($a[m..].iter(), $b[m..].iter(), $c[m..].iter_mut()).for_each(
129                        |(a, b, c)| {
130                            $f(&$self, a, b, c);
131                        },
132                    );
133                }
134                _ => {
135                    izip!($a.iter(), $b.iter(), $c.iter_mut()).for_each(|(a, b, c)| {
136                        $f(&$self, a, b, c);
137                    });
138                }
139            }
140        };
141    }
142
143    #[macro_export]
144    macro_rules! apply_sv {
145        ($self:expr, $f:expr, $a:expr, $b:expr, $CHUNK:expr) => {
146            let n: usize = $b.len();
147
148            debug_assert!(
149                CHUNK & (CHUNK - 1) == 0,
150                "invalid CHUNK const: not a power of two"
151            );
152
153            match CHUNK {
154                8 => {
155                    izip!($b.chunks_exact_mut(8)).for_each(|b| {
156                        $f(&$self, $a, &mut b[0]);
157                        $f(&$self, $a, &mut b[1]);
158                        $f(&$self, $a, &mut b[2]);
159                        $f(&$self, $a, &mut b[3]);
160                        $f(&$self, $a, &mut b[4]);
161                        $f(&$self, $a, &mut b[5]);
162                        $f(&$self, $a, &mut b[6]);
163                        $f(&$self, $a, &mut b[7]);
164                    });
165
166                    let m = n - (n & 7);
167                    izip!($b[m..].iter_mut()).for_each(|b| {
168                        $f(&$self, $a, b);
169                    });
170                }
171                _ => {
172                    izip!($b.iter_mut()).for_each(|b| {
173                        $f(&$self, $a, b);
174                    });
175                }
176            }
177        };
178    }
179
180    #[macro_export]
181    macro_rules! apply_svv {
182        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
183            let n: usize = $b.len();
184            debug_assert!(
185                $c.len() == n,
186                "invalid argument c: c.len() = {} != b.len() = {}",
187                $c.len(),
188                n
189            );
190            debug_assert!(
191                CHUNK & (CHUNK - 1) == 0,
192                "invalid CHUNK const: not a power of two"
193            );
194
195            match CHUNK {
196                8 => {
197                    izip!($b.chunks_exact(8), $c.chunks_exact_mut(8)).for_each(|(b, c)| {
198                        $f(&$self, $a, &b[0], &mut c[0]);
199                        $f(&$self, $a, &b[1], &mut c[1]);
200                        $f(&$self, $a, &b[2], &mut c[2]);
201                        $f(&$self, $a, &b[3], &mut c[3]);
202                        $f(&$self, $a, &b[4], &mut c[4]);
203                        $f(&$self, $a, &b[5], &mut c[5]);
204                        $f(&$self, $a, &b[6], &mut c[6]);
205                        $f(&$self, $a, &b[7], &mut c[7]);
206                    });
207
208                    let m = n - (n & 7);
209                    izip!($b[m..].iter(), $c[m..].iter_mut()).for_each(|(b, c)| {
210                        $f(&$self, $a, b, c);
211                    });
212                }
213                _ => {
214                    izip!($b.iter(), $c.iter_mut()).for_each(|(b, c)| {
215                        $f(&$self, $a, b, c);
216                    });
217                }
218            }
219        };
220    }
221
222    #[macro_export]
223    macro_rules! apply_vvsv {
224        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
225            let n: usize = $a.len();
226            debug_assert!(
227                $b.len() == n,
228                "invalid argument b: b.len() = {} != a.len() = {}",
229                $b.len(),
230                n
231            );
232            debug_assert!(
233                $d.len() == n,
234                "invalid argument d: d.len() = {} != a.len() = {}",
235                $d.len(),
236                n
237            );
238            debug_assert!(
239                CHUNK & (CHUNK - 1) == 0,
240                "invalid CHUNK const: not a power of two"
241            );
242
243            match CHUNK {
244                8 => {
245                    izip!(
246                        $a.chunks_exact(8),
247                        $b.chunks_exact(8),
248                        $d.chunks_exact_mut(8)
249                    )
250                    .for_each(|(a, b, d)| {
251                        $f(&$self, &a[0], &b[0], $c, &mut d[0]);
252                        $f(&$self, &a[1], &b[1], $c, &mut d[1]);
253                        $f(&$self, &a[2], &b[2], $c, &mut d[2]);
254                        $f(&$self, &a[3], &b[3], $c, &mut d[3]);
255                        $f(&$self, &a[4], &b[4], $c, &mut d[4]);
256                        $f(&$self, &a[5], &b[5], $c, &mut d[5]);
257                        $f(&$self, &a[6], &b[6], $c, &mut d[6]);
258                        $f(&$self, &a[7], &b[7], $c, &mut d[7]);
259                    });
260
261                    let m = n - (n & 7);
262                    izip!($a[m..].iter(), $b[m..].iter(), $d[m..].iter_mut()).for_each(
263                        |(a, b, d)| {
264                            $f(&$self, a, b, $c, d);
265                        },
266                    );
267                }
268                _ => {
269                    izip!($a.iter(), $b.iter(), $d.iter_mut()).for_each(|(a, b, d)| {
270                        $f(&$self, a, b, $c, d);
271                    });
272                }
273            }
274        };
275    }
276
277    #[macro_export]
278    macro_rules! apply_vsv {
279        ($self:expr, $f:expr, $a:expr, $c:expr, $b:expr, $CHUNK:expr) => {
280            let n: usize = $a.len();
281            debug_assert!(
282                $b.len() == n,
283                "invalid argument b: b.len() = {} != a.len() = {}",
284                $b.len(),
285                n
286            );
287            debug_assert!(
288                CHUNK & (CHUNK - 1) == 0,
289                "invalid CHUNK const: not a power of two"
290            );
291
292            match CHUNK {
293                8 => {
294                    izip!($a.chunks_exact(8), $b.chunks_exact_mut(8)).for_each(|(a, b)| {
295                        $f(&$self, &a[0], $c, &mut b[0]);
296                        $f(&$self, &a[1], $c, &mut b[1]);
297                        $f(&$self, &a[2], $c, &mut b[2]);
298                        $f(&$self, &a[3], $c, &mut b[3]);
299                        $f(&$self, &a[4], $c, &mut b[4]);
300                        $f(&$self, &a[5], $c, &mut b[5]);
301                        $f(&$self, &a[6], $c, &mut b[6]);
302                        $f(&$self, &a[7], $c, &mut b[7]);
303                    });
304
305                    let m = n - (n & 7);
306                    izip!($a[m..].iter(), $b[m..].iter_mut()).for_each(|(a, b)| {
307                        $f(&$self, a, $c, b);
308                    });
309                }
310                _ => {
311                    izip!($a.iter(), $b.iter_mut()).for_each(|(a, b)| {
312                        $f(&$self, a, $c, b);
313                    });
314                }
315            }
316        };
317    }
318
319    #[macro_export]
320    macro_rules! apply_vssv {
321        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $CHUNK:expr) => {
322            let n: usize = $a.len();
323            debug_assert!(
324                $d.len() == n,
325                "invalid argument d: d.len() = {} != a.len() = {}",
326                $d.len(),
327                n
328            );
329            debug_assert!(
330                CHUNK & (CHUNK - 1) == 0,
331                "invalid CHUNK const: not a power of two"
332            );
333
334            match CHUNK {
335                8 => {
336                    izip!($a.chunks_exact(8), $d.chunks_exact_mut(8)).for_each(|(a, d)| {
337                        $f(&$self, &a[0], $b, $c, &mut d[0]);
338                        $f(&$self, &a[1], $b, $c, &mut d[1]);
339                        $f(&$self, &a[2], $b, $c, &mut d[2]);
340                        $f(&$self, &a[3], $b, $c, &mut d[3]);
341                        $f(&$self, &a[4], $b, $c, &mut d[4]);
342                        $f(&$self, &a[5], $b, $c, &mut d[5]);
343                        $f(&$self, &a[6], $b, $c, &mut d[6]);
344                        $f(&$self, &a[7], $b, $c, &mut d[7]);
345                    });
346
347                    let m = n - (n & 7);
348                    izip!($a[m..].iter(), $d[m..].iter_mut()).for_each(|(a, d)| {
349                        $f(&$self, a, $b, $c, d);
350                    });
351                }
352                _ => {
353                    izip!($a.iter(), $d.iter_mut()).for_each(|(a, d)| {
354                        $f(&$self, a, $b, $c, d);
355                    });
356                }
357            }
358        };
359    }
360
361    #[macro_export]
362    macro_rules! apply_ssv {
363        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
364            let n: usize = $c.len();
365            debug_assert!(
366                CHUNK & (CHUNK - 1) == 0,
367                "invalid CHUNK const: not a power of two"
368            );
369
370            match CHUNK {
371                8 => {
372                    izip!($c.chunks_exact_mut(8)).for_each(|c| {
373                        $f(&$self, $a, $b, &mut c[0]);
374                        $f(&$self, $a, $b, &mut c[1]);
375                        $f(&$self, $a, $b, &mut c[2]);
376                        $f(&$self, $a, $b, &mut c[3]);
377                        $f(&$self, $a, $b, &mut c[4]);
378                        $f(&$self, $a, $b, &mut c[5]);
379                        $f(&$self, $a, $b, &mut c[6]);
380                        $f(&$self, $a, $b, &mut c[7]);
381                    });
382
383                    let m = n - (n & 7);
384                    izip!($c[m..].iter_mut()).for_each(|c| {
385                        $f(&$self, $a, $b, c);
386                    });
387                }
388                _ => {
389                    izip!($c.iter_mut()).for_each(|c| {
390                        $f(&$self, $a, $b, c);
391                    });
392                }
393            }
394        };
395    }
396
397    #[macro_export]
398    macro_rules! apply_vvssv {
399        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $CHUNK:expr) => {
400            let n: usize = $a.len();
401            debug_assert!(
402                $b.len() == n,
403                "invalid argument b: b.len() = {} != a.len() = {}",
404                $b.len(),
405                n
406            );
407            debug_assert!(
408                $e.len() == n,
409                "invalid argument e: e.len() = {} != a.len() = {}",
410                $e.len(),
411                n
412            );
413            debug_assert!(
414                CHUNK & (CHUNK - 1) == 0,
415                "invalid CHUNK const: not a power of two"
416            );
417
418            match CHUNK {
419                8 => {
420                    izip!(
421                        $a.chunks_exact(8),
422                        $b.chunks_exact(8),
423                        $e.chunks_exact_mut(8)
424                    )
425                    .for_each(|(a, b, e)| {
426                        $f(&$self, &a[0], &b[0], $c, $d, &mut e[0]);
427                        $f(&$self, &a[1], &b[1], $c, $d,  &mut e[1]);
428                        $f(&$self, &a[2], &b[2], $c, $d,  &mut e[2]);
429                        $f(&$self, &a[3], &b[3], $c, $d,  &mut e[3]);
430                        $f(&$self, &a[4], &b[4], $c, $d,  &mut e[4]);
431                        $f(&$self, &a[5], &b[5], $c, $d,  &mut e[5]);
432                        $f(&$self, &a[6], &b[6], $c, $d,  &mut e[6]);
433                        $f(&$self, &a[7], &b[7], $c, $d,  &mut e[7]);
434                    });
435
436                    let m = n - (n & 7);
437                    izip!($a[m..].iter(), $b[m..].iter(), $e[m..].iter_mut()).for_each(
438                        |(a, b, e)| {
439                            $f(&$self, a, b, $c, $d, e);
440                        },
441                    );
442                }
443                _ => {
444                    izip!($a.iter(), $b.iter(), $e.iter_mut()).for_each(|(a, b, e)| {
445                        $f(&$self, a, b, $c, $d, e);
446                    });
447                }
448            }
449        };
450    }
451}