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
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use super::*;
use std::marker;
use crate::TransformContent;

macro_rules! try_transform {
    ($op: expr, $matrix: ident) => {{
        match $op {
            Ok(rows) => Ok($matrix {
                rows: rows,
                storage_type: marker::PhantomData,
                number_type: marker::PhantomData,
            }),
            Err((r, rows)) => Err((
                r,
                $matrix {
                    rows: rows,
                    storage_type: marker::PhantomData,
                    number_type: marker::PhantomData,
                },
            )),
        }
    }};
}

macro_rules! add_mat_impl {
    ($($matrix:ident);*) => {
        $(
			impl <V: Vector<T> + ToComplexResult, S: ToSlice<T>, T: RealNumber>
				ToComplexResult for $matrix<V, S, T>
				where <V as ToComplexResult>::ComplexResult: Vector<T> {
					type ComplexResult = $matrix<V::ComplexResult, S, T>;
			}

			impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber>
					RealToComplexTransformsOps<T> for $matrix<V, S, T>
					where <V as ToComplexResult>::ComplexResult: Vector<T>,
                          V: RealToComplexTransformsOps<T> {
				fn to_complex(self) -> TransRes<Self::ComplexResult> {
					let rows = self.rows.transform_res(|v|v.to_complex());
					try_transform!(rows, $matrix)
				}
			}

			impl<V: Vector<T>, S: ToSliceMut<T>, T: RealNumber>
					RealToComplexTransformsOpsBuffered<S, T> for $matrix<V, S, T>
					where <V as ToComplexResult>::ComplexResult: Vector<T>,
                          V: RealToComplexTransformsOpsBuffered<S, T> {
				fn to_complex_b<B>(self, buffer: &mut B) -> Self::ComplexResult
                    where B: for<'b> Buffer<'b, S, T> {
					let rows = self.rows.transform(|v|v.to_complex_b(buffer));
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}
			}

			impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber> RealOps
                    for $matrix<V, S, T>
                    where V: RealOps {
				fn abs(&mut self) {
                    for v in self.rows_mut() {
                        v.abs();
                    }
				}
			}

			impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber> ModuloOps<T>
                    for $matrix<V, S, T>
                    where V: ModuloOps<T> {
				fn wrap(&mut self, divisor: T) {
                    for v in self.rows_mut() {
                        v.wrap(divisor);
                    }
				}

				fn unwrap(&mut self, divisor: T) {
                    for v in self.rows_mut() {
                        v.unwrap(divisor);
                    }
				}
			}

			impl<S: ToSlice<T>, V: Vector<T> + ApproximatedOps<T>, T: RealNumber>
					ApproximatedOps<T> for $matrix<V, S, T> {
				fn ln_approx(&mut self)  {
					for v in self.rows_mut() {
						v.ln_approx()
					}
				}

				fn exp_approx(&mut self)  {
					for v in self.rows_mut() {
						v.exp_approx()
					}
				}

				fn sin_approx(&mut self)  {
					for v in self.rows_mut() {
						v.sin_approx()
					}
				}

				fn cos_approx(&mut self)  {
					for v in self.rows_mut() {
						v.cos_approx()
					}
				}

				fn log_approx(&mut self, base: T)  {
					for v in self.rows_mut() {
						v.log_approx(base)
					}
				}

				fn expf_approx(&mut self, base: T)  {
					for v in self.rows_mut() {
						v.expf_approx(base)
					}
				}

				fn powf_approx(&mut self, exponent: T)  {
					for v in self.rows_mut() {
						v.powf_approx(exponent)
					}
				}
			}
		)*
	}
}

add_mat_impl!(MatrixMxN; Matrix2xN; Matrix3xN; Matrix4xN);