1 module daque.math.linear; 2 3 enum MatrixOrder 4 { 5 RowMajor, ColumnMajor 6 } 7 8 struct Matrix(RealType, uint Rows, uint Columns, MatrixOrder Order = MatrixOrder.ColumnMajor) 9 { 10 private RealType[Rows * Columns] m_element; 11 12 ref RealType opIndex(uint i, uint j) 13 { 14 static if(Order == MatrixOrder.RowMajor) 15 { 16 return m_element[j * Rows + i]; 17 } 18 else 19 { 20 return m_element[i * Columns + j]; 21 } 22 } 23 24 RealType[] linearize(MatrixOrder order = Order)() 25 { 26 RealType[] linearization; 27 28 static if(order == Order) 29 { 30 linearization = m_element; 31 } 32 else 33 { 34 static if(order == MatrixOrder.RowMajor) 35 { 36 for(uint i; i < Rows; i++) 37 for(uint j; j < Columns; j++) 38 linearization ~= this[i, j]; 39 } 40 else 41 { 42 for(uint j; j < Columns; j++) 43 for(uint i; i < Rows; i++) 44 linearization ~= this[i, j]; 45 } 46 } 47 48 return linearization; 49 } 50 51 static Matrix!(RealType, Rows, Columns, Order) Identity() 52 { 53 Matrix!(RealType, Rows, Columns, Order) identity; 54 for(uint i; i < Rows; i++) 55 for(uint j; j < Columns; j++) 56 identity[i, j] = i == j; 57 return identity; 58 } 59 } 60 61 unittest 62 { 63 import std.algorithm; 64 import std.range; 65 import std.stdio; 66 auto identityColumn = Matrix!(real, 3, 3, MatrixOrder.ColumnMajor).Identity(); 67 auto identityRow = Matrix!(real, 3, 3, MatrixOrder.RowMajor).Identity(); 68 writeln(identityColumn.linearize!(MatrixOrder.RowMajor)()); 69 writeln(identityRow); 70 }