From 8d97ffba92a8538db5db84e28bf960098cf6ace0 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 26 Sep 2024 15:06:01 -0700 Subject: [PATCH] column major --- linear_ops/src/macros/matrix.rs | 55 +++++++++++++++++------------- linear_ops/src/matrix.rs | 2 +- linear_ops/src/tests/fixed_wide.rs | 14 ++++---- linear_ops/src/tests/tests.rs | 20 +++++------ 4 files changed, 49 insertions(+), 42 deletions(-) diff --git a/linear_ops/src/macros/matrix.rs b/linear_ops/src/macros/matrix.rs index c04e965..69db874 100644 --- a/linear_ops/src/macros/matrix.rs +++ b/linear_ops/src/macros/matrix.rs @@ -4,18 +4,18 @@ macro_rules! impl_matrix { () => { impl Matrix{ #[inline(always)] - pub const fn new(array:[[T;X];Y])->Self{ + pub const fn new(array:[[T;Y];X])->Self{ Self{array} } #[inline(always)] - pub fn to_array(self)->[[T;X];Y]{ + pub fn to_array(self)->[[T;Y];X]{ self.array } #[inline] - pub fn from_rows(rows:[Vector;Y])->Self + pub fn from_cols(cols:[Vector;X])->Self { Matrix::new( - rows.map(|row|row.array), + cols.map(|col|col.array), ) } #[inline] @@ -40,38 +40,45 @@ macro_rules! impl_matrix { ) } #[inline] - // MatY.MatX = MatY + // 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=rhs.array.map(|axis|axis.into_iter().cycle()); - Matrix::new( - self.array.map(|axis| + let mut array_of_iterators=self.array.map(|axis|axis.into_iter().cycle()); + Matrix{ + array:rhs.array.map(|rhs_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() + array_of_iterators + .iter_mut() + .zip(rhs_axis.iter()) + .map(|(lhs_iter,&rhs_value)| + lhs_iter.next().unwrap()*rhs_value + ).sum() ) ) - ) + } } #[inline] - // MatY.VecX = VecY + // 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( - self.array.map(|axis| - Vector::new(axis).dot(rhs) + 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() ) ) } @@ -82,7 +89,7 @@ macro_rules! impl_matrix { { #[inline(always)] pub const fn from_value(value:T)->Self{ - Self::new([[value;X];Y]) + Self::new([[value;Y];X]) } } @@ -98,13 +105,13 @@ macro_rules! impl_matrix { 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]{ + for col in &self.array[0..X]{ core::write!(f,"\n")?; - for elem in &row[0..X-1]{ + 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,"{}",row.last().unwrap())?; + core::write!(f,"{}",col.last().unwrap())?; } Ok(()) } @@ -166,14 +173,14 @@ 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>{ + 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_column(self,value:Vector<$y,T>)->Matrix<{$x+1},$y,T>{ + 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|{ diff --git a/linear_ops/src/matrix.rs b/linear_ops/src/matrix.rs index 2c7dfb5..200d176 100644 --- a/linear_ops/src/matrix.rs +++ b/linear_ops/src/matrix.rs @@ -2,7 +2,7 @@ use crate::vector::Vector; #[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)] pub struct Matrix{ - pub(crate) array:[[T;X];Y], + pub(crate) array:[[T;Y];X], } crate::impl_matrix!(); diff --git a/linear_ops/src/tests/fixed_wide.rs b/linear_ops/src/tests/fixed_wide.rs index ae11c41..7032fd0 100644 --- a/linear_ops/src/tests/fixed_wide.rs +++ b/linear_ops/src/tests/fixed_wide.rs @@ -1,4 +1,4 @@ -use crate::types::{Matrix3,Matrix2x3,Matrix4x3,Matrix2x4,Vector3}; +use crate::types::{Matrix3,Matrix3x2,Matrix3x4,Matrix4x2,Vector3}; type Planar64=fixed_wide::types::I32F32; type Planar64Wide1=fixed_wide::types::I64F64; @@ -37,28 +37,28 @@ fn wide_vec3_length_squared(){ #[test] fn wide_matrix_dot(){ - let lhs=Matrix4x3::new([ + let lhs=Matrix3x4::new([ [Planar64::from(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)], [Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)], - ]); - let rhs=Matrix2x4::new([ + ]).transpose(); + let rhs=Matrix4x2::new([ [Planar64::from(1),Planar64::from(2)], [Planar64::from(3),Planar64::from(4)], [Planar64::from(5),Planar64::from(6)], [Planar64::from(7),Planar64::from(8)], - ]); + ]).transpose(); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot.array, - Matrix2x3::new([ + Matrix3x2::new([ [Planar64Wide1::from(50),Planar64Wide1::from(60)], [Planar64Wide1::from(114),Planar64Wide1::from(140)], [Planar64Wide1::from(178),Planar64Wide1::from(220)], - ]).array + ]).transpose().array ); } diff --git a/linear_ops/src/tests/tests.rs b/linear_ops/src/tests/tests.rs index 41233b2..573fe9a 100644 --- a/linear_ops/src/tests/tests.rs +++ b/linear_ops/src/tests/tests.rs @@ -1,4 +1,4 @@ -use crate::types::{Vector2,Vector3,Matrix4x3,Matrix2x4,Matrix2x3,Matrix3x2}; +use crate::types::{Vector2,Vector3,Matrix3x4,Matrix4x2,Matrix3x2,Matrix2x3}; #[test] fn test_bool(){ @@ -21,10 +21,10 @@ fn test_arithmetic(){ #[test] fn matrix_transform_vector(){ - let m=Matrix3x2::new([ + let m=Matrix2x3::new([ [1,2,3], [4,5,6], - ]); + ]).transpose(); let v=Vector3::new([1,2,3]); let transformed=m*v; assert_eq!(transformed.array,Vector2::new([14,32]).array); @@ -32,28 +32,28 @@ fn matrix_transform_vector(){ #[test] fn matrix_dot(){ - - let rhs=Matrix2x4::new([ + // All this code was written row major and I converted the lib to colum major + let rhs=Matrix4x2::new([ [ 1.0, 2.0], [ 3.0, 4.0], [ 5.0, 6.0], [ 7.0, 8.0], - ]); // | | | - let lhs=Matrix4x3::new([ // | | | + ]).transpose(); // | | | + let lhs=Matrix3x4::new([ // | | | [1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0], [5.0, 6.0, 7.0, 8.0],// [114.0,140.0], [9.0,10.0,11.0,12.0],// [178.0,220.0], - ]); + ]).transpose(); // Mat3.dot(Mat4) -> Mat3 let m_dot=lhs*rhs; //In[1]:= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}} . {{1, 2}, {3, 4}, {5, 6}, {7, 8}} //Out[1]= {{50, 60}, {114, 140}, {178, 220}} assert_eq!( m_dot.array, - Matrix2x3::new([ + Matrix3x2::new([ [50.0,60.0], [114.0,140.0], [178.0,220.0], - ]).array + ]).transpose().array ); }