1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::matrix::Matrix;
use crate::number::Number;
use crate::types::*;
use rayon::prelude::*;
use std::ops::Sub;

fn sub<T, U, V, W>(mut slf: Matrix<T, U>, rhs: Matrix<V, U>) -> Matrix<W, U>
where
    T: Type,
    U: Number,
    V: Type,
    W: Type,
{
    if !slf.is_same_size(&rhs) {
        panic!("dimension mismatch")
    }

    slf.elements
        .par_iter_mut()
        .zip(rhs.elements.into_par_iter())
        .map(|(s, r)| {
            *s -= r;
        })
        .collect::<Vec<_>>();

    slf.transmute()
}

macro_rules! implement {
    ($t1: ty, $t2: ty, $t3: ty) => {
        impl<U: Number> Sub<Matrix<$t2, U>> for Matrix<$t1, U> {
            type Output = Matrix<$t3, U>;

            fn sub(self, rhs: Matrix<$t2, U>) -> Self::Output {
                sub(self, rhs)
            }
        }
    };
}

macro_rules! implement_commutate {
    ($t1: ty, $t2: ty, $t3: ty) => {
        implement! {$t1, $t2, $t3}
        implement! {$t2, $t1, $t3}
    };
}

implement! {Standard, Standard, Standard}
implement_commutate! {Standard, Square, Standard}
implement_commutate! {Standard, UpperTriangle, Standard}
implement_commutate! {Standard, LowerTriangle, Standard}
implement_commutate! {Standard, Diagonal, Standard}
implement_commutate! {Standard, PositiveDefinite, Standard}
implement_commutate! {Standard, PositiveSemiDefinite, Standard}

implement! {Square, Square, Square}
implement_commutate! {Square, UpperTriangle, Square}
implement_commutate! {Square, LowerTriangle, Square}
implement_commutate! {Square, Diagonal, Square}
implement_commutate! {Square, PositiveDefinite, Square}
implement_commutate! {Square, PositiveSemiDefinite, Square}

implement! {UpperTriangle, UpperTriangle, UpperTriangle}
implement_commutate! {UpperTriangle, LowerTriangle, Square}
implement_commutate! {UpperTriangle, Diagonal, UpperTriangle}
implement_commutate! {UpperTriangle,PositiveDefinite, Square}
implement_commutate! {UpperTriangle, PositiveSemiDefinite, Square}

implement! {LowerTriangle, LowerTriangle, LowerTriangle}
implement_commutate! {LowerTriangle, Diagonal, LowerTriangle}
implement_commutate! {LowerTriangle, PositiveDefinite, Square}
implement_commutate! {LowerTriangle, PositiveSemiDefinite, Square}

implement! {Diagonal, PositiveDefinite, Square}
implement_commutate! {Diagonal, PositiveSemiDefinite, Square}

implement! {PositiveDefinite, PositiveDefinite, Square}
implement_commutate! {PositiveDefinite, PositiveSemiDefinite, Square}

implement! {PositiveSemiDefinite, PositiveSemiDefinite, Square}