Skip to main content

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