basic_dsp_matrix/
to_from_mat_conversions.rs

1use super::*;
2use crate::TransformContent;
3use std::marker;
4
5/// Conversion from a collection of vectors to a matrix.
6pub trait ToMatrix<V, T>
7where
8    V: Vector<T>,
9    T: RealNumber,
10{
11    type Output: Matrix<V, T>;
12
13    /// Create a new matrix from a collection of vectors.
14    fn to_mat(self) -> Self::Output;
15}
16
17/// Conversion from a generic data type into a dsp matrix which tracks
18/// its meta information (domain and number space)
19/// only at runtime. See `ToRealMatrix` and
20/// `ToComplexMatrix` for alternatives which track most of the meta data
21/// with the type system and therefore avoid runtime errors.
22pub trait ToDspMatrix<V, T>
23where
24    V: Vector<T>,
25    T: RealNumber,
26{
27    type Output: Matrix<V, T>;
28
29    /// Create a new generic matrix.
30    /// `delta` can be changed after construction with a call of `set_delta`.
31    ///
32    /// For complex matrices with an odd length the resulting value will have a zero length.
33    fn to_gen_dsp_mat(self, is_complex: bool, domain: DataDomain) -> Self::Output;
34}
35
36/// Conversion from a generic data type into a dsp matrix with real data.
37pub trait ToRealTimeMatrix<V, T>
38where
39    V: Vector<T>,
40    T: RealNumber,
41{
42    type Output: Matrix<V, T>;
43
44    /// Create a new matrix in real number space and time domain.
45    /// `delta` can be changed after construction with a call of `set_delta`.
46    fn to_real_time_mat(self) -> Self::Output;
47}
48
49/// Conversion from a generic data type into a dsp matrix with real data.
50pub trait ToRealFreqMatrix<V, T>
51where
52    V: Vector<T>,
53    T: RealNumber,
54{
55    type Output: Matrix<V, T>;
56
57    /// Create a new vector in real number space and frequency domain.
58    /// `delta` can be changed after construction with a call of `set_delta`.
59    fn to_real_freq_mat(self) -> Self::Output;
60}
61
62/// Conversion from a generic data type into a dsp vector with complex data.
63pub trait ToComplexTimeMatrix<V, T>
64where
65    V: Vector<T>,
66    T: RealNumber,
67{
68    type Output: Matrix<V, T>;
69
70    /// Create a new matrix in complex number space and time domain.
71    /// `delta` can be changed after construction with a call of `set_delta`.
72    ///
73    /// For complex matrices with an odd length the resulting value will have a zero length.
74    fn to_complex_time_mat(self) -> Self::Output;
75}
76
77/// Conversion from a generic data type into a dsp vector with complex data.
78pub trait ToComplexFreqMatrix<V, T>
79where
80    V: Vector<T>,
81    T: RealNumber,
82{
83    type Output: Matrix<V, T>;
84
85    /// Create a new matrix in complex number space and frequency domain.
86    /// `delta` can be changed after construction with a call of `set_delta`.
87    ///
88    /// For complex matrices with an odd length the resulting value will have a zero length.
89    fn to_complex_freq_mat(self) -> Self::Output;
90}
91
92/// Retrieves the underlying storage from a matrix.
93pub trait FromMatrix<T>
94where
95    T: RealNumber,
96{
97    /// Type of the underlying storage of a matrix.
98    type Output;
99
100    /// Gets the underlying matrix and the number of elements which
101    /// contain valid.
102    fn get(self) -> (Self::Output, usize);
103}
104
105fn to_mat_mxn<S, F, V, T>(source: Vec<S>, conversion: F) -> MatrixMxN<V, S, T>
106where
107    S: ToSlice<T>,
108    V: Vector<T>,
109    T: RealNumber,
110    F: Fn(S) -> V,
111{
112    let rows = source.transform(conversion);
113    MatrixMxN {
114        rows,
115        storage_type: marker::PhantomData,
116        number_type: marker::PhantomData,
117    }
118}
119
120fn to_mat_2xn<S, F, V, T>(source: [S; 2], conversion: F) -> Matrix2xN<V, S, T>
121where
122    S: ToSlice<T>,
123    V: Vector<T>,
124    T: RealNumber,
125    F: Fn(S) -> V,
126{
127    let rows = source.transform(conversion);
128    Matrix2xN {
129        rows,
130        storage_type: marker::PhantomData,
131        number_type: marker::PhantomData,
132    }
133}
134
135fn to_mat_3xn<S, F, V, T>(source: [S; 3], conversion: F) -> Matrix3xN<V, S, T>
136where
137    S: ToSlice<T>,
138    V: Vector<T>,
139    T: RealNumber,
140    F: Fn(S) -> V,
141{
142    let rows = source.transform(conversion);
143    Matrix3xN {
144        rows,
145        storage_type: marker::PhantomData,
146        number_type: marker::PhantomData,
147    }
148}
149
150fn to_mat_4xn<S, F, V, T>(source: [S; 4], conversion: F) -> Matrix4xN<V, S, T>
151where
152    S: ToSlice<T>,
153    V: Vector<T>,
154    T: RealNumber,
155    F: Fn(S) -> V,
156{
157    let rows = source.transform(conversion);
158    Matrix4xN {
159        rows,
160        storage_type: marker::PhantomData,
161        number_type: marker::PhantomData,
162    }
163}
164
165impl<S, T, N, D> ToMatrix<DspVec<S, T, N, D>, T> for Vec<DspVec<S, T, N, D>>
166where
167    S: ToSlice<T>,
168    T: RealNumber,
169    N: NumberSpace,
170    D: Domain,
171{
172    type Output = MatrixMxN<DspVec<S, T, N, D>, S, T>;
173
174    fn to_mat(self) -> Self::Output {
175        MatrixMxN {
176            rows: self,
177            storage_type: marker::PhantomData,
178            number_type: marker::PhantomData,
179        }
180    }
181}
182
183impl<S, T, N, D> ToMatrix<DspVec<S, T, N, D>, T> for [DspVec<S, T, N, D>; 2]
184where
185    S: ToSlice<T>,
186    T: RealNumber,
187    N: NumberSpace,
188    D: Domain,
189{
190    type Output = Matrix2xN<DspVec<S, T, N, D>, S, T>;
191
192    fn to_mat(self) -> Self::Output {
193        Matrix2xN {
194            rows: self,
195            storage_type: marker::PhantomData,
196            number_type: marker::PhantomData,
197        }
198    }
199}
200
201impl<S, T, N, D> ToMatrix<DspVec<S, T, N, D>, T> for [DspVec<S, T, N, D>; 3]
202where
203    S: ToSlice<T>,
204    T: RealNumber,
205    N: NumberSpace,
206    D: Domain,
207{
208    type Output = Matrix3xN<DspVec<S, T, N, D>, S, T>;
209
210    fn to_mat(self) -> Self::Output {
211        Matrix3xN {
212            rows: self,
213            storage_type: marker::PhantomData,
214            number_type: marker::PhantomData,
215        }
216    }
217}
218
219impl<S, T, N, D> ToMatrix<DspVec<S, T, N, D>, T> for [DspVec<S, T, N, D>; 4]
220where
221    S: ToSlice<T>,
222    T: RealNumber,
223    N: NumberSpace,
224    D: Domain,
225{
226    type Output = Matrix4xN<DspVec<S, T, N, D>, S, T>;
227
228    fn to_mat(self) -> Self::Output {
229        Matrix4xN {
230            rows: self,
231            storage_type: marker::PhantomData,
232            number_type: marker::PhantomData,
233        }
234    }
235}
236
237impl<T, S> ToDspMatrix<GenDspVec<S, T>, T> for Vec<S>
238where
239    T: RealNumber,
240    S: ToDspVector<T> + ToSlice<T>,
241{
242    type Output = MatrixMxN<GenDspVec<S, T>, S, T>;
243
244    fn to_gen_dsp_mat(self, is_complex: bool, domain: DataDomain) -> Self::Output {
245        to_mat_mxn(self, |v| v.to_gen_dsp_vec(is_complex, domain))
246    }
247}
248
249impl<T, S> ToDspMatrix<GenDspVec<S, T>, T> for [S; 2]
250where
251    T: RealNumber,
252    S: ToDspVector<T> + ToSlice<T>,
253{
254    type Output = Matrix2xN<GenDspVec<S, T>, S, T>;
255
256    fn to_gen_dsp_mat(self, is_complex: bool, domain: DataDomain) -> Self::Output {
257        to_mat_2xn(self, |v| v.to_gen_dsp_vec(is_complex, domain))
258    }
259}
260
261impl<T, S> ToDspMatrix<GenDspVec<S, T>, T> for [S; 3]
262where
263    T: RealNumber,
264    S: ToDspVector<T> + ToSlice<T>,
265{
266    type Output = Matrix3xN<GenDspVec<S, T>, S, T>;
267
268    fn to_gen_dsp_mat(self, is_complex: bool, domain: DataDomain) -> Self::Output {
269        to_mat_3xn(self, |v| v.to_gen_dsp_vec(is_complex, domain))
270    }
271}
272
273impl<T, S> ToDspMatrix<GenDspVec<S, T>, T> for [S; 4]
274where
275    T: RealNumber,
276    S: ToDspVector<T> + ToSlice<T>,
277{
278    type Output = Matrix4xN<GenDspVec<S, T>, S, T>;
279
280    fn to_gen_dsp_mat(self, is_complex: bool, domain: DataDomain) -> Self::Output {
281        to_mat_4xn(self, |v| v.to_gen_dsp_vec(is_complex, domain))
282    }
283}
284
285impl<T, S> ToRealTimeMatrix<RealTimeVec<S, T>, T> for Vec<S>
286where
287    T: RealNumber,
288    S: ToRealVector<T> + ToSlice<T>,
289{
290    type Output = MatrixMxN<RealTimeVec<S, T>, S, T>;
291
292    fn to_real_time_mat(self) -> Self::Output {
293        to_mat_mxn(self, |v| v.to_real_time_vec())
294    }
295}
296
297impl<T, S> ToRealTimeMatrix<RealTimeVec<S, T>, T> for [S; 2]
298where
299    T: RealNumber,
300    S: ToRealVector<T> + ToSlice<T>,
301{
302    type Output = Matrix2xN<RealTimeVec<S, T>, S, T>;
303
304    fn to_real_time_mat(self) -> Self::Output {
305        to_mat_2xn(self, |v| v.to_real_time_vec())
306    }
307}
308
309impl<T, S> ToRealTimeMatrix<RealTimeVec<S, T>, T> for [S; 3]
310where
311    T: RealNumber,
312    S: ToRealVector<T> + ToSlice<T>,
313{
314    type Output = Matrix3xN<RealTimeVec<S, T>, S, T>;
315
316    fn to_real_time_mat(self) -> Self::Output {
317        to_mat_3xn(self, |v| v.to_real_time_vec())
318    }
319}
320
321impl<T, S> ToRealTimeMatrix<RealTimeVec<S, T>, T> for [S; 4]
322where
323    T: RealNumber,
324    S: ToRealVector<T> + ToSlice<T>,
325{
326    type Output = Matrix4xN<RealTimeVec<S, T>, S, T>;
327
328    fn to_real_time_mat(self) -> Self::Output {
329        to_mat_4xn(self, |v| v.to_real_time_vec())
330    }
331}
332
333impl<T, S> ToRealFreqMatrix<RealFreqVec<S, T>, T> for Vec<S>
334where
335    T: RealNumber,
336    S: ToRealVector<T> + ToSlice<T>,
337{
338    type Output = MatrixMxN<RealFreqVec<S, T>, S, T>;
339
340    fn to_real_freq_mat(self) -> Self::Output {
341        to_mat_mxn(self, |v| v.to_real_freq_vec())
342    }
343}
344
345impl<T, S> ToRealFreqMatrix<RealFreqVec<S, T>, T> for [S; 2]
346where
347    T: RealNumber,
348    S: ToRealVector<T> + ToSlice<T>,
349{
350    type Output = Matrix2xN<RealFreqVec<S, T>, S, T>;
351
352    fn to_real_freq_mat(self) -> Self::Output {
353        to_mat_2xn(self, |v| v.to_real_freq_vec())
354    }
355}
356
357impl<T, S> ToRealFreqMatrix<RealFreqVec<S, T>, T> for [S; 3]
358where
359    T: RealNumber,
360    S: ToRealVector<T> + ToSlice<T>,
361{
362    type Output = Matrix3xN<RealFreqVec<S, T>, S, T>;
363
364    fn to_real_freq_mat(self) -> Self::Output {
365        to_mat_3xn(self, |v| v.to_real_freq_vec())
366    }
367}
368
369impl<T, S> ToRealFreqMatrix<RealFreqVec<S, T>, T> for [S; 4]
370where
371    T: RealNumber,
372    S: ToRealVector<T> + ToSlice<T>,
373{
374    type Output = Matrix4xN<RealFreqVec<S, T>, S, T>;
375
376    fn to_real_freq_mat(self) -> Self::Output {
377        to_mat_4xn(self, |v| v.to_real_freq_vec())
378    }
379}
380
381impl<T, S> ToComplexTimeMatrix<ComplexTimeVec<S, T>, T> for Vec<S>
382where
383    T: RealNumber,
384    S: ToComplexVector<S, T> + ToSlice<T>,
385{
386    type Output = MatrixMxN<ComplexTimeVec<S, T>, S, T>;
387
388    fn to_complex_time_mat(self) -> Self::Output {
389        to_mat_mxn(self, |v| v.to_complex_time_vec())
390    }
391}
392
393impl<T, S> ToComplexTimeMatrix<ComplexTimeVec<S, T>, T> for [S; 2]
394where
395    T: RealNumber,
396    S: ToComplexVector<S, T> + ToSlice<T>,
397{
398    type Output = Matrix2xN<ComplexTimeVec<S, T>, S, T>;
399
400    fn to_complex_time_mat(self) -> Self::Output {
401        to_mat_2xn(self, |v| v.to_complex_time_vec())
402    }
403}
404
405impl<T, S> ToComplexTimeMatrix<ComplexTimeVec<S, T>, T> for [S; 3]
406where
407    T: RealNumber,
408    S: ToComplexVector<S, T> + ToSlice<T>,
409{
410    type Output = Matrix3xN<ComplexTimeVec<S, T>, S, T>;
411
412    fn to_complex_time_mat(self) -> Self::Output {
413        to_mat_3xn(self, |v| v.to_complex_time_vec())
414    }
415}
416
417impl<T, S> ToComplexTimeMatrix<ComplexTimeVec<S, T>, T> for [S; 4]
418where
419    T: RealNumber,
420    S: ToComplexVector<S, T> + ToSlice<T>,
421{
422    type Output = Matrix4xN<ComplexTimeVec<S, T>, S, T>;
423
424    fn to_complex_time_mat(self) -> Self::Output {
425        to_mat_4xn(self, |v| v.to_complex_time_vec())
426    }
427}
428
429impl<V, S, T> FromMatrix<T> for MatrixMxN<V, S, T>
430where
431    T: RealNumber,
432    V: Vector<T>,
433    S: ToSlice<T>,
434{
435    type Output = Vec<V>;
436
437    fn get(self) -> (Self::Output, usize) {
438        let len = self.row_len();
439        (self.rows, len)
440    }
441}
442
443impl<V, S, T> FromMatrix<T> for Matrix2xN<V, S, T>
444where
445    T: RealNumber,
446    V: Vector<T>,
447    S: ToSlice<T>,
448{
449    type Output = [V; 2];
450
451    fn get(self) -> (Self::Output, usize) {
452        let len = self.row_len();
453        (self.rows, len)
454    }
455}
456
457impl<V, S, T> FromMatrix<T> for Matrix3xN<V, S, T>
458where
459    T: RealNumber,
460    V: Vector<T>,
461    S: ToSlice<T>,
462{
463    type Output = [V; 3];
464
465    fn get(self) -> (Self::Output, usize) {
466        let len = self.row_len();
467        (self.rows, len)
468    }
469}
470
471impl<V, S, T> FromMatrix<T> for Matrix4xN<V, S, T>
472where
473    T: RealNumber,
474    V: Vector<T>,
475    S: ToSlice<T>,
476{
477    type Output = [V; 4];
478
479    fn get(self) -> (Self::Output, usize) {
480        let len = self.row_len();
481        (self.rows, len)
482    }
483}
484
485#[cfg(test)]
486mod tests {
487    use super::super::*;
488
489    #[test]
490    fn to_gen_dsp_mat_test() {
491        let mat: MatrixMxN<_, _, _> =
492            vec![vec![0.0, 1.0], vec![2.0, 3.0]].to_gen_dsp_mat(false, DataDomain::Time);
493        assert_eq!(mat.rows[0].data(..), &[0.0, 1.0]);
494        assert_eq!(mat.rows[1].data(..), &[2.0, 3.0]);
495
496        let mat: Matrix2xN<_, _, _> =
497            [vec![0.0, 1.0], vec![2.0, 3.0]].to_gen_dsp_mat(false, DataDomain::Time);
498        assert_eq!(mat.rows[0].data(..), &[0.0, 1.0]);
499        assert_eq!(mat.rows[1].data(..), &[2.0, 3.0]);
500    }
501}