Skip to content

Commit 22879c6

Browse files
committed
Implement sub for MatZ and MatQ
1 parent b894561 commit 22879c6

File tree

3 files changed

+118
-41
lines changed

3 files changed

+118
-41
lines changed

src/integer/mat_z/arithmetic/sub.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::integer_mod_q::MatZq;
1414
use crate::macros::arithmetics::{
1515
arithmetic_trait_borrowed_to_owned, arithmetic_trait_mixed_borrowed_owned,
1616
};
17+
use crate::rational::MatQ;
1718
use crate::traits::MatrixDimensions;
1819
use flint_sys::fmpz_mat::fmpz_mat_sub;
1920
use flint_sys::fmpz_mod_mat::_fmpz_mod_mat_reduce;
@@ -105,6 +106,43 @@ impl Sub<&MatZq> for &MatZ {
105106
arithmetic_trait_borrowed_to_owned!(Sub, sub, MatZ, MatZq, MatZq);
106107
arithmetic_trait_mixed_borrowed_owned!(Sub, sub, MatZ, MatZq, MatZq);
107108

109+
impl Sub<&MatQ> for &MatZ {
110+
type Output = MatQ;
111+
112+
/// Implements the [`Sub`] trait for two matrices.
113+
/// Furthermore, it is available for any combination of [`MatZ`] and [`MatQ`].
114+
///
115+
/// Parameters:
116+
/// - `other`: specifies the value to subtract from `self`
117+
///
118+
/// Returns the result of the subtraction as a [`MatQ`].
119+
///
120+
/// # Examples
121+
/// ```
122+
/// use qfall_math::{rational::MatQ, integer::MatZ};
123+
/// use std::str::FromStr;
124+
///
125+
/// let a: MatQ = MatQ::from_str("[[1/2, 2/3, 3/4],[3/4, 4/5, 5/7]]").unwrap();
126+
/// let b: MatZ = MatZ::identity(2, 3);
127+
///
128+
/// let d: MatQ = &a - &b;
129+
/// let e: MatQ = a.clone() - b.clone();
130+
/// let f: MatQ = &a - b.clone();
131+
/// let g: MatQ = a - b;
132+
/// ```
133+
///
134+
/// # Panics ...
135+
/// - if the dimensions of both matrices mismatch.
136+
fn sub(self, other: &MatQ) -> Self::Output {
137+
let new_self = MatQ::from(self);
138+
139+
other.sub_safe(&new_self).unwrap()
140+
}
141+
}
142+
143+
arithmetic_trait_borrowed_to_owned!(Sub, sub, MatZ, MatQ, MatQ);
144+
arithmetic_trait_mixed_borrowed_owned!(Sub, sub, MatZ, MatQ, MatQ);
145+
108146
impl MatZ {
109147
/// Implements subtraction for two [`MatZ`] matrices.
110148
///

src/rational/mat_q/arithmetic/add.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -122,25 +122,9 @@ impl Add<&MatZ> for &MatQ {
122122

123123
/// Documentation at [`MatQ::add`].
124124
fn add(self, other: &MatZ) -> Self::Output {
125-
if self.get_num_rows() != other.get_num_rows()
126-
|| self.get_num_columns() != other.get_num_columns()
127-
{
128-
panic!(
129-
"Tried to add a '{}x{}' matrix and a '{}x{}' matrix.",
130-
self.get_num_rows(),
131-
self.get_num_columns(),
132-
other.get_num_rows(),
133-
other.get_num_columns()
134-
);
135-
}
136-
137125
let other = MatQ::from(other);
138-
let mut out = MatQ::new(self.get_num_rows(), self.get_num_columns());
139-
unsafe {
140-
fmpq_mat_add(&mut out.matrix, &self.matrix, &other.matrix);
141-
}
142126

143-
out
127+
self.add_safe(&other).unwrap()
144128
}
145129
}
146130

@@ -321,22 +305,6 @@ mod test_add {
321305
}
322306
}
323307

324-
/// Ensure that `add` is available for all types between [`MatZ`] and [`MatQ`].
325-
#[test]
326-
fn availability() {
327-
let a = MatQ::new(2, 2);
328-
let b = MatZ::new(2, 2);
329-
330-
let _ = &a + &b;
331-
let _ = &a + b.clone();
332-
let _ = a.clone() + &b;
333-
let _ = a.clone() + b.clone();
334-
let _ = &b + &a;
335-
let _ = &b + a.clone();
336-
let _ = b.clone() + &a;
337-
let _ = b.clone() + a.clone();
338-
}
339-
340308
/// Testing addition for two [`MatQ`]
341309
#[test]
342310
fn add() {
@@ -417,4 +385,30 @@ mod test_add {
417385
assert!(a.add_safe(&b).is_err());
418386
assert!(c.add_safe(&b).is_err());
419387
}
388+
389+
/// Ensure that `add` is available for all types between [`MatZ`] and [`MatQ`].
390+
#[test]
391+
fn availability() {
392+
let a = MatQ::new(2, 2);
393+
let b = MatZ::new(2, 2);
394+
let c = MatQ::new(2, 2);
395+
396+
let _ = &a + &b;
397+
let _ = &a + b.clone();
398+
let _ = a.clone() + &b;
399+
let _ = a.clone() + b.clone();
400+
let _ = &b + &a;
401+
let _ = &b + a.clone();
402+
let _ = b.clone() + &a;
403+
let _ = b.clone() + a.clone();
404+
405+
let _ = &a + &c;
406+
let _ = &a + c.clone();
407+
let _ = a.clone() + &c;
408+
let _ = a.clone() + c.clone();
409+
let _ = &c + &a;
410+
let _ = &c + a.clone();
411+
let _ = c.clone() + &a;
412+
let _ = c.clone() + a.clone();
413+
}
420414
}

src/rational/mat_q/arithmetic/sub.rs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
use super::super::MatQ;
1212
use crate::error::MathError;
13+
use crate::integer::MatZ;
1314
use crate::macros::arithmetics::{
1415
arithmetic_trait_borrowed_to_owned, arithmetic_trait_mixed_borrowed_owned,
1516
};
@@ -19,26 +20,30 @@ use std::ops::Sub;
1920

2021
impl Sub for &MatQ {
2122
type Output = MatQ;
22-
/// Implements the [`Sub`] trait for two [`MatQ`] values.
23+
/// Implements the [`Sub`] trait for two matrices.
2324
/// [`Sub`] is implemented for any combination of [`MatQ`] and borrowed [`MatQ`].
25+
/// Furthermore, it is available for any combination of [`MatZ`] and [`MatQ`].
2426
///
2527
/// Parameters:
26-
/// - `other`: specifies the value to subtract from`self`
28+
/// - `other`: specifies the value to subtract from `self`
2729
///
2830
/// Returns the result of the subtraction as a [`MatQ`].
2931
///
3032
/// # Examples
3133
/// ```
32-
/// use qfall_math::rational::MatQ;
34+
/// use qfall_math::{rational::MatQ, integer::MatZ};
3335
/// use std::str::FromStr;
3436
///
3537
/// let a: MatQ = MatQ::from_str("[[1/2, 2/3, 3/4],[3/4, 4/5, 5/7]]").unwrap();
3638
/// let b: MatQ = MatQ::from_str("[[1/4, 9/7, 3/7],[1, 0, 5]]").unwrap();
39+
/// let c: MatZ = MatZ::identity(2, 3);
3740
///
38-
/// let c: MatQ = &a - &b;
39-
/// let d: MatQ = a - b;
40-
/// let e: MatQ = &c - d;
41-
/// let f: MatQ = c - &e;
41+
/// let d: MatQ = &a - &b;
42+
/// let e: MatQ = a - b;
43+
/// let f: MatQ = &d - e;
44+
/// let g: MatQ = d - &f;
45+
/// let h: MatQ = &f - &c;
46+
/// let i: MatQ = f - c;
4247
/// ```
4348
///
4449
/// # Panics ...
@@ -48,6 +53,20 @@ impl Sub for &MatQ {
4853
}
4954
}
5055

56+
impl Sub<&MatZ> for &MatQ {
57+
type Output = MatQ;
58+
59+
/// Documentation at [`MatQ::sub`].
60+
fn sub(self, other: &MatZ) -> Self::Output {
61+
let other = MatQ::from(other);
62+
63+
self.sub_safe(&other).unwrap()
64+
}
65+
}
66+
67+
arithmetic_trait_borrowed_to_owned!(Sub, sub, MatQ, MatZ, MatQ);
68+
arithmetic_trait_mixed_borrowed_owned!(Sub, sub, MatQ, MatZ, MatQ);
69+
5170
impl MatQ {
5271
/// Implements subtraction for two [`MatQ`] matrices.
5372
///
@@ -98,7 +117,7 @@ arithmetic_trait_mixed_borrowed_owned!(Sub, sub, MatQ, MatQ, MatQ);
98117
#[cfg(test)]
99118
mod test_sub {
100119
use super::MatQ;
101-
use crate::rational::Q;
120+
use crate::{integer::MatZ, rational::Q};
102121
use std::str::FromStr;
103122

104123
/// Testing subtraction for two [`MatQ`]
@@ -174,4 +193,30 @@ mod test_sub {
174193
assert!(a.sub_safe(&b).is_err());
175194
assert!(c.sub_safe(&b).is_err());
176195
}
196+
197+
/// Ensure that `sub` is available for all types between [`MatZ`] and [`MatQ`].
198+
#[test]
199+
fn availability() {
200+
let a = MatQ::new(2, 2);
201+
let b = MatZ::new(2, 2);
202+
let c = MatQ::new(2, 2);
203+
204+
let _ = &a - &b;
205+
let _ = &a - b.clone();
206+
let _ = a.clone() - &b;
207+
let _ = a.clone() - b.clone();
208+
let _ = &b - &a;
209+
let _ = &b - a.clone();
210+
let _ = b.clone() - &a;
211+
let _ = b.clone() - a.clone();
212+
213+
let _ = &a - &c;
214+
let _ = &a - c.clone();
215+
let _ = a.clone() - &c;
216+
let _ = a.clone() - c.clone();
217+
let _ = &c - &a;
218+
let _ = &c - a.clone();
219+
let _ = c.clone() - &a;
220+
let _ = c.clone() - a.clone();
221+
}
177222
}

0 commit comments

Comments
 (0)