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 }