haar_lib/math/mod_ops/
mod.rs1pub mod enum_inv;
4pub mod inv;
5pub mod inv_p;
6pub mod log;
7pub mod pow;
8pub mod sqrt;
9
10#[cfg(test)]
11mod tests {
12 use super::{enum_inv::*, inv::*, log::*, pow::*, sqrt::*};
13
14 #[test]
15 fn test_mod_pow() {
16 fn straight_forward(x: u64, p: u64, m: u64) -> u64 {
17 let mut ret = 1;
18 for _ in 0..p {
19 ret *= x;
20 ret %= m;
21 }
22 ret
23 }
24
25 for x in 1..10 {
26 for p in 0..10 {
27 for m in 1..10 {
28 assert_eq!(mod_pow(x, p, m), straight_forward(x, p, m));
29 }
30 }
31 }
32 }
33
34 #[test]
35 fn test_mod_inv() {
36 let m = 19;
37
38 for x in 1..m {
39 assert_eq!(mod_inv(x, m).unwrap() * x % m, 1);
40 }
41
42 assert_eq!(mod_inv(4, 10), None);
43 assert_eq!(mod_inv(3, 10), Some(7));
44 }
45
46 #[test]
47 fn test_mod_log() {
48 assert_eq!(mod_log(2, 1, 5), Some(0));
50 assert_eq!(mod_log(4, 7, 10), None);
51 assert_eq!(mod_log(8, 6, 10), Some(4));
52 assert_eq!(mod_log(5, 2, 11), None);
53 assert_eq!(mod_log(5, 9, 11), Some(4));
54 assert_eq!(mod_log(0, 0, 1), Some(0));
55 assert_eq!(mod_log(0, 2, 4), None);
56 }
57
58 #[test]
59 fn test_mod_sqrt() {
60 assert_eq!(mod_sqrt(0, 5).map(|x| x.pow(2) % 5), Some(0));
62 assert_eq!(mod_sqrt(1, 5).map(|x| x.pow(2) % 5), Some(1));
63 assert_eq!(mod_sqrt(2, 5).map(|x| x.pow(2) % 5), None);
64 assert_eq!(mod_sqrt(3, 5).map(|x| x.pow(2) % 5), None);
65 assert_eq!(mod_sqrt(4, 5).map(|x| x.pow(2) % 5), Some(4));
66
67 let m = 1000000007;
68 for x in 0..100 {
69 if let Some(s) = mod_sqrt(x, m) {
70 assert_eq!(s * s % m, x);
71 }
72 }
73 }
74
75 #[test]
76 fn test_enumerate_mod_inv() {
77 #![allow(clippy::needless_range_loop)]
78 let m = 1000000007;
79 let n = 100;
80
81 let s = enumerate_mod_inv(n, m);
82 for i in 1..=n {
83 assert_eq!(i as u64 * s[i] % m, 1);
84 }
85 }
86}