#[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix { () => { impl Matrix{ #[inline(always)] pub const fn new(array:[[T;X];Y])->Self{ Self{array} } #[inline(always)] pub fn to_array(self)->[[T;X];Y]{ self.array } #[inline] pub fn from_rows(rows:[Vector;Y])->Self { Matrix::new( rows.map(|row|row.array), ) } #[inline] pub fn map(self,f:F)->Matrix where F:Fn(T)->U { Matrix::new( self.array.map(|inner|inner.map(&f)), ) } #[inline] pub fn transpose(self)->Matrix{ //how did I think of this let mut array_of_iterators=self.array.map(|axis|axis.into_iter()); Matrix::new( core::array::from_fn(|_| array_of_iterators.each_mut().map(|iter| iter.next().unwrap() ) ) ) } #[inline] // MatY.MatX = MatY pub fn dot(self,rhs:Matrix)->Matrix where T:core::ops::Mul+Copy, V:core::iter::Sum, U:Copy, { let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle()); Matrix::new( self.array.map(|axis| core::array::from_fn(|_| // axis dot product with transposed rhs array axis.iter().zip( array_of_iterators.iter_mut() ).map(|(&lhs_value,rhs_iter)| lhs_value*rhs_iter.next().unwrap() ).sum() ) ) ) } #[inline] // MatY.VecX = VecY pub fn transform_vector(self,rhs:Vector)->Vector where T:core::ops::Mul, V:core::iter::Sum, U:Copy, { Vector::new( self.array.map(|axis| Vector::new(axis).dot(rhs) ) ) } } impl Matrix where T:Copy { #[inline(always)] pub const fn from_value(value:T)->Self{ Self::new([[value;X];Y]) } } impl Default for Matrix{ #[inline] fn default()->Self{ Self::new( core::array::from_fn(|_|core::array::from_fn(|_|Default::default())) ) } } impl core::fmt::Display for Matrix{ #[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(()) } } impl core::ops::Mul> for Matrix where T:core::ops::Mul+Copy, V:core::iter::Sum, U:Copy, { type Output=Matrix; #[inline] fn mul(self,rhs:Matrix)->Self::Output{ self.dot(rhs) } } impl core::ops::Mul> for Matrix where T:core::ops::Mul, V:core::iter::Sum, U:Copy, { type Output=Vector; #[inline] fn mul(self,rhs:Vector)->Self::Output{ self.transform_vector(rhs) } } #[cfg(feature="deferred-division")] $crate::impl_matrix_deferred_division!(); } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_deferred_division { () => { impl,U:Copy,V> ratio_ops::ratio::Divide for Matrix{ type Output=Matrix; #[inline] fn divide(self,rhs:U)->Self::Output{ self.map(|t|t.divide(rhs)) } } impl core::ops::Div for Matrix{ type Output=ratio_ops::ratio::Ratio,U>; #[inline] fn div(self,rhs:U)->Self::Output{ ratio_ops::ratio::Ratio::new(self,rhs) } } } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_extend { ( $x: expr, $y: expr ) => { impl 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()) }) ) } } } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_named_fields_shape { ( ($struct_outer:ident, $size_outer: expr), ($size_inner: expr) ) => { impl core::ops::Deref for Matrix<$size_outer,$size_inner,T>{ type Target=$struct_outer>; #[inline] fn deref(&self)->&Self::Target{ unsafe{core::mem::transmute(&self.array)} } } impl core::ops::DerefMut for Matrix<$size_outer,$size_inner,T>{ #[inline] 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),+); } } #[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix_3x3 { ()=>{ impl Matrix<3,3,T> where //cross T:core::ops::Mul+Copy, T2:core::ops::Sub, //dot T:core::ops::Mul<::Output,Output=T3>, T3:core::iter::Sum, { pub fn det(self)->T3{ self.x_axis.dot(self.y_axis.cross(self.z_axis)) } } impl Matrix<3,3,T> where T:core::ops::Mul+Copy, T2:core::ops::Sub, { pub fn adjugate(self)->Matrix<3,3,::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], ]) } } } }