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