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}