Skip to main content

geo_nd/
farray2.rs

1use crate::{FArray, matrix, vector};
2use crate::{Float, SqMatrix, Vector};
3
4//a FArray2
5//tp FArray2
6/// The [FArray2] is a wrapper around a `D2 = D`^2` sized array of [Float]s.
7///
8/// It provides implementations of the traits required for a [SqMatrix]
9/// trait operating on an [FArray] of dimesion D.
10#[derive(Clone, Copy, Debug, PartialEq)]
11#[repr(transparent)]
12pub struct FArray2<F: Float, const D: usize, const D2: usize> {
13    data: [F; D2],
14}
15
16//a Macros
17//mi farray2_basic_traits!
18macro_rules! farray2_basic_traits {
19    { $f:ty,  $d:expr,  $d2:expr, $ty:ty } => {
20
21        //ip Default for FArray
22        impl std::default::Default for $ty {
23            fn default() -> Self {
24                Self {
25                    data: vector::zero(),
26                }
27            }
28        }
29
30        //ip Display for FArray
31        impl std::fmt::Display for $ty {
32            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
33                vector::fmt(f, &self.data)
34            }
35        }
36    }
37}
38
39//mi farray2_mul_traits!
40macro_rules! farray2_mul_traits {
41    { $f:ty,  $d:expr,  $d2:expr, $ty:ty } => {
42        //ip FArray2
43        //ip Mul, MulAssign <Self> for FArray2
44        impl std::ops::Mul<Self> for $ty {
45            type Output = Self;
46            fn mul(self, other: Self) -> Self {
47                matrix::multiply::<$f, $d2, $d2, $d2, $d, $d, $d>(&self.data, &other.data).into()
48            }
49        }
50        impl std::ops::MulAssign<Self> for $ty {
51            fn mul_assign(&mut self, other: Self) {
52                *self = *self * other;
53            }
54        }
55    }
56}
57
58//ip SqMatrix<F,2,4> for FArray2
59//mi farray2_sqmatrix_trait!
60//
61// Note that Matrix is auto-implemented
62macro_rules! farray2_sqmatrix_trait {
63    { $f:ty,  $d:expr,  $d2:expr, $ty:ty, $det_fn:expr, $inv_fn:expr } => {
64
65        impl SqMatrix<$f, $d, $d2> for $ty
66        where
67            FArray<$f, $d>: Vector<$f, $d>,
68        {
69            fn determinant(&self) -> $f {
70                $det_fn (&self.data)
71            }
72            fn checked_inverse(&self) -> (Self, bool) {
73                let (inv, ok) = $inv_fn (&self.data);
74                (inv.into(), ok)
75            }
76        }
77    }
78}
79
80//mi farray2_traits
81macro_rules! farray2_traits {
82    { $f:ty,  $d:expr,  $d2:expr, $ty:ty, $det_fn:expr, $inv_fn:expr } => {
83        farray2_basic_traits! {$f, $d, $d2, $ty}
84
85        crate::ref_traits!{$f, $d2, $ty}
86        crate::convert_traits!{$f, $d2, $ty}
87        crate::serialize_traits!{$f, $d2, $ty}
88        crate::unary_traits!{$f, $d2, $ty}
89        crate::elementwise_traits!{$f, $d2, $ty, Add, add, +, AddAssign, add_assign, +=}
90        crate::elementwise_traits!{$f, $d2, $ty, Sub, sub, -, SubAssign, sub_assign, -=}
91        crate::scale_by_f_traits!{$f, $ty, Mul, mul, *, MulAssign, mul_assign, *=}
92        crate::scale_by_f_traits!{$f, $ty, Div, div, /, DivAssign, div_assign, /=}
93
94        farray2_mul_traits! {$f, $d, $d2, $ty}
95
96        farray2_sqmatrix_trait! {$f, $d, $d2, $ty, $det_fn, $inv_fn}
97    }
98}
99
100macro_rules! farray2_4_mul_vecs {
101    { $f:ty,  $ty:ty } => {
102        impl std::ops::Mul<FArray<$f, 4>> for $ty {
103            type Output = FArray<$f, 4>;
104            fn mul(self, v: FArray<$f, 4>) -> Self::Output {
105                matrix::transform_vec::<$f, 16, 4, 4>(&self, &v).into()
106            }
107        }
108    }
109}
110
111//a Use macros
112farray2_traits! {f32,2,4,FArray2<f32,2,4>, matrix::determinant2, matrix::checked_inverse2}
113farray2_traits! {f32,3,9,FArray2<f32,3,9>, matrix::determinant3, matrix::checked_inverse3}
114farray2_traits! {f32,4,16,FArray2<f32,4,16>, matrix::determinant4, matrix::checked_inverse4}
115
116farray2_traits! {f64,2,4,FArray2<f64,2,4>, matrix::determinant2, matrix::checked_inverse2}
117farray2_traits! {f64,3,9,FArray2<f64,3,9>, matrix::determinant3, matrix::checked_inverse3}
118farray2_traits! {f64,4,16,FArray2<f64,4,16>, matrix::determinant4, matrix::checked_inverse4}
119
120farray2_4_mul_vecs! {f32, FArray2<f32,4,16> }
121farray2_4_mul_vecs! {f64, FArray2<f64,4,16> }