column major
This commit is contained in:
parent
e46f4fb900
commit
8d97ffba92
@ -4,18 +4,18 @@ macro_rules! impl_matrix {
|
|||||||
() => {
|
() => {
|
||||||
impl<const X:usize,const Y:usize,T> Matrix<X,Y,T>{
|
impl<const X:usize,const Y:usize,T> Matrix<X,Y,T>{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn new(array:[[T;X];Y])->Self{
|
pub const fn new(array:[[T;Y];X])->Self{
|
||||||
Self{array}
|
Self{array}
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn to_array(self)->[[T;X];Y]{
|
pub fn to_array(self)->[[T;Y];X]{
|
||||||
self.array
|
self.array
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_rows(rows:[Vector<X,T>;Y])->Self
|
pub fn from_cols(cols:[Vector<Y,T>;X])->Self
|
||||||
{
|
{
|
||||||
Matrix::new(
|
Matrix::new(
|
||||||
rows.map(|row|row.array),
|
cols.map(|col|col.array),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -40,38 +40,45 @@ macro_rules! impl_matrix {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
// MatY<VecX>.MatX<VecZ> = MatY<VecZ>
|
// old (list of rows) MatY<VecX>.MatX<VecZ> = MatY<VecZ>
|
||||||
|
// new (list of columns) MatX<VecY>.MatZ<VecX> = MatZ<VecY>
|
||||||
pub fn dot<const Z:usize,U,V>(self,rhs:Matrix<Z,X,U>)->Matrix<Z,Y,V>
|
pub fn dot<const Z:usize,U,V>(self,rhs:Matrix<Z,X,U>)->Matrix<Z,Y,V>
|
||||||
where
|
where
|
||||||
T:core::ops::Mul<U,Output=V>+Copy,
|
T:core::ops::Mul<U,Output=V>+Copy,
|
||||||
V:core::iter::Sum,
|
V:core::iter::Sum,
|
||||||
U:Copy,
|
U:Copy,
|
||||||
{
|
{
|
||||||
let mut array_of_iterators=rhs.array.map(|axis|axis.into_iter().cycle());
|
let mut array_of_iterators=self.array.map(|axis|axis.into_iter().cycle());
|
||||||
Matrix::new(
|
Matrix{
|
||||||
self.array.map(|axis|
|
array:rhs.array.map(|rhs_axis|
|
||||||
core::array::from_fn(|_|
|
core::array::from_fn(|_|
|
||||||
// axis dot product with transposed rhs array
|
array_of_iterators
|
||||||
axis.iter().zip(
|
.iter_mut()
|
||||||
array_of_iterators.iter_mut()
|
.zip(rhs_axis.iter())
|
||||||
).map(|(&lhs_value,rhs_iter)|
|
.map(|(lhs_iter,&rhs_value)|
|
||||||
lhs_value*rhs_iter.next().unwrap()
|
lhs_iter.next().unwrap()*rhs_value
|
||||||
).sum()
|
).sum()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
// MatY<VecX>.VecX = VecY
|
// MatX<VecY>.VecY = VecX
|
||||||
pub fn transform_vector<U,V>(self,rhs:Vector<X,U>)->Vector<Y,V>
|
pub fn transform_vector<U,V>(self,rhs:Vector<X,U>)->Vector<Y,V>
|
||||||
where
|
where
|
||||||
T:core::ops::Mul<U,Output=V>,
|
T:core::ops::Mul<U,Output=V>,
|
||||||
V:core::iter::Sum,
|
V:core::iter::Sum,
|
||||||
U:Copy,
|
U:Copy,
|
||||||
{
|
{
|
||||||
|
let mut array_of_iterators=self.array.map(|axis|axis.into_iter());
|
||||||
Vector::new(
|
Vector::new(
|
||||||
self.array.map(|axis|
|
core::array::from_fn(|_|
|
||||||
Vector::new(axis).dot(rhs)
|
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)]
|
#[inline(always)]
|
||||||
pub const fn from_value(value:T)->Self{
|
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<const X:usize,const Y:usize,T:core::fmt::Display> core::fmt::Display for Matrix<X,Y,T>{
|
impl<const X:usize,const Y:usize,T:core::fmt::Display> core::fmt::Display for Matrix<X,Y,T>{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self,f:&mut core::fmt::Formatter)->Result<(),core::fmt::Error>{
|
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")?;
|
core::write!(f,"\n")?;
|
||||||
for elem in &row[0..X-1]{
|
for elem in &col[0..Y-1]{
|
||||||
core::write!(f,"{}, ",elem)?;
|
core::write!(f,"{}, ",elem)?;
|
||||||
}
|
}
|
||||||
// assume we will be using matrices of size 1x1 or greater
|
// assume we will be using matrices of size 1x1 or greater
|
||||||
core::write!(f,"{}",row.last().unwrap())?;
|
core::write!(f,"{}",col.last().unwrap())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -166,14 +173,14 @@ macro_rules! impl_matrix_extend {
|
|||||||
( $x: expr, $y: expr ) => {
|
( $x: expr, $y: expr ) => {
|
||||||
impl<T> Matrix<$x,$y,T>{
|
impl<T> Matrix<$x,$y,T>{
|
||||||
#[inline]
|
#[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));
|
let mut iter=self.array.into_iter().chain(core::iter::once(value.array));
|
||||||
Matrix::new(
|
Matrix::new(
|
||||||
core::array::from_fn(|_|iter.next().unwrap()),
|
core::array::from_fn(|_|iter.next().unwrap()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[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();
|
let mut iter_rows=value.array.into_iter();
|
||||||
Matrix::new(
|
Matrix::new(
|
||||||
self.array.map(|axis|{
|
self.array.map(|axis|{
|
||||||
|
@ -2,7 +2,7 @@ use crate::vector::Vector;
|
|||||||
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
|
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq)]
|
||||||
pub struct Matrix<const X:usize,const Y:usize,T>{
|
pub struct Matrix<const X:usize,const Y:usize,T>{
|
||||||
pub(crate) array:[[T;X];Y],
|
pub(crate) array:[[T;Y];X],
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::impl_matrix!();
|
crate::impl_matrix!();
|
||||||
|
@ -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 Planar64=fixed_wide::types::I32F32;
|
||||||
type Planar64Wide1=fixed_wide::types::I64F64;
|
type Planar64Wide1=fixed_wide::types::I64F64;
|
||||||
@ -37,28 +37,28 @@ fn wide_vec3_length_squared(){
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn wide_matrix_dot(){
|
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(1),Planar64::from(2),Planar64::from(3),Planar64::from(4)],
|
||||||
[Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)],
|
[Planar64::from(5),Planar64::from(6),Planar64::from(7),Planar64::from(8)],
|
||||||
[Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)],
|
[Planar64::from(9),Planar64::from(10),Planar64::from(11),Planar64::from(12)],
|
||||||
]);
|
]).transpose();
|
||||||
let rhs=Matrix2x4::new([
|
let rhs=Matrix4x2::new([
|
||||||
[Planar64::from(1),Planar64::from(2)],
|
[Planar64::from(1),Planar64::from(2)],
|
||||||
[Planar64::from(3),Planar64::from(4)],
|
[Planar64::from(3),Planar64::from(4)],
|
||||||
[Planar64::from(5),Planar64::from(6)],
|
[Planar64::from(5),Planar64::from(6)],
|
||||||
[Planar64::from(7),Planar64::from(8)],
|
[Planar64::from(7),Planar64::from(8)],
|
||||||
]);
|
]).transpose();
|
||||||
// Mat3<Vec4>.dot(Mat4<Vec2>) -> Mat3<Vec2>
|
// Mat3<Vec4>.dot(Mat4<Vec2>) -> Mat3<Vec2>
|
||||||
let m_dot=lhs*rhs;
|
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}}
|
//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}}
|
//Out[1]= {{50, 60}, {114, 140}, {178, 220}}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
m_dot.array,
|
m_dot.array,
|
||||||
Matrix2x3::new([
|
Matrix3x2::new([
|
||||||
[Planar64Wide1::from(50),Planar64Wide1::from(60)],
|
[Planar64Wide1::from(50),Planar64Wide1::from(60)],
|
||||||
[Planar64Wide1::from(114),Planar64Wide1::from(140)],
|
[Planar64Wide1::from(114),Planar64Wide1::from(140)],
|
||||||
[Planar64Wide1::from(178),Planar64Wide1::from(220)],
|
[Planar64Wide1::from(178),Planar64Wide1::from(220)],
|
||||||
]).array
|
]).transpose().array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::types::{Vector2,Vector3,Matrix4x3,Matrix2x4,Matrix2x3,Matrix3x2};
|
use crate::types::{Vector2,Vector3,Matrix3x4,Matrix4x2,Matrix3x2,Matrix2x3};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bool(){
|
fn test_bool(){
|
||||||
@ -21,10 +21,10 @@ fn test_arithmetic(){
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_transform_vector(){
|
fn matrix_transform_vector(){
|
||||||
let m=Matrix3x2::new([
|
let m=Matrix2x3::new([
|
||||||
[1,2,3],
|
[1,2,3],
|
||||||
[4,5,6],
|
[4,5,6],
|
||||||
]);
|
]).transpose();
|
||||||
let v=Vector3::new([1,2,3]);
|
let v=Vector3::new([1,2,3]);
|
||||||
let transformed=m*v;
|
let transformed=m*v;
|
||||||
assert_eq!(transformed.array,Vector2::new([14,32]).array);
|
assert_eq!(transformed.array,Vector2::new([14,32]).array);
|
||||||
@ -32,28 +32,28 @@ fn matrix_transform_vector(){
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn matrix_dot(){
|
fn matrix_dot(){
|
||||||
|
// All this code was written row major and I converted the lib to colum major
|
||||||
let rhs=Matrix2x4::new([
|
let rhs=Matrix4x2::new([
|
||||||
[ 1.0, 2.0],
|
[ 1.0, 2.0],
|
||||||
[ 3.0, 4.0],
|
[ 3.0, 4.0],
|
||||||
[ 5.0, 6.0],
|
[ 5.0, 6.0],
|
||||||
[ 7.0, 8.0],
|
[ 7.0, 8.0],
|
||||||
]); // | | |
|
]).transpose(); // | | |
|
||||||
let lhs=Matrix4x3::new([ // | | |
|
let lhs=Matrix3x4::new([ // | | |
|
||||||
[1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0],
|
[1.0, 2.0, 3.0, 4.0],// [ 50.0, 60.0],
|
||||||
[5.0, 6.0, 7.0, 8.0],// [114.0,140.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],
|
[9.0,10.0,11.0,12.0],// [178.0,220.0],
|
||||||
]);
|
]).transpose();
|
||||||
// Mat3<Vec4>.dot(Mat4<Vec2>) -> Mat3<Vec2>
|
// Mat3<Vec4>.dot(Mat4<Vec2>) -> Mat3<Vec2>
|
||||||
let m_dot=lhs*rhs;
|
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}}
|
//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}}
|
//Out[1]= {{50, 60}, {114, 140}, {178, 220}}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
m_dot.array,
|
m_dot.array,
|
||||||
Matrix2x3::new([
|
Matrix3x2::new([
|
||||||
[50.0,60.0],
|
[50.0,60.0],
|
||||||
[114.0,140.0],
|
[114.0,140.0],
|
||||||
[178.0,220.0],
|
[178.0,220.0],
|
||||||
]).array
|
]).transpose().array
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user