basic_dsp_matrix/
lib.rs

1//! In this lib a matrix is simply a collection of
2//! vectors. The idea is that the matrix types can be used to reduce the size
3//! of a large matrix and that the return types are basic enough
4//! so that other specialized matrix libs can do the rest of the work, e.g.
5//! inverting the resulting matrix.
6
7extern crate basic_dsp_vector;
8
9use basic_dsp_vector::numbers::*;
10use basic_dsp_vector::*;
11use std::{mem::ManuallyDrop, ptr};
12
13mod mat_impl;
14pub use self::mat_impl::*;
15mod to_from_mat_conversions;
16pub use self::to_from_mat_conversions::*;
17mod complex;
18mod general;
19mod real;
20mod rededicate;
21mod time_freq;
22
23/// A matrix which can hold 1 to N vectors.
24pub struct MatrixMxN<V, S, T>
25where
26    T: RealNumber,
27    S: ToSlice<T>,
28    V: Vector<T>,
29{
30    rows: Vec<V>,
31    storage_type: std::marker::PhantomData<S>,
32    number_type: std::marker::PhantomData<T>,
33}
34
35/// A matrix which can hold exactly 2 vectors.
36pub struct Matrix2xN<V, S, T>
37where
38    T: RealNumber,
39    V: Vector<T>,
40{
41    rows: [V; 2],
42    storage_type: std::marker::PhantomData<S>,
43    number_type: std::marker::PhantomData<T>,
44}
45
46/// A matrix which can hold exactly 3 vectors.
47pub struct Matrix3xN<V, S, T>
48where
49    T: RealNumber,
50    V: Vector<T>,
51{
52    rows: [V; 3],
53    storage_type: std::marker::PhantomData<S>,
54    number_type: std::marker::PhantomData<T>,
55}
56
57/// A matrix which can hold exactly 4 vectors.
58pub struct Matrix4xN<V, S, T>
59where
60    T: RealNumber,
61    V: Vector<T>,
62{
63    rows: [V; 4],
64    storage_type: std::marker::PhantomData<S>,
65    number_type: std::marker::PhantomData<T>,
66}
67
68/// A matrix which can hold 1 to N vectors of 32 bit floating point numbers in any number space or domain.
69pub type Matrix32xN = MatrixMxN<GenDspVec32, Vec<f32>, f32>;
70/// A matrix which can hold 1 to N vectors of 64 bit floating point numbers in any number space or domain.
71pub type Matrix64xN = MatrixMxN<GenDspVec64, Vec<f64>, f64>;
72/// A matrix which can hold 1 to N vectors of 32 bit floating point numbers in real number space and time domain.
73pub type RealTimeMatrix32xN = MatrixMxN<RealTimeVec32, Vec<f32>, f32>;
74/// A matrix which can hold 1 to N vectors of 64 bit floating point numbers in real number space and time domain.
75pub type RealTimeMatrix64xN = MatrixMxN<RealTimeVec64, Vec<f64>, f64>;
76/// A matrix which can hold 1 to N vectors of 32 bit floating point numbers in complex number space and time domain.
77pub type ComplexTimeMatrix32xN = MatrixMxN<ComplexTimeVec32, Vec<f32>, f32>;
78/// A matrix which can hold 1 to N vectors of 64 bit floating point numbers in complex number space and time domain.
79pub type ComplexTimeMatrix64xN = MatrixMxN<ComplexTimeVec64, Vec<f64>, f64>;
80/// A matrix which can hold 1 to N vectors of 32 bit floating point numbers in real number space and frequency domain.
81pub type RealFreqMatrix32xN = MatrixMxN<RealFreqVec32, Vec<f32>, f32>;
82/// A matrix which can hold 1 to N vectors of 64 bit floating point numbers in real number space and frequency domain.
83pub type RealFreqMatrix64xN = MatrixMxN<RealFreqVec64, Vec<f64>, f64>;
84/// A matrix which can hold 1 to N vectors of 32 bit floating point numbers in complex number space and frequency domain.
85pub type ComplexFreqMatrix32xN = MatrixMxN<ComplexFreqVec32, Vec<f32>, f32>;
86/// A matrix which can hold 1 to N vectors of 64 bit floating point numbers in complex number space and frequency domain.
87pub type ComplexFreqMatrix64xN = MatrixMxN<ComplexFreqVec64, Vec<f64>, f64>;
88
89/// A matrix which can hold exactly 2 vectors of 32 bit floating point numbers in any number space or domain.
90pub type Matrix32x2 = Matrix2xN<GenDspVec32, Vec<f32>, f32>;
91/// A matrix which can hold exactly 2 vectors of 64 bit floating point numbers in any number space or domain.
92pub type Matrix64x2 = Matrix2xN<GenDspVec64, Vec<f64>, f64>;
93/// A matrix which can hold exactly 2 vectors of 32 bit floating point numbers in real number space and time domain.
94pub type RealTimeMatrix32x2 = Matrix2xN<RealTimeVec32, Vec<f32>, f32>;
95/// A matrix which can hold exactly 2 vectors of 64 bit floating point numbers in real number space and time domain.
96pub type RealTimeMatrix64x2 = Matrix2xN<RealTimeVec64, Vec<f64>, f64>;
97/// A matrix which can hold exactly 2 vectors of 32 bit floating point numbers in complex number space and time domain.
98pub type ComplexTimeMatrix32x2 = Matrix2xN<ComplexTimeVec32, Vec<f32>, f32>;
99/// A matrix which can hold exactly 2 vectors of 64 bit floating point numbers in complex number space and time domain.
100pub type ComplexTimeMatrix64x2 = Matrix2xN<ComplexTimeVec64, Vec<f64>, f64>;
101/// A matrix which can hold exactly 2 vectors of 32 bit floating point numbers in real number space and frequency domain.
102pub type RealFreqMatrix32x2 = Matrix2xN<RealFreqVec32, Vec<f32>, f32>;
103/// A matrix which can hold exactly 2 vectors of 64 bit floating point numbers in real number space and frequency domain.
104pub type RealFreqMatrix64x2 = Matrix2xN<RealFreqVec64, Vec<f64>, f64>;
105/// A matrix which can hold exactly 2 vectors of 32 bit floating point numbers in complex number space and frequency domain.
106pub type ComplexFreqMatrix32x2 = Matrix2xN<ComplexFreqVec32, Vec<f32>, f32>;
107/// A matrix which can hold exactly 2 vectors of 64 bit floating point numbers in complex number space and frequency domain.
108pub type ComplexFreqMatrix64x2 = Matrix2xN<ComplexFreqVec64, Vec<f64>, f64>;
109
110/// A matrix which can hold exactly 3 vectors of 32 bit floating point numbers in any number space or domain.
111pub type Matrix32x3 = Matrix3xN<GenDspVec32, Vec<f32>, f32>;
112/// A matrix which can hold exactly 3 vectors of 64 bit floating point numbers in any number space or domain.
113pub type Matrix64x3 = Matrix3xN<GenDspVec64, Vec<f64>, f64>;
114/// A matrix which can hold exactly 3 vectors of 32 bit floating point numbers in real number space and time domain.
115pub type RealTimeMatrix32x3 = Matrix3xN<RealTimeVec32, Vec<f32>, f32>;
116/// A matrix which can hold exactly 3 vectors of 64 bit floating point numbers in real number space and time domain.
117pub type RealTimeMatrix64x3 = Matrix3xN<RealTimeVec64, Vec<f64>, f64>;
118/// A matrix which can hold exactly 3 vectors of 32 bit floating point numbers in complex number space and time domain.
119pub type ComplexTimeMatrix32x3 = Matrix3xN<ComplexTimeVec32, Vec<f32>, f32>;
120/// A matrix which can hold exactly 3 vectors of 64 bit floating point numbers in complex number space and time domain.
121pub type ComplexTimeMatrix64x3 = Matrix3xN<ComplexTimeVec64, Vec<f64>, f64>;
122/// A matrix which can hold exactly 3 vectors of 32 bit floating point numbers in real number space and frequency domain.
123pub type RealFreqMatrix32x3 = Matrix3xN<RealFreqVec32, Vec<f32>, f32>;
124/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in real number space and frequency domain.
125pub type RealFreqMatrix64x3 = Matrix3xN<RealFreqVec64, Vec<f64>, f64>;
126/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in complex number space and frequency domain.
127pub type ComplexFreqMatrix32x3 = Matrix3xN<ComplexFreqVec32, Vec<f32>, f32>;
128/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in complex number space and frequency domain.
129pub type ComplexFreqMatrix64x3 = Matrix3xN<ComplexFreqVec64, Vec<f64>, f64>;
130
131/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in any number space or domain.
132pub type Matrix32x4 = Matrix4xN<GenDspVec32, Vec<f32>, f32>;
133/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in any number space or domain.
134pub type Matrix64x4 = Matrix4xN<GenDspVec64, Vec<f64>, f64>;
135/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in real number space and time domain.
136pub type RealTimeMatrix32x4 = Matrix4xN<RealTimeVec32, Vec<f32>, f32>;
137/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in real number space and time domain.
138pub type RealTimeMatrix64x4 = Matrix4xN<RealTimeVec64, Vec<f64>, f64>;
139/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in complex number space and time domain.
140pub type ComplexTimeMatrix32x4 = Matrix4xN<ComplexTimeVec32, Vec<f32>, f32>;
141/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in complex number space and time domain.
142pub type ComplexTimeMatrix64x4 = Matrix4xN<ComplexTimeVec64, Vec<f64>, f64>;
143/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in real number space and frequency domain.
144pub type RealFreqMatrix32x4 = Matrix4xN<RealFreqVec32, Vec<f32>, f32>;
145/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in real number space and frequency domain.
146pub type RealFreqMatrix64x4 = Matrix4xN<RealFreqVec64, Vec<f64>, f64>;
147/// A matrix which can hold exactly 4 vectors of 32 bit floating point numbers in complex number space and frequency domain.
148pub type ComplexFreqMatrix32x4 = Matrix4xN<ComplexFreqVec32, Vec<f32>, f32>;
149/// A matrix which can hold exactly 4 vectors of 64 bit floating point numbers in complex number space and frequency domain.
150pub type ComplexFreqMatrix64x4 = Matrix4xN<ComplexFreqVec64, Vec<f64>, f64>;
151
152/// Internal trait to transform a row storage type to another
153trait TransformContent<S, D> {
154    type Output;
155    fn transform<F>(self, conversion: F) -> Self::Output
156    where
157        F: FnMut(S) -> D;
158    fn transform_res<F>(self, conversion: F) -> TransRes<Self::Output>
159    where
160        F: FnMut(S) -> TransRes<D>;
161}
162
163trait IntoFixedLength<T, O> {
164    fn into_fixed_length(self) -> O;
165}
166
167impl<T> IntoFixedLength<T, Vec<T>> for Vec<T> {
168    fn into_fixed_length(self) -> Vec<T> {
169        self
170    }
171}
172
173macro_rules! try_conv {
174    ($op: expr, $err: ident) => {{
175        let res = $op;
176        match res {
177            Ok(v) => v,
178            Err((r, v)) => {
179                $err = Some(r);
180                v
181            }
182        }
183    }};
184}
185
186impl<S, D> TransformContent<S, D> for Vec<S> {
187    type Output = Vec<D>;
188
189    fn transform<F>(mut self, mut conversion: F) -> Self::Output
190    where
191        F: FnMut(S) -> D,
192    {
193        let mut rows: Vec<D> = Vec::with_capacity(self.len());
194        for _ in 0..self.len() {
195            let v: S = self.pop().unwrap();
196            rows.push(conversion(v));
197        }
198        rows.reverse();
199        rows
200    }
201
202    fn transform_res<F>(mut self, mut conversion: F) -> TransRes<Self::Output>
203    where
204        F: FnMut(S) -> TransRes<D>,
205    {
206        let mut rows: Vec<D> = Vec::with_capacity(self.len());
207        let mut error = None;
208        for _ in 0..self.len() {
209            let v: S = self.pop().unwrap();
210            rows.push(try_conv!(conversion(v), error));
211        }
212        rows.reverse();
213
214        match error {
215            None => Ok(rows),
216            Some(err) => Err((err, rows)),
217        }
218    }
219}
220
221impl<S, D> TransformContent<S, D> for [S; 2] {
222    type Output = [D; 2];
223
224    fn transform<F>(self, mut conversion: F) -> Self::Output
225    where
226        F: FnMut(S) -> D,
227    {
228        let self_forget = ManuallyDrop::new(self);
229        unsafe {
230            [
231                conversion(ptr::read(&self_forget[0])),
232                conversion(ptr::read(&self_forget[1])),
233            ]
234        }
235    }
236
237    fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
238    where
239        F: FnMut(S) -> TransRes<D>,
240    {
241        let self_forget = ManuallyDrop::new(self);
242        unsafe {
243            let mut error = None;
244            let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
245            let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);
246
247            match error {
248                None => Ok([first, second]),
249                Some(err) => Err((err, [first, second])),
250            }
251        }
252    }
253}
254
255impl<S, D> TransformContent<S, D> for [S; 3] {
256    type Output = [D; 3];
257
258    fn transform<F>(self, mut conversion: F) -> Self::Output
259    where
260        F: FnMut(S) -> D,
261    {
262        let self_forget = ManuallyDrop::new(self);
263
264        unsafe {
265            [
266                conversion(ptr::read(&self_forget[0])),
267                conversion(ptr::read(&self_forget[1])),
268                conversion(ptr::read(&self_forget[2])),
269            ]
270        }
271    }
272
273    fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
274    where
275        F: FnMut(S) -> TransRes<D>,
276    {
277        let self_forget = ManuallyDrop::new(self);
278
279        unsafe {
280            let mut error = None;
281            let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
282            let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);
283            let third = try_conv!(conversion(ptr::read(&self_forget[2])), error);
284
285            match error {
286                None => Ok([first, second, third]),
287                Some(err) => Err((err, [first, second, third])),
288            }
289        }
290    }
291}
292
293impl<S, D> TransformContent<S, D> for [S; 4] {
294    type Output = [D; 4];
295
296    fn transform<F>(self, mut conversion: F) -> Self::Output
297    where
298        F: FnMut(S) -> D,
299    {
300        let self_forget = ManuallyDrop::new(self);
301
302        unsafe {
303            [
304                conversion(ptr::read(&self_forget[0])),
305                conversion(ptr::read(&self_forget[1])),
306                conversion(ptr::read(&self_forget[2])),
307                conversion(ptr::read(&self_forget[3])),
308            ]
309        }
310    }
311
312    fn transform_res<F>(self, mut conversion: F) -> TransRes<Self::Output>
313    where
314        F: FnMut(S) -> TransRes<D>,
315    {
316        let self_forget = ManuallyDrop::new(self);
317
318        unsafe {
319            let mut error = None;
320            let first = try_conv!(conversion(ptr::read(&self_forget[0])), error);
321            let second = try_conv!(conversion(ptr::read(&self_forget[1])), error);
322            let third = try_conv!(conversion(ptr::read(&self_forget[2])), error);
323            let fourth = try_conv!(conversion(ptr::read(&self_forget[3])), error);
324
325            match error {
326                None => Ok([first, second, third, fourth]),
327                Some(err) => Err((err, [first, second, third, fourth])),
328            }
329        }
330    }
331}
332
333impl<T> IntoFixedLength<T, [T; 2]> for Vec<T> {
334    fn into_fixed_length(mut self) -> [T; 2] {
335        let second = self.pop().unwrap();
336        let first = self.pop().unwrap();
337        [first, second]
338    }
339}
340
341impl<T> IntoFixedLength<T, [T; 3]> for Vec<T> {
342    fn into_fixed_length(mut self) -> [T; 3] {
343        let third = self.pop().unwrap();
344        let second = self.pop().unwrap();
345        let first = self.pop().unwrap();
346        [first, second, third]
347    }
348}
349
350impl<T> IntoFixedLength<T, [T; 4]> for Vec<T> {
351    fn into_fixed_length(mut self) -> [T; 4] {
352        let fourth = self.pop().unwrap();
353        let third = self.pop().unwrap();
354        let second = self.pop().unwrap();
355        let first = self.pop().unwrap();
356        [first, second, third, fourth]
357    }
358}