use serde::{Deserialize, Serialize};
use crate::{matrix, vector, FArray};
use crate::{Float, SqMatrix, Vector};
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(transparent)]
pub struct FArray2<F: Float, const D: usize, const D2: usize> {
data: [F; D2],
}
macro_rules! farray2_basic_traits {
{ $f:ty, $d:expr, $d2:expr, $ty:ty } => {
impl std::default::Default for $ty {
fn default() -> Self {
Self {
data: vector::zero(),
}
}
}
impl std::fmt::Display for $ty {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
vector::fmt(f, &self.data)
}
}
}
}
macro_rules! farray2_mul_traits {
{ $f:ty, $d:expr, $d2:expr, $ty:ty } => {
impl std::ops::Mul<Self> for $ty {
type Output = Self;
fn mul(self, other: Self) -> Self {
matrix::multiply::<$f, $d2, $d2, $d2, $d, $d, $d>(&self.data, &other.data).into()
}
}
impl std::ops::MulAssign<Self> for $ty {
fn mul_assign(&mut self, other: Self) {
*self = *self * other;
}
}
}
}
macro_rules! farray2_sqmatrix_trait {
{ $f:ty, $d:expr, $d2:expr, $ty:ty, $det_fn:expr, $inv_fn:expr } => {
impl SqMatrix<$f, $d, $d2> for $ty
where
FArray<$f, $d>: Vector<$f, $d>,
{
fn transpose(&self) -> Self {
matrix::transpose::<$f, $d2, $d, $d>(self.data).into()
}
fn transform<T>(&self, v: &T) -> T
where
T: std::ops::Deref<Target = [$f; $d]>,
T: From<[$f; $d]>
{
matrix::multiply::<$f, $d2, $d, $d, $d, $d, 1>(&self.data, v).into()
}
fn determinant(&self) -> $f {
$det_fn (&self.data)
}
fn inverse(&self) -> Self {
$inv_fn (&self.data).into()
}
}
}
}
macro_rules! farray2_traits {
{ $f:ty, $d:expr, $d2:expr, $ty:ty, $det_fn:expr, $inv_fn:expr } => {
farray2_basic_traits! {$f, $d, $d2, $ty}
crate::ref_traits!{$f, $d2, $ty}
crate::convert_traits!{$f, $d2, $ty}
crate::serialize_traits!{$f, $d2, $ty}
crate::unary_traits!{$f, $d2, $ty}
crate::elementwise_traits!{$f, $d2, $ty, Add, add, +, AddAssign, add_assign, +=}
crate::elementwise_traits!{$f, $d2, $ty, Sub, sub, -, SubAssign, sub_assign, -=}
crate::scale_by_f_traits!{$f, $ty, Mul, mul, *, MulAssign, mul_assign, *=}
crate::scale_by_f_traits!{$f, $ty, Div, div, /, DivAssign, div_assign, /=}
farray2_mul_traits! {$f, $d, $d2, $ty}
farray2_sqmatrix_trait! {$f, $d, $d2, $ty, $det_fn, $inv_fn}
}
}
farray2_traits! {f32,2,4,FArray2<f32,2,4>, matrix::determinant2, matrix::inverse2}
farray2_traits! {f32,3,9,FArray2<f32,3,9>, matrix::determinant3, matrix::inverse3}
farray2_traits! {f32,4,16,FArray2<f32,4,16>, matrix::determinant4, matrix::inverse4}
farray2_traits! {f64,2,4,FArray2<f64,2,4>, matrix::determinant2, matrix::inverse2}
farray2_traits! {f64,3,9,FArray2<f64,3,9>, matrix::determinant3, matrix::inverse3}
farray2_traits! {f64,4,16,FArray2<f64,4,16>, matrix::determinant4, matrix::inverse4}