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;
  9pub mod num_bigint;
 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!(
337                        $a.chunks_exact(8),
338                        $d.chunks_exact_mut(8)
339                    )
340                    .for_each(|(a, d)| {
341                        $f(&$self, &a[0], $b, $c, &mut d[0]);
342                        $f(&$self, &a[1], $b, $c, &mut d[1]);
343                        $f(&$self, &a[2], $b, $c, &mut d[2]);
344                        $f(&$self, &a[3], $b, $c, &mut d[3]);
345                        $f(&$self, &a[4], $b, $c, &mut d[4]);
346                        $f(&$self, &a[5], $b, $c, &mut d[5]);
347                        $f(&$self, &a[6], $b, $c, &mut d[6]);
348                        $f(&$self, &a[7], $b, $c, &mut d[7]);
349                    });
350
351                    let m = n - (n & 7);
352                    izip!($a[m..].iter(), $d[m..].iter_mut()).for_each(
353                        |(a, d)| {
354                            $f(&$self, a, $b, $c, d);
355                        },
356                    );
357                }
358                _ => {
359                    izip!($a.iter(), $d.iter_mut()).for_each(|(a, d)| {
360                        $f(&$self, a, $b, $c, d);
361                    });
362                }
363            }
364        };
365    }
366
367    #[macro_export]
368    macro_rules! apply_ssv {
369        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $CHUNK:expr) => {
370            let n: usize = $c.len();
371            debug_assert!(
372                CHUNK & (CHUNK - 1) == 0,
373                "invalid CHUNK const: not a power of two"
374            );
375
376            match CHUNK {
377                8 => {
378                    izip!($c.chunks_exact_mut(8)).for_each(|c| {
379                        $f(&$self, $a, $b, &mut c[0]);
380                        $f(&$self, $a, $b, &mut c[1]);
381                        $f(&$self, $a, $b, &mut c[2]);
382                        $f(&$self, $a, $b, &mut c[3]);
383                        $f(&$self, $a, $b, &mut c[4]);
384                        $f(&$self, $a, $b, &mut c[5]);
385                        $f(&$self, $a, $b, &mut c[6]);
386                        $f(&$self, $a, $b, &mut c[7]);
387                    });
388
389                    let m = n - (n & 7);
390                    izip!($c[m..].iter_mut()).for_each(|c| {
391                        $f(&$self, $a, $b, c);
392                    });
393                }
394                _ => {
395                    izip!($c.iter_mut()).for_each(|c| {
396                        $f(&$self, $a, $b, c);
397                    });
398                }
399            }
400        };
401    }
402
403    #[macro_export]
404    macro_rules! apply_vvssv {
405        ($self:expr, $f:expr, $a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $CHUNK:expr) => {
406            let n: usize = $a.len();
407            debug_assert!(
408                $b.len() == n,
409                "invalid argument b: b.len() = {} != a.len() = {}",
410                $b.len(),
411                n
412            );
413            debug_assert!(
414                $e.len() == n,
415                "invalid argument e: e.len() = {} != a.len() = {}",
416                $e.len(),
417                n
418            );
419            debug_assert!(
420                CHUNK & (CHUNK - 1) == 0,
421                "invalid CHUNK const: not a power of two"
422            );
423
424            match CHUNK {
425                8 => {
426                    izip!(
427                        $a.chunks_exact(8),
428                        $b.chunks_exact(8),
429                        $e.chunks_exact_mut(8)
430                    )
431                    .for_each(|(a, b, e)| {
432                        $f(&$self, &a[0], &b[0], $c, $d, &mut e[0]);
433                        $f(&$self, &a[1], &b[1], $c, $d,  &mut e[1]);
434                        $f(&$self, &a[2], &b[2], $c, $d,  &mut e[2]);
435                        $f(&$self, &a[3], &b[3], $c, $d,  &mut e[3]);
436                        $f(&$self, &a[4], &b[4], $c, $d,  &mut e[4]);
437                        $f(&$self, &a[5], &b[5], $c, $d,  &mut e[5]);
438                        $f(&$self, &a[6], &b[6], $c, $d,  &mut e[6]);
439                        $f(&$self, &a[7], &b[7], $c, $d,  &mut e[7]);
440                    });
441
442                    let m = n - (n & 7);
443                    izip!($a[m..].iter(), $b[m..].iter(), $e[m..].iter_mut()).for_each(
444                        |(a, b, e)| {
445                            $f(&$self, a, b, $c, $d, e);
446                        },
447                    );
448                }
449                _ => {
450                    izip!($a.iter(), $b.iter(), $e.iter_mut()).for_each(|(a, b, e)| {
451                        $f(&$self, a, b, $c, $d, e);
452                    });
453                }
454            }
455        };
456    }
457}