#[doc(hidden)] #[macro_export(local_inner_macros)] macro_rules! impl_matrix { () => { impl Matrix{ #[inline(always)] pub const fn new(array:[[T;Y];X])->Self{ Self{array} } #[inline(always)] pub fn to_array(self)->[[T;Y];X]{ self.array } #[inline] pub fn from_cols(cols:[Vector;X])->Self { Matrix::new( cols.map(|col|col.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] // old (list of rows) MatY.MatX = MatY // new (list of columns) MatX.MatZ = MatZ pub fn dot(self,rhs:Matrix)->Matrix where T:core::ops::Mul+Copy, V:core::iter::Sum, U:Copy, { let mut array_of_iterators=self.array.map(|axis|axis.into_iter().cycle()); Matrix{ array:rhs.array.map(|rhs_axis| core::array::from_fn(|_| array_of_iterators .iter_mut() .zip(rhs_axis.iter()) .map(|(lhs_iter,&rhs_value)| lhs_iter.next().unwrap()*rhs_value ).sum() ) ) } } #[inline] // MatX.VecY = VecX pub fn transform_vector(self,rhs:Vector)->Vector where T:core::ops::Mul, V:core::iter::Sum, U:Copy, { let mut array_of_iterators=self.array.map(|axis|axis.into_iter()); Vector::new( core::array::from_fn(|_| array_of_iterators .iter_mut() .zip(rhs.array.iter()) .map(|(lhs_iter,&rhs_value)| lhs_iter.next().unwrap()*rhs_value ).sum() ) ) } } impl Matrix where T:Copy { #[inline(always)] pub const fn from_value(value:T)->Self{ Self::new([[value;Y];X]) } } 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 col in &self.array[0..X]{ core::write!(f,"\n")?; for elem in &col[0..Y-1]{ core::write!(f,"{}, ",elem)?; } // assume we will be using matrices of size 1x1 or greater core::write!(f,"{}",col.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_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,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_row(self,value:Vector<$x,T>)->Matrix<$x,{$y+1},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], ]) } } } }