Skip to main content

qfall_math/integer/mat_z/arithmetic/
neg.rs

1// Copyright 2026 Jan Niklas Siemer
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//! Implementation of the [`Neg`] trait for [`MatZ`] values.
10
11use super::super::MatZ;
12use crate::traits::MatrixDimensions;
13use flint3_sys::fmpz_mat_neg;
14use std::ops::Neg;
15
16impl Neg for MatZ {
17    type Output = MatZ;
18
19    /// Implements the [`Neg`] trait for [`MatZ`] values.
20    /// [`Neg`] is implemented for both borrowed and owned [`MatZ`].
21    ///
22    /// When called on owned [`MatZ`] it will reuse the memory of `self`.
23    ///
24    /// Returns the additive inverse of `self` as a [`MatZ`].
25    ///
26    /// # Examples
27    /// ```
28    /// use qfall_math::integer::MatZ;
29    /// use std::str::FromStr;
30    ///
31    /// let a: MatZ = MatZ::from_str("[[1, -2],[3, 42]]").unwrap();
32    ///
33    /// let b: MatZ = -&a;
34    /// let c: MatZ = -a;
35    /// ```
36    fn neg(mut self) -> Self::Output {
37        unsafe { fmpz_mat_neg(&mut self.matrix, &self.matrix) };
38        self
39    }
40}
41
42impl Neg for &MatZ {
43    type Output = MatZ;
44
45    /// Documentation at [`MatZ::neg`].
46    fn neg(self) -> Self::Output {
47        let mut out = MatZ::new(self.get_num_rows(), self.get_num_columns());
48        unsafe { fmpz_mat_neg(&mut out.matrix, &self.matrix) };
49        out
50    }
51}
52
53#[cfg(test)]
54mod test_neg {
55    use super::MatZ;
56    use std::str::FromStr;
57
58    /// Ensure that `neg` works for small entries.
59    #[test]
60    fn correct_small() {
61        let a = MatZ::from_str("[[1, -2, 0],[3, 4, -5]]").unwrap();
62        let b = MatZ::from_str("[[-1, 2, 0],[-3, -4, 5]]").unwrap();
63        let c = MatZ::new(2, 3);
64
65        assert_eq!(a, -(-&a));
66        assert_eq!(a, -&b);
67        assert_eq!(b, -&a);
68        assert_eq!(a, -b.clone());
69        assert_eq!(b, -a);
70        assert_eq!(c, -&c);
71        assert_eq!(c.clone(), -c);
72    }
73
74    /// Ensure that `neg` works for large entries.
75    #[test]
76    fn correct_large() {
77        let a = MatZ::from_str(&format!("[[{}, {}],[1, 2]]", u64::MAX, i64::MIN)).unwrap();
78        let b = MatZ::from_str(&format!(
79            "[[-{}, {}],[-1, -2]]",
80            u64::MAX,
81            i64::MAX as u64 + 1
82        ))
83        .unwrap();
84
85        assert_eq!(a, -(-&a));
86        assert_eq!(b, -&a);
87        assert_eq!(b, -a);
88    }
89}