qfall_math/integer_mod_q/modulus/distance.rs
1// Copyright © 2024 Marcel Luca Schmidt
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains the implementation of the [`Distance`] trait for [`Modulus`].
10
11use super::Modulus;
12use crate::{integer::Z, traits::Distance};
13
14impl<Integer: Into<Z>> Distance<Integer> for Modulus {
15 type Output = Z;
16
17 /// Computes the absolute distance between a [`Modulus`] and a value that
18 /// implements [`Into<Z>`].
19 ///
20 /// Parameters:
21 /// - `other`: specifies the [`Z`] value whose distance is calculated to `self`
22 ///
23 /// Returns the absolute difference, i.e. distance between the [`Modulus`] instance
24 /// and the value that implements [`Into<Z>`] as a new [`Z`] instance.
25 ///
26 /// # Examples
27 /// ```
28 /// use qfall_math::integer::Z;
29 /// use qfall_math::integer_mod_q::Modulus;
30 /// use qfall_math::traits::*;
31 ///
32 /// let a = Modulus::from(2);
33 ///
34 /// let distance_0 = a.distance(5);
35 /// let distance_1 = a.distance(10);
36 ///
37 /// # assert_eq!(Z::from(3), distance_0);
38 /// # assert_eq!(Z::from(8), distance_1);
39 /// ```
40 fn distance(&self, other: Integer) -> Self::Output {
41 let z: Z = self.into();
42 z.distance(other)
43 }
44}
45
46#[cfg(test)]
47mod test_distance {
48 use super::{Distance, Z};
49 use crate::integer_mod_q::Modulus;
50
51 /// Since we convert `self` always into a [`Z`] instance, it suffices to test
52 /// the availability here
53 #[test]
54 fn availability() {
55 let modulus = Modulus::from(2);
56 let z = Z::from(5);
57
58 let u_0 = modulus.distance(0_u8);
59 let u_1 = modulus.distance(15_u16);
60 let u_2 = modulus.distance(35_u32);
61 let u_3 = modulus.distance(u64::MAX);
62 let i_0 = modulus.distance(0_i8);
63 let i_1 = modulus.distance(-15_i16);
64 let i_2 = modulus.distance(35_i32);
65 let i_3 = modulus.distance(i64::MIN + 2);
66 let dist_z_0 = modulus.distance(&z);
67 let dist_z_1 = modulus.distance(z);
68
69 assert_eq!(Z::from(2), u_0);
70 assert_eq!(Z::from(13), u_1);
71 assert_eq!(Z::from(33), u_2);
72 assert_eq!(Z::from(u64::MAX - 2), u_3);
73 assert_eq!(Z::from(2), i_0);
74 assert_eq!(Z::from(17), i_1);
75 assert_eq!(Z::from(33), i_2);
76 assert_eq!(Z::from(i64::MIN).abs(), i_3);
77 assert_eq!(Z::from(3), dist_z_0);
78 assert_eq!(Z::from(3), dist_z_1);
79 }
80}