2024-09-05 20:36:38 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix {
|
|
|
|
() => {
|
2024-09-05 20:52:54 +00:00
|
|
|
impl<const X:usize,const Y:usize,T> Matrix<X,Y,T>{
|
2024-09-05 22:41:39 +00:00
|
|
|
#[inline(always)]
|
2024-09-06 17:52:17 +00:00
|
|
|
pub const fn new(array:[[T;X];Y])->Self{
|
2024-09-05 20:52:54 +00:00
|
|
|
Self{array}
|
|
|
|
}
|
2024-09-05 22:41:39 +00:00
|
|
|
#[inline(always)]
|
2024-09-06 17:52:17 +00:00
|
|
|
pub fn to_array(self)->[[T;X];Y]{
|
2024-09-05 22:41:39 +00:00
|
|
|
self.array
|
|
|
|
}
|
|
|
|
#[inline]
|
2024-09-12 19:16:44 +00:00
|
|
|
pub fn from_rows(rows:[Vector<X,T>;Y])->Self
|
|
|
|
{
|
|
|
|
Matrix::new(
|
|
|
|
rows.map(|row|row.array),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
#[inline]
|
2024-09-05 22:41:39 +00:00
|
|
|
pub fn map<F,U>(self,f:F)->Matrix<X,Y,U>
|
|
|
|
where
|
|
|
|
F:Fn(T)->U
|
|
|
|
{
|
2024-09-06 18:44:43 +00:00
|
|
|
Matrix::new(
|
|
|
|
self.array.map(|inner|inner.map(&f)),
|
|
|
|
)
|
2024-09-05 22:41:39 +00:00
|
|
|
}
|
2024-09-06 00:15:41 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn transpose(self)->Matrix<Y,X,T>{
|
|
|
|
//how did I think of this
|
|
|
|
let mut array_of_iterators=self.array.map(|axis|axis.into_iter());
|
2024-09-06 18:44:43 +00:00
|
|
|
Matrix::new(
|
|
|
|
core::array::from_fn(|_|
|
2024-09-06 00:15:41 +00:00
|
|
|
array_of_iterators.each_mut().map(|iter|
|
|
|
|
iter.next().unwrap()
|
|
|
|
)
|
|
|
|
)
|
2024-09-06 18:44:43 +00:00
|
|
|
)
|
2024-09-06 00:15:41 +00:00
|
|
|
}
|
2024-09-06 00:36:37 +00:00
|
|
|
#[inline]
|
2024-09-06 17:52:17 +00:00
|
|
|
// MatY<VecX>.MatX<VecZ> = MatY<VecZ>
|
|
|
|
pub fn dot<const Z:usize,U,V>(self,rhs:Matrix<Z,X,U>)->Matrix<Z,Y,V>
|
2024-09-06 00:36:37 +00:00
|
|
|
where
|
|
|
|
T:core::ops::Mul<U,Output=V>+Copy,
|
|
|
|
V:core::iter::Sum,
|
2024-09-06 17:36:24 +00:00
|
|
|
U:Copy,
|
2024-09-06 00:36:37 +00:00
|
|
|
{
|
2024-09-06 00:56:04 +00:00
|
|
|
let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle());
|
2024-09-06 18:44:43 +00:00
|
|
|
Matrix::new(
|
|
|
|
self.array.map(|axis|
|
2024-09-06 00:36:37 +00:00
|
|
|
core::array::from_fn(|_|
|
|
|
|
// axis dot product with transposed rhs array
|
2024-09-06 00:44:44 +00:00
|
|
|
axis.iter().zip(
|
2024-09-06 17:36:24 +00:00
|
|
|
array_of_iterators.iter_mut()
|
|
|
|
).map(|(&lhs_value,rhs_iter)|
|
|
|
|
lhs_value*rhs_iter.next().unwrap()
|
2024-09-06 00:36:37 +00:00
|
|
|
).sum()
|
|
|
|
)
|
|
|
|
)
|
2024-09-06 18:44:43 +00:00
|
|
|
)
|
2024-09-06 00:36:37 +00:00
|
|
|
}
|
2024-09-10 00:22:37 +00:00
|
|
|
#[inline]
|
|
|
|
// MatY<VecX>.VecX = VecY
|
|
|
|
pub fn transform_vector<U,V>(self,rhs:Vector<X,U>)->Vector<Y,V>
|
|
|
|
where
|
|
|
|
T:core::ops::Mul<U,Output=V>,
|
|
|
|
V:core::iter::Sum,
|
|
|
|
U:Copy,
|
|
|
|
{
|
|
|
|
Vector::new(
|
|
|
|
self.array.map(|axis|
|
|
|
|
Vector::new(axis).dot(rhs)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
2024-09-05 22:41:39 +00:00
|
|
|
}
|
|
|
|
impl<const X:usize,const Y:usize,T> Matrix<X,Y,T>
|
|
|
|
where
|
|
|
|
T:Copy
|
|
|
|
{
|
2024-09-10 00:02:03 +00:00
|
|
|
#[inline(always)]
|
2024-09-05 22:41:39 +00:00
|
|
|
pub const fn from_value(value:T)->Self{
|
2024-09-06 18:44:43 +00:00
|
|
|
Self::new([[value;X];Y])
|
2024-09-05 22:41:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<const X:usize,const Y:usize,T:Default> Default for Matrix<X,Y,T>{
|
2024-09-10 00:02:03 +00:00
|
|
|
#[inline]
|
2024-09-05 22:41:39 +00:00
|
|
|
fn default()->Self{
|
2024-09-06 18:44:43 +00:00
|
|
|
Self::new(
|
|
|
|
core::array::from_fn(|_|core::array::from_fn(|_|Default::default()))
|
|
|
|
)
|
2024-09-05 22:41:39 +00:00
|
|
|
}
|
2024-09-05 20:52:54 +00:00
|
|
|
}
|
2024-09-11 19:06:58 +00:00
|
|
|
|
|
|
|
impl<const X:usize,const Y:usize,T:core::fmt::Display> core::fmt::Display for Matrix<X,Y,T>{
|
|
|
|
#[inline]
|
|
|
|
fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{
|
|
|
|
for row in &self.array[0..Y]{
|
|
|
|
core::write!(f,"\n")?;
|
|
|
|
for elem in &row[0..X-1]{
|
|
|
|
core::write!(f,"{}, ",elem)?;
|
|
|
|
}
|
|
|
|
// assume we will be using matrices of size 1x1 or greater
|
|
|
|
core::write!(f,"{}",row.last().unwrap())?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-10 00:01:52 +00:00
|
|
|
impl<const X:usize,const Y:usize,const Z:usize,T,U,V> core::ops::Mul<Matrix<Z,X,U>> for Matrix<X,Y,T>
|
|
|
|
where
|
|
|
|
T:core::ops::Mul<U,Output=V>+Copy,
|
|
|
|
V:core::iter::Sum,
|
|
|
|
U:Copy,
|
|
|
|
{
|
|
|
|
type Output=Matrix<Z,Y,V>;
|
|
|
|
#[inline]
|
|
|
|
fn mul(self,rhs:Matrix<Z,X,U>)->Self::Output{
|
|
|
|
self.dot(rhs)
|
|
|
|
}
|
|
|
|
}
|
2024-09-10 00:22:37 +00:00
|
|
|
impl<const X:usize,const Y:usize,T,U,V> core::ops::Mul<Vector<X,U>> for Matrix<X,Y,T>
|
|
|
|
where
|
|
|
|
T:core::ops::Mul<U,Output=V>,
|
|
|
|
V:core::iter::Sum,
|
|
|
|
U:Copy,
|
|
|
|
{
|
|
|
|
type Output=Vector<Y,V>;
|
|
|
|
#[inline]
|
|
|
|
fn mul(self,rhs:Vector<X,U>)->Self::Output{
|
|
|
|
self.transform_vector(rhs)
|
|
|
|
}
|
|
|
|
}
|
2024-09-11 19:20:17 +00:00
|
|
|
#[cfg(feature="deferred-division")]
|
|
|
|
$crate::impl_matrix_deferred_division!();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_deferred_division {
|
|
|
|
() => {
|
2024-09-11 19:59:33 +00:00
|
|
|
impl<const X:usize,const Y:usize,T:ratio_ops::ratio::Divide<U,Output=V>,U:Copy,V> ratio_ops::ratio::Divide<U> for Matrix<X,Y,T>{
|
|
|
|
type Output=Matrix<X,Y,V>;
|
|
|
|
#[inline]
|
|
|
|
fn divide(self,rhs:U)->Self::Output{
|
|
|
|
self.map(|t|t.divide(rhs))
|
|
|
|
}
|
|
|
|
}
|
2024-09-11 19:20:17 +00:00
|
|
|
impl<const X:usize,const Y:usize,T,U> core::ops::Div<U> for Matrix<X,Y,T>{
|
|
|
|
type Output=ratio_ops::ratio::Ratio<Matrix<X,Y,T>,U>;
|
|
|
|
#[inline]
|
|
|
|
fn div(self,rhs:U)->Self::Output{
|
|
|
|
ratio_ops::ratio::Ratio::new(self,rhs)
|
|
|
|
}
|
|
|
|
}
|
2024-09-05 20:36:38 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-30 19:06:33 +00:00
|
|
|
|
2024-09-06 20:23:55 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_extend {
|
|
|
|
( $x: expr, $y: expr ) => {
|
|
|
|
impl<T> Matrix<$x,$y,T>{
|
|
|
|
#[inline]
|
|
|
|
pub fn extend_row(self,value:Vector<$x,T>)->Matrix<$x,{$y+1},T>{
|
|
|
|
let mut iter=self.array.into_iter().chain(core::iter::once(value.array));
|
|
|
|
Matrix::new(
|
|
|
|
core::array::from_fn(|_|iter.next().unwrap()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
pub fn extend_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,T>{
|
|
|
|
let mut iter_rows=value.array.into_iter();
|
|
|
|
Matrix::new(
|
|
|
|
self.array.map(|axis|{
|
|
|
|
let mut elements_iter=axis.into_iter().chain(core::iter::once(iter_rows.next().unwrap()));
|
|
|
|
core::array::from_fn(|_|elements_iter.next().unwrap())
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-05 20:36:38 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_named_fields_shape {
|
|
|
|
(
|
|
|
|
($struct_outer:ident, $size_outer: expr),
|
2024-09-06 18:25:46 +00:00
|
|
|
($size_inner: expr)
|
2024-09-05 20:36:38 +00:00
|
|
|
) => {
|
|
|
|
impl<T> core::ops::Deref for Matrix<$size_outer,$size_inner,T>{
|
2024-09-06 18:25:46 +00:00
|
|
|
type Target=$struct_outer<Vector<$size_inner,T>>;
|
2024-09-10 00:02:03 +00:00
|
|
|
#[inline]
|
2024-09-05 20:36:38 +00:00
|
|
|
fn deref(&self)->&Self::Target{
|
|
|
|
unsafe{core::mem::transmute(&self.array)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl<T> core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{
|
2024-09-10 00:02:03 +00:00
|
|
|
#[inline]
|
2024-09-05 20:36:38 +00:00
|
|
|
fn deref_mut(&mut self)->&mut Self::Target{
|
|
|
|
unsafe{core::mem::transmute(&mut self.array)}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_named_fields_shape_shim {
|
|
|
|
(
|
|
|
|
($($vector_info:tt),+),
|
|
|
|
$matrix_info:tt
|
|
|
|
) => {
|
|
|
|
$crate::macro_repeated!(impl_matrix_named_fields_shape,$matrix_info,$($vector_info),+);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_named_fields {
|
|
|
|
(
|
|
|
|
($($matrix_info:tt),+),
|
|
|
|
$vector_infos:tt
|
|
|
|
) => {
|
|
|
|
$crate::macro_repeated!(impl_matrix_named_fields_shape_shim,$vector_infos,$($matrix_info),+);
|
|
|
|
}
|
|
|
|
}
|
2024-09-06 18:25:46 +00:00
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[macro_export(local_inner_macros)]
|
|
|
|
macro_rules! impl_matrix_3x3 {
|
|
|
|
()=>{
|
2024-09-10 01:02:05 +00:00
|
|
|
impl<T,T2,T3> Matrix<3,3,T>
|
|
|
|
where
|
|
|
|
//cross
|
|
|
|
T:core::ops::Mul<T,Output=T2>+Copy,
|
|
|
|
T2:core::ops::Sub,
|
|
|
|
//dot
|
|
|
|
T:core::ops::Mul<<T2 as core::ops::Sub>::Output,Output=T3>,
|
|
|
|
T3:core::iter::Sum,
|
|
|
|
{
|
|
|
|
pub fn det(self)->T3{
|
|
|
|
self.x_axis.dot(self.y_axis.cross(self.z_axis))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl<T,T2> Matrix<3,3,T>
|
|
|
|
where
|
|
|
|
T:core::ops::Mul<T,Output=T2>+Copy,
|
|
|
|
T2:core::ops::Sub,
|
|
|
|
{
|
|
|
|
pub fn adjugate(self)->Matrix<3,3,<T2 as core::ops::Sub>::Output>{
|
|
|
|
Matrix::new([
|
|
|
|
[self.y_axis.y*self.z_axis.z-self.y_axis.z*self.z_axis.y,self.x_axis.z*self.z_axis.y-self.x_axis.y*self.z_axis.z,self.x_axis.y*self.y_axis.z-self.x_axis.z*self.y_axis.y],
|
|
|
|
[self.y_axis.z*self.z_axis.x-self.y_axis.x*self.z_axis.z,self.x_axis.x*self.z_axis.z-self.x_axis.z*self.z_axis.x,self.x_axis.z*self.y_axis.x-self.x_axis.x*self.y_axis.z],
|
|
|
|
[self.y_axis.x*self.z_axis.y-self.y_axis.y*self.z_axis.x,self.x_axis.y*self.z_axis.x-self.x_axis.x*self.z_axis.y,self.x_axis.x*self.y_axis.y-self.x_axis.y*self.y_axis.x],
|
|
|
|
])
|
|
|
|
}
|
|
|
|
}
|
2024-09-06 18:25:46 +00:00
|
|
|
}
|
|
|
|
}
|