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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
use super::*;
use std::marker;
use crate::TransformContent;

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

			impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber>
					ComplexToRealTransformsOps<T> for $matrix<V, S, T>
					where <V as ToRealResult>::RealResult: Vector<T>,
                          V: ComplexToRealTransformsOps<T> {
				fn magnitude(self) -> Self::RealResult {
					let rows = self.rows.transform(|v|v.magnitude());
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn magnitude_squared(self) -> Self::RealResult {
                    let rows = self.rows.transform(|v|v.magnitude_squared());
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn to_real(self) -> Self::RealResult {
                    let rows = self.rows.transform(|v|v.to_real());
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn to_imag(self) -> Self::RealResult {
                    let rows = self.rows.transform(|v|v.to_imag());
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn phase(self) -> Self::RealResult {
                    let rows = self.rows.transform(|v|v.phase());
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}
			}

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

				fn magnitude_squared_b<B>(self, buffer: &mut B) -> Self::RealResult
                    where B: for<'b> Buffer<'b, S, T> {
                    let rows = self.rows.transform(|v|v.magnitude_squared_b(buffer));
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn to_real_b<B>(self, buffer: &mut B) -> Self::RealResult
                    where B: for<'b> Buffer<'b, S, T> {
                    let rows = self.rows.transform(|v|v.to_real_b(buffer));
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn to_imag_b<B>(self, buffer: &mut B) -> Self::RealResult
                    where B: for<'b> Buffer<'b, S, T> {
                    let rows = self.rows.transform(|v|v.to_imag_b(buffer));
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}

				fn phase_b<B>(self, buffer: &mut B) -> Self::RealResult
                    where B: for<'b> Buffer<'b, S, T> {
                    let rows = self.rows.transform(|v|v.phase_b(buffer));
                    $matrix {
                        rows: rows,
                        storage_type: marker::PhantomData,
                	  	number_type: marker::PhantomData
                    }
				}
			}

			impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber, N: NumberSpace, D: Domain, O>
					ComplexToRealGetterOps<O, T, N, D> for $matrix<V, S, T>
					where O: Matrix<V, T> + GetMetaData<T, N, D>,
                          V: ComplexToRealGetterOps<V, T, N, D> + GetMetaData<T, N, D> {
				fn get_real(&self, destination: &mut O) {
                    for (o, v) in destination.rows_mut().iter_mut().zip(self.rows()) {
						v.get_real(o);
					}
				}

				fn get_imag(&self, destination: &mut O) {
                    for (o, v) in destination.rows_mut().iter_mut().zip(self.rows()) {
						v.get_imag(o);
					}
				}

				fn get_magnitude(&self, destination: &mut O) {
                    for (o, v) in destination.rows_mut().iter_mut().zip(self.rows()) {
						v.get_imag(o);
					}
				}

				fn get_magnitude_squared(&self, destination: &mut O) {
                    for (o, v) in destination.rows_mut().iter_mut().zip(self.rows()) {
						v.get_imag(o);
					}
				}

				fn get_phase(&self, destination: &mut O) {
                    for (o, v) in destination.rows_mut().iter_mut().zip(self.rows()) {
						v.get_imag(o);
					}
				}

				fn get_real_imag(&self,
                                 real: &mut O,
                                 imag: &mut O) {
                    for ((r, i), v) in real.rows_mut().iter_mut()
                                    .zip(imag.rows_mut())
                                    .zip(self.rows()) {
 						v.get_real_imag(r, i);
 					}
				}

				fn get_mag_phase(&self,
                                 mag: &mut O,
                                 phase: &mut O) {
                    for ((r, i), v) in mag.rows_mut().iter_mut()
                                     .zip(phase.rows_mut())
                                     .zip(self.rows()) {
  						v.get_mag_phase(r, i);
  					}
				}
			}

            impl<V: Vector<T>, S: ToSlice<T>, T: RealNumber, N: NumberSpace, D: Domain, O>
					ComplexToRealSetterOps<O, T, N, D> for $matrix<V, S, T>
					where O: Matrix<V, T> + GetMetaData<T, N, D>,
                          V: ComplexToRealSetterOps<V, T, N, D> + GetMetaData<T, N, D> {
				fn set_real_imag(&mut self,
                                 real: &O,
                                 imag: &O) -> VoidResult {
                    for ((v, r), i) in self.rows_mut().iter_mut()
                                    .zip(real.rows())
                                    .zip(imag.rows()) {
 						v.set_real_imag(r, i)?;
 					}

                    Ok(())
				}

				fn set_mag_phase(&mut self,
                                 mag: &O,
                                 phase: &O) -> VoidResult {
                    for ((v, r), i) in self.rows_mut().iter_mut()
                                     .zip(mag.rows())
                                     .zip(phase.rows()) {
  						v.set_mag_phase(r, i)?;
  					}

                    Ok(())
				}
			}

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

				fn conj(&mut self) {
                    for v in self.rows_mut() {
                        v.conj();
                    }
				}
			}
		)*
	}
}

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