poulpy/math/tests/ring_switch.rs
math/tests/ring_switch.rsRaw
1use math::poly::Poly;
2use math::ring::Ring;
3
4#[test]
5fn ring_switch_u64() {
6 let n: usize = 1 << 4;
7 let q_base: u64 = 65537u64;
8 let q_power: usize = 1usize;
9 let ring_small: Ring<u64> = Ring::new(n, q_base, q_power);
10 let ring_large = Ring::new(2 * n, q_base, q_power);
11
12 sub_test("test_ring_switch_small_to_large_u64::<NTT:false>", || {
13 test_ring_switch_small_to_large_u64::<false>(&ring_small, &ring_large)
14 });
15 sub_test("test_ring_switch_small_to_large_u64::<NTT:true>", || {
16 test_ring_switch_small_to_large_u64::<true>(&ring_small, &ring_large)
17 });
18 sub_test("test_ring_switch_large_to_small_u64::<NTT:false>", || {
19 test_ring_switch_large_to_small_u64::<false>(&ring_small, &ring_large)
20 });
21 sub_test("test_ring_switch_large_to_small_u64::<NTT:true>", || {
22 test_ring_switch_large_to_small_u64::<true>(&ring_small, &ring_large)
23 });
24}
25
26fn sub_test<F: FnOnce()>(name: &str, f: F) {
27 println!("Running {}", name);
28 f();
29}
30
31fn test_ring_switch_small_to_large_u64<const NTT: bool>(
32 ring_small: &Ring<u64>,
33 ring_large: &Ring<u64>,
34) {
35 let mut a: Poly<u64> = ring_small.new_poly();
36 let mut buf: Poly<u64> = ring_small.new_poly();
37 let mut b: Poly<u64> = ring_large.new_poly();
38
39 a.0.iter_mut().enumerate().for_each(|(i, x)| *x = i as u64);
40
41 if NTT {
42 ring_small.ntt_inplace::<false>(&mut a);
43 }
44
45 ring_large.switch_degree::<NTT>(&a, &mut buf, &mut b);
46
47 if NTT {
48 ring_small.intt_inplace::<false>(&mut a);
49 ring_large.intt_inplace::<false>(&mut b);
50 }
51
52 let gap: usize = ring_large.n() / ring_small.n();
53
54 b.0.iter()
55 .step_by(gap)
56 .zip(a.0.iter())
57 .for_each(|(x_out, x_in)| assert_eq!(x_out, x_in));
58}
59
60fn test_ring_switch_large_to_small_u64<const NTT: bool>(
61 ring_small: &Ring<u64>,
62 ring_large: &Ring<u64>,
63) {
64 let mut a: Poly<u64> = ring_large.new_poly();
65 let mut buf: Poly<u64> = ring_large.new_poly();
66 let mut b: Poly<u64> = ring_small.new_poly();
67
68 a.0.iter_mut().enumerate().for_each(|(i, x)| *x = i as u64);
69
70 if NTT {
71 ring_large.ntt_inplace::<false>(&mut a);
72 }
73
74 ring_large.switch_degree::<NTT>(&a, &mut buf, &mut b);
75
76 if NTT {
77 ring_large.intt_inplace::<false>(&mut a);
78 ring_small.intt_inplace::<false>(&mut b);
79 }
80
81 let gap: usize = ring_large.n() / ring_small.n();
82
83 a.0.iter()
84 .step_by(gap)
85 .zip(b.0.iter())
86 .for_each(|(x_out, x_in)| assert_eq!(x_out, x_in));
87}