minikalman/matrix/
data.rs

1mod matrix_data_array;
2#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
3#[cfg(any(feature = "alloc", feature = "std"))]
4mod matrix_data_boxed;
5mod matrix_data_mut;
6mod matrix_data_ref;
7mod matrix_data_row_major;
8mod matrix_data_row_major_mut;
9
10#[cfg(all(feature = "alloc", not(feature = "std")))]
11use alloc::boxed::Box;
12
13#[cfg(all(feature = "std", not(feature = "alloc")))]
14use std::boxed::Box;
15
16pub use matrix_data_array::*;
17pub use matrix_data_mut::*;
18pub use matrix_data_ref::*;
19pub use matrix_data_row_major::*;
20pub use matrix_data_row_major_mut::*;
21
22use crate::prelude::{RowMajorSequentialData, RowMajorSequentialDataMut};
23#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
24#[cfg(any(feature = "alloc", feature = "std"))]
25pub use matrix_data_boxed::*;
26
27/// A builder for a Kalman filter measurements.
28pub struct MatrixData;
29
30impl MatrixData {
31    /// Creates an empty matrix.
32    pub fn empty<T>() -> MatrixDataArray<0, 0, 0, T>
33    where
34        T: Default,
35    {
36        MatrixDataArray::<0, 0, 0, T>::default()
37    }
38
39    /// Creates a new matrix buffer from a given storage.
40    #[allow(clippy::new_ret_no_self)]
41    pub fn new_from<const ROWS: usize, const COLS: usize, T, S>(
42        storage: S,
43    ) -> MatrixDataRowMajor<ROWS, COLS, S, T>
44    where
45        T: Copy,
46        S: RowMajorSequentialData<ROWS, COLS, T>,
47    {
48        MatrixDataRowMajor::from(storage)
49    }
50
51    /// Creates a new mutable matrix buffer from a given storage.
52    #[allow(clippy::new_ret_no_self)]
53    pub fn new_mut_from<const ROWS: usize, const COLS: usize, T, S>(
54        storage: S,
55    ) -> MatrixDataRowMajorMut<ROWS, COLS, S, T>
56    where
57        T: Copy,
58        S: RowMajorSequentialDataMut<ROWS, COLS, T>,
59    {
60        MatrixDataRowMajorMut::from(storage)
61    }
62
63    /// Creates a new matrix buffer that owns the data.
64    #[allow(clippy::new_ret_no_self)]
65    #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
66    #[cfg(any(feature = "alloc", feature = "std"))]
67    pub fn new<const ROWS: usize, const COLS: usize, T>(init: T) -> MatrixDataBoxed<ROWS, COLS, T>
68    where
69        T: Copy,
70    {
71        MatrixDataBoxed::<ROWS, COLS, T>::new(alloc::vec![init; ROWS * COLS])
72    }
73
74    /// Creates a new matrix buffer that owns the data.
75    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
76    #[cfg(feature = "alloc")]
77    pub fn new_boxed<const ROWS: usize, const COLS: usize, T, B>(
78        data: B,
79    ) -> MatrixDataBoxed<ROWS, COLS, T>
80    where
81        B: Into<Box<[T]>>,
82    {
83        MatrixDataBoxed::<ROWS, COLS, T>::new(data.into())
84    }
85
86    /// Creates a new matrix buffer that owns the data.
87    pub const fn new_array<const ROWS: usize, const COLS: usize, const TOTAL: usize, T>(
88        data: [T; TOTAL],
89    ) -> MatrixDataArray<ROWS, COLS, TOTAL, T> {
90        MatrixDataArray::<ROWS, COLS, TOTAL, T>::new_unchecked(data)
91    }
92
93    /// Creates a new matrix buffer that references the data.
94    pub const fn new_ref<const ROWS: usize, const COLS: usize, T>(
95        data: &[T],
96    ) -> MatrixDataRef<ROWS, COLS, T> {
97        MatrixDataRef::<ROWS, COLS, T>::new(data)
98    }
99
100    /// Creates a new matrix buffer that mutably references the data.
101    pub fn new_mut<const ROWS: usize, const COLS: usize, T>(
102        data: &mut [T],
103    ) -> MatrixDataMut<ROWS, COLS, T> {
104        MatrixDataMut::<ROWS, COLS, T>::new(data)
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111    use assert_float_eq::*;
112
113    use crate::prelude::{
114        ColumnVector, ColumnVectorMut, RowMajorSequentialData, RowVector, RowVectorMut, Scalar,
115        ScalarMut,
116    };
117    #[cfg(feature = "unsafe")]
118    use core::ptr::addr_of;
119
120    #[test]
121    #[cfg(feature = "alloc")]
122    #[rustfmt::skip]
123    fn aray_buffer() {
124        let a = MatrixData::new::<2, 3, f32>(0.0);
125        assert_eq!(a.len(), 6);
126        assert_eq!(a.buffer_len(), 6);
127        assert!(!a.is_empty());
128        assert!(a.is_valid());
129    }
130
131    #[test]
132    #[rustfmt::skip]
133    fn array_buffer() {
134        let a_buf = [
135            1.0, 2.0, 3.0,
136            4.0, 5.0, 6.0];
137        let mut a = MatrixData::new_array::<2, 3, 6, f32>(a_buf);
138        a[2] += 10.0;
139
140        assert_f32_near!(a[0], 1.);
141        assert_f32_near!(a[1], 2.);
142        assert_f32_near!(a[2], 13.);
143        assert_f32_near!(a[3], 4.);
144        assert_f32_near!(a[4], 5.);
145        assert_f32_near!(a[5], 6.);
146
147        assert_eq!(a.len(), 6);
148        assert_eq!(a.buffer_len(), 6);
149        assert!(!a.is_empty());
150        assert!(a.is_valid());
151    }
152
153    #[test]
154    #[rustfmt::skip]
155    fn ref_buffer() {
156        let a_buf = [
157            1.0, 2.0, 3.0,
158            4.0, 5.0, 6.0];
159        let a = MatrixData::new_ref::<2, 3, f32>(&a_buf);
160
161        assert_f32_near!(a_buf[0], 1.);
162        assert_f32_near!(a_buf[1], 2.);
163        assert_f32_near!(a_buf[2], 3.);
164        assert_f32_near!(a[3], 4.);
165        assert_f32_near!(a[4], 5.);
166        assert_f32_near!(a[5], 6.);
167    }
168
169    #[test]
170    #[rustfmt::skip]
171    fn mut_buffer() {
172        let mut a_buf = [
173            1.0, 2.0, 3.0,
174            4.0, 5.0, 6.0];
175        let mut a = MatrixData::new_mut::<2, 3, f32>(&mut a_buf);
176        a[2] += 10.0;
177
178        assert_f32_near!(a[0], 1.);
179        assert_f32_near!(a[1], 2.);
180        assert_f32_near!(a[2], 13.);
181        assert_f32_near!(a[3], 4.);
182        assert_f32_near!(a[4], 5.);
183        assert_f32_near!(a[5], 6.);
184    }
185
186    #[test]
187    #[rustfmt::skip]
188    fn static_buffer() {
189        static BUFFER: [f32; 6] = [
190            1.0, 2.0, 3.0,
191            4.0, 5.0, 6.0];
192
193        let a = MatrixData::new_ref::<2, 3, f32>(&BUFFER);
194
195        assert_f32_near!(a[0], 1.);
196        assert_f32_near!(a[1], 2.);
197        assert_f32_near!(a[2], 3.);
198        assert_f32_near!(a[3], 4.);
199        assert_f32_near!(a[4], 5.);
200        assert_f32_near!(a[5], 6.);
201    }
202
203    #[test]
204    #[cfg(feature = "unsafe")]
205    #[rustfmt::skip]
206    fn static_mut_buffer() {
207        static mut BUFFER: [f32; 6] = [
208            1.0, 2.0, 3.0,
209            4.0, 5.0, 6.0];
210
211        let a = unsafe { MatrixData::new_ref::<2, 3, f32>(&*addr_of!(BUFFER)) };
212
213        assert_f32_near!(a[0], 1.);
214        assert_f32_near!(a[1], 2.);
215        assert_f32_near!(a[2], 3.);
216        assert_f32_near!(a[3], 4.);
217        assert_f32_near!(a[4], 5.);
218        assert_f32_near!(a[5], 6.);
219    }
220
221    #[test]
222    #[rustfmt::skip]
223    fn from_array() {
224        let a_buf = [
225            1.0, 2.0, 3.0,
226            4.0, 5.0, 6.0];
227        let mut a = MatrixDataArray::<2, 3, 6, f32>::from(a_buf);
228        a[2] += 10.0;
229
230        assert_f32_near!(a[0], 1.);
231        assert_f32_near!(a[1], 2.);
232        assert_f32_near!(a[2], 13.);
233        assert_f32_near!(a[3], 4.);
234        assert_f32_near!(a[4], 5.);
235        assert_f32_near!(a[5], 6.);
236
237        assert_eq!(a.len(), 6);
238        assert_eq!(a.buffer_len(), 6);
239        assert!(!a.is_empty());
240        assert!(a.is_valid());
241    }
242
243    #[test]
244    #[rustfmt::skip]
245    fn ref_from_ref() {
246        let a_buf = [
247            1.0, 2.0, 3.0,
248            4.0, 5.0, 6.0];
249        let a = MatrixDataRef::<2, 3, f32>::from(a_buf.as_ref());
250
251        assert_f32_near!(a[0], 1.);
252        assert_f32_near!(a[1], 2.);
253        assert_f32_near!(a[2], 3.);
254        assert_f32_near!(a[3], 4.);
255        assert_f32_near!(a[4], 5.);
256        assert_f32_near!(a[5], 6.);
257
258        assert_eq!(a.len(), 6);
259        assert_eq!(a.buffer_len(), 6);
260        assert!(!a.is_empty());
261        assert!(a.is_valid());
262    }
263
264    #[test]
265    fn data_into_array() {
266        let value: MatrixDataArray<4, 1, 4, f32> = [0.0, 1.0, 3.0, 4.0].into();
267        let data: [f32; 4] = value.into();
268        assert_eq!(data, [0.0, 1.0, 3.0, 4.0]);
269    }
270
271    #[test]
272    #[rustfmt::skip]
273    fn ref_from_mut() {
274        let mut a_buf = [
275            1.0, 2.0, 3.0,
276            4.0, 5.0, 6.0];
277        let a = MatrixDataRef::<2, 3, f32>::from(a_buf.as_mut_slice());
278
279        assert_f32_near!(a[0], 1.);
280        assert_f32_near!(a[1], 2.);
281        assert_f32_near!(a[2], 3.);
282        assert_f32_near!(a[3], 4.);
283        assert_f32_near!(a[4], 5.);
284        assert_f32_near!(a[5], 6.);
285
286        assert_eq!(a.len(), 6);
287        assert_eq!(a.buffer_len(), 6);
288        assert!(!a.is_empty());
289        assert!(a.is_valid());
290    }
291
292    #[test]
293    #[rustfmt::skip]
294    fn mut_from_mut() {
295        let mut a_buf = [
296            1.0, 2.0, 3.0,
297            4.0, 5.0, 6.0];
298        let mut a = MatrixDataMut::<2, 3, f32>::from(a_buf.as_mut_slice());
299        a[2] += 10.0;
300
301        assert_f32_near!(a[0], 1.);
302        assert_f32_near!(a[1], 2.);
303        assert_f32_near!(a[2], 13.);
304        assert_f32_near!(a[3], 4.);
305        assert_f32_near!(a[4], 5.);
306        assert_f32_near!(a[5], 6.);
307
308        assert_eq!(a.len(), 6);
309        assert_eq!(a.buffer_len(), 6);
310        assert!(!a.is_empty());
311        assert!(a.is_valid());
312    }
313
314    #[test]
315    fn row_vector() {
316        let mut a_buf = [1.0, 2.0, 3.0];
317        let mut a = MatrixDataMut::<3, 1, f32>::from(a_buf.as_mut_slice());
318        assert_eq!(a.get_row(0), 1.0);
319        assert_eq!(a.get_row(1), 2.0);
320        assert_eq!(a.get_row(2), 3.0);
321
322        a.set_row(0, 0.0);
323        assert_eq!(a.get_row(0), 0.0);
324    }
325
326    #[test]
327    fn column_vector() {
328        let mut a_buf = [1.0, 2.0, 3.0];
329        let mut a = MatrixDataMut::<1, 3, f32>::from(a_buf.as_mut_slice());
330        assert_eq!(a.get_col(0), 1.0);
331        assert_eq!(a.get_col(1), 2.0);
332        assert_eq!(a.get_col(2), 3.0);
333
334        a.set_col(0, 0.0);
335        assert_eq!(a.get_col(0), 0.0);
336    }
337
338    #[test]
339    fn scalar() {
340        let mut a_buf = [1.0, 2.0, 3.0];
341        let mut a = MatrixDataMut::<1, 1, f32>::from(a_buf.as_mut_slice());
342        assert_eq!(a.get_value(), 1.0);
343
344        a.set_value(0.0);
345        assert_eq!(a.get_value(), 0.0);
346    }
347}