1e5c31af7Sopenharmony_ci#ifndef _TCUMATRIX_HPP
2e5c31af7Sopenharmony_ci#define _TCUMATRIX_HPP
3e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core
5e5c31af7Sopenharmony_ci * ----------------------------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
8e5c31af7Sopenharmony_ci *
9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci *
15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci * limitations under the License.
20e5c31af7Sopenharmony_ci *
21e5c31af7Sopenharmony_ci *//*!
22e5c31af7Sopenharmony_ci * \file
23e5c31af7Sopenharmony_ci * \brief Templatized matrix class.
24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "tcuDefs.hpp"
27e5c31af7Sopenharmony_ci#include "tcuVector.hpp"
28e5c31af7Sopenharmony_ci#include "tcuArray.hpp"
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_cinamespace tcu
31e5c31af7Sopenharmony_ci{
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ci// Templated matrix class.
34e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
35e5c31af7Sopenharmony_ciclass Matrix
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cipublic:
38e5c31af7Sopenharmony_ci	typedef	Vector<T, Rows>			Element;
39e5c31af7Sopenharmony_ci	typedef	T						Scalar;
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ci	enum
42e5c31af7Sopenharmony_ci	{
43e5c31af7Sopenharmony_ci		SIZE = Cols,
44e5c31af7Sopenharmony_ci		ROWS = Rows,
45e5c31af7Sopenharmony_ci		COLS = Cols,
46e5c31af7Sopenharmony_ci	};
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ci									Matrix				(void);
49e5c31af7Sopenharmony_ci	explicit						Matrix				(const T& src);
50e5c31af7Sopenharmony_ci	explicit						Matrix				(const T src[Rows*Cols]);
51e5c31af7Sopenharmony_ci									Matrix				(const Vector<T, Rows>& src);
52e5c31af7Sopenharmony_ci									Matrix				(const Matrix<T, Rows, Cols>& src);
53e5c31af7Sopenharmony_ci									~Matrix				(void);
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols>&			operator=			(const Matrix<T, Rows, Cols>& src);
56e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols>&			operator*=			(const Matrix<T, Rows, Cols>& src);
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	void							setRow				(int rowNdx, const Vector<T, Cols>& vec);
59e5c31af7Sopenharmony_ci	void							setColumn			(int colNdx, const Vector<T, Rows>& vec);
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci	Vector<T, Cols>					getRow				(int ndx) const;
62e5c31af7Sopenharmony_ci	Vector<T, Rows>&				getColumn			(int ndx);
63e5c31af7Sopenharmony_ci	const Vector<T, Rows>&			getColumn			(int ndx) const;
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_ci	Vector<T, Rows>&				operator[]			(int ndx)					{ return getColumn(ndx);	}
66e5c31af7Sopenharmony_ci	const Vector<T, Rows>&			operator[]			(int ndx) const				{ return getColumn(ndx);	}
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci	inline const T&					operator()			(int row, int col) const	{ return m_data[col][row];	}
69e5c31af7Sopenharmony_ci	inline T&						operator()			(int row, int col)			{ return m_data[col][row];	}
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	Array<T, Rows*Cols>				getRowMajorData		(void) const;
72e5c31af7Sopenharmony_ci	Array<T, Rows*Cols>				getColumnMajorData	(void) const;
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ciprivate:
75e5c31af7Sopenharmony_ci	Vector<Vector<T, Rows>, Cols>	m_data;
76e5c31af7Sopenharmony_ci} DE_WARN_UNUSED_TYPE;
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_ci// Operators.
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ci// Mat * Mat.
81e5c31af7Sopenharmony_citemplate <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
82e5c31af7Sopenharmony_ciMatrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b);
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci// Mat * Vec (column vector).
85e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
86e5c31af7Sopenharmony_ciVector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec);
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci// Vec * Mat (row vector).
89e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
90e5c31af7Sopenharmony_ciVector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx);
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
93e5c31af7Sopenharmony_cibool operator== (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs);
94e5c31af7Sopenharmony_ci
95e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
96e5c31af7Sopenharmony_cibool operator!= (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs);
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ci// Further operations
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_citemplate <typename T, int Size>
101e5c31af7Sopenharmony_cistruct SquareMatrixOps
102e5c31af7Sopenharmony_ci{
103e5c31af7Sopenharmony_ci	static T						doDeterminant	(const Matrix<T, Size, Size>& mat);
104e5c31af7Sopenharmony_ci	static Matrix<T, Size, Size>	doInverse		(const Matrix<T, Size, Size>& mat);
105e5c31af7Sopenharmony_ci};
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_citemplate <typename T>
108e5c31af7Sopenharmony_cistruct SquareMatrixOps<T, 2>
109e5c31af7Sopenharmony_ci{
110e5c31af7Sopenharmony_ci	static T						doDeterminant	(const Matrix<T, 2, 2>& mat);
111e5c31af7Sopenharmony_ci	static Matrix<T, 2, 2>			doInverse		(const Matrix<T, 2, 2>& mat);
112e5c31af7Sopenharmony_ci};
113e5c31af7Sopenharmony_ci
114e5c31af7Sopenharmony_citemplate <typename T>
115e5c31af7Sopenharmony_cistruct SquareMatrixOps<T, 3>
116e5c31af7Sopenharmony_ci{
117e5c31af7Sopenharmony_ci	static T						doDeterminant	(const Matrix<T, 3, 3>& mat);
118e5c31af7Sopenharmony_ci	static Matrix<T, 3, 3>			doInverse		(const Matrix<T, 3, 3>& mat);
119e5c31af7Sopenharmony_ci};
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_citemplate <typename T>
122e5c31af7Sopenharmony_cistruct SquareMatrixOps<T, 4>
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	static T						doDeterminant	(const Matrix<T, 4, 4>& mat);
125e5c31af7Sopenharmony_ci	static Matrix<T, 4, 4>			doInverse		(const Matrix<T, 4, 4>& mat);
126e5c31af7Sopenharmony_ci};
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_cinamespace matrix
129e5c31af7Sopenharmony_ci{
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_citemplate <typename T, int Size>
132e5c31af7Sopenharmony_ciT determinant (const Matrix<T, Size, Size>& mat)
133e5c31af7Sopenharmony_ci{
134e5c31af7Sopenharmony_ci	return SquareMatrixOps<T, Size>::doDeterminant(mat);
135e5c31af7Sopenharmony_ci}
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_citemplate <typename T, int Size>
138e5c31af7Sopenharmony_ciMatrix<T, Size, Size> inverse (const Matrix<T, Size, Size>& mat)
139e5c31af7Sopenharmony_ci{
140e5c31af7Sopenharmony_ci	return SquareMatrixOps<T, Size>::doInverse(mat);
141e5c31af7Sopenharmony_ci}
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci} // matrix
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ci// Template implementations.
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_citemplate <typename T>
148e5c31af7Sopenharmony_ciT SquareMatrixOps<T, 2>::doDeterminant (const Matrix<T, 2, 2>& mat)
149e5c31af7Sopenharmony_ci{
150e5c31af7Sopenharmony_ci	return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
151e5c31af7Sopenharmony_ci}
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_citemplate <typename T>
154e5c31af7Sopenharmony_ciT SquareMatrixOps<T, 3>::doDeterminant (const Matrix<T, 3, 3>& mat)
155e5c31af7Sopenharmony_ci{
156e5c31af7Sopenharmony_ci	return	+ mat(0,0) * mat(1,1) * mat(2,2)
157e5c31af7Sopenharmony_ci			+ mat(0,1) * mat(1,2) * mat(2,0)
158e5c31af7Sopenharmony_ci			+ mat(0,2) * mat(1,0) * mat(2,1)
159e5c31af7Sopenharmony_ci			- mat(0,0) * mat(1,2) * mat(2,1)
160e5c31af7Sopenharmony_ci			- mat(0,1) * mat(1,0) * mat(2,2)
161e5c31af7Sopenharmony_ci			- mat(0,2) * mat(1,1) * mat(2,0);
162e5c31af7Sopenharmony_ci}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_citemplate <typename T>
165e5c31af7Sopenharmony_ciT SquareMatrixOps<T, 4>::doDeterminant (const Matrix<T, 4, 4>& mat)
166e5c31af7Sopenharmony_ci{
167e5c31af7Sopenharmony_ci	using matrix::determinant;
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	const T minorMatrices[4][3*3] =
170e5c31af7Sopenharmony_ci	{
171e5c31af7Sopenharmony_ci		{
172e5c31af7Sopenharmony_ci			mat(1,1),	mat(2,1),	mat(3,1),
173e5c31af7Sopenharmony_ci			mat(1,2),	mat(2,2),	mat(3,2),
174e5c31af7Sopenharmony_ci			mat(1,3),	mat(2,3),	mat(3,3),
175e5c31af7Sopenharmony_ci		},
176e5c31af7Sopenharmony_ci		{
177e5c31af7Sopenharmony_ci			mat(1,0),	mat(2,0),	mat(3,0),
178e5c31af7Sopenharmony_ci			mat(1,2),	mat(2,2),	mat(3,2),
179e5c31af7Sopenharmony_ci			mat(1,3),	mat(2,3),	mat(3,3),
180e5c31af7Sopenharmony_ci		},
181e5c31af7Sopenharmony_ci		{
182e5c31af7Sopenharmony_ci			mat(1,0),	mat(2,0),	mat(3,0),
183e5c31af7Sopenharmony_ci			mat(1,1),	mat(2,1),	mat(3,1),
184e5c31af7Sopenharmony_ci			mat(1,3),	mat(2,3),	mat(3,3),
185e5c31af7Sopenharmony_ci		},
186e5c31af7Sopenharmony_ci		{
187e5c31af7Sopenharmony_ci			mat(1,0),	mat(2,0),	mat(3,0),
188e5c31af7Sopenharmony_ci			mat(1,1),	mat(2,1),	mat(3,1),
189e5c31af7Sopenharmony_ci			mat(1,2),	mat(2,2),	mat(3,2),
190e5c31af7Sopenharmony_ci		}
191e5c31af7Sopenharmony_ci	};
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci	return	+ mat(0,0) * determinant(Matrix<T, 3, 3>(minorMatrices[0]))
194e5c31af7Sopenharmony_ci			- mat(0,1) * determinant(Matrix<T, 3, 3>(minorMatrices[1]))
195e5c31af7Sopenharmony_ci			+ mat(0,2) * determinant(Matrix<T, 3, 3>(minorMatrices[2]))
196e5c31af7Sopenharmony_ci			- mat(0,3) * determinant(Matrix<T, 3, 3>(minorMatrices[3]));
197e5c31af7Sopenharmony_ci}
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_citemplate <typename T>
200e5c31af7Sopenharmony_ciMatrix<T, 2, 2> SquareMatrixOps<T, 2>::doInverse (const Matrix<T, 2, 2>& mat)
201e5c31af7Sopenharmony_ci{
202e5c31af7Sopenharmony_ci	using matrix::determinant;
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ci	const T			det		= determinant(mat);
205e5c31af7Sopenharmony_ci	Matrix<T, 2, 2>	retVal;
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	retVal(0, 0) =  mat(1, 1) / det;
208e5c31af7Sopenharmony_ci	retVal(0, 1) = -mat(0, 1) / det;
209e5c31af7Sopenharmony_ci	retVal(1, 0) = -mat(1, 0) / det;
210e5c31af7Sopenharmony_ci	retVal(1, 1) =  mat(0, 0) / det;
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	return retVal;
213e5c31af7Sopenharmony_ci}
214e5c31af7Sopenharmony_ci
215e5c31af7Sopenharmony_citemplate <typename T>
216e5c31af7Sopenharmony_ciMatrix<T, 3, 3> SquareMatrixOps<T, 3>::doInverse (const Matrix<T, 3, 3>& mat)
217e5c31af7Sopenharmony_ci{
218e5c31af7Sopenharmony_ci	// Blockwise inversion
219e5c31af7Sopenharmony_ci	using matrix::inverse;
220e5c31af7Sopenharmony_ci
221e5c31af7Sopenharmony_ci	const T areaA[2*2] =
222e5c31af7Sopenharmony_ci	{
223e5c31af7Sopenharmony_ci		mat(0,0),	mat(0,1),
224e5c31af7Sopenharmony_ci		mat(1,0),	mat(1,1)
225e5c31af7Sopenharmony_ci	};
226e5c31af7Sopenharmony_ci	const T areaB[2] =
227e5c31af7Sopenharmony_ci	{
228e5c31af7Sopenharmony_ci		mat(0,2),
229e5c31af7Sopenharmony_ci		mat(1,2),
230e5c31af7Sopenharmony_ci	};
231e5c31af7Sopenharmony_ci	const T areaC[2] =
232e5c31af7Sopenharmony_ci	{
233e5c31af7Sopenharmony_ci		mat(2,0),	mat(2,1),
234e5c31af7Sopenharmony_ci	};
235e5c31af7Sopenharmony_ci	const T areaD[1] =
236e5c31af7Sopenharmony_ci	{
237e5c31af7Sopenharmony_ci		mat(2,2)
238e5c31af7Sopenharmony_ci	};
239e5c31af7Sopenharmony_ci	const T nullField[4] = { T(0.0f) };
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2>	invA = inverse(Matrix<T, 2, 2>(areaA));
242e5c31af7Sopenharmony_ci	const Matrix<T, 2, 1>	matB =         Matrix<T, 2, 1>(areaB);
243e5c31af7Sopenharmony_ci	const Matrix<T, 1, 2>	matC =         Matrix<T, 1, 2>(areaC);
244e5c31af7Sopenharmony_ci	const Matrix<T, 1, 1>	matD =         Matrix<T, 1, 1>(areaD);
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci	const T					schurComplement = T(1.0f) / (matD - matC*invA*matB)(0,0);
247e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2>	zeroMat         = Matrix<T, 2, 2>(nullField);
248e5c31af7Sopenharmony_ci
249e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2>	blockA = invA + invA*matB*schurComplement*matC*invA;
250e5c31af7Sopenharmony_ci	const Matrix<T, 2, 1>	blockB = (zeroMat-invA)*matB*schurComplement;
251e5c31af7Sopenharmony_ci	const Matrix<T, 1, 2>	blockC = matC*invA*(-schurComplement);
252e5c31af7Sopenharmony_ci	const T					blockD = schurComplement;
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci	const T result[3*3] =
255e5c31af7Sopenharmony_ci	{
256e5c31af7Sopenharmony_ci		blockA(0,0),	blockA(0,1),	blockB(0,0),
257e5c31af7Sopenharmony_ci		blockA(1,0),	blockA(1,1),	blockB(1,0),
258e5c31af7Sopenharmony_ci		blockC(0,0),	blockC(0,1),	blockD,
259e5c31af7Sopenharmony_ci	};
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci	return Matrix<T, 3, 3>(result);
262e5c31af7Sopenharmony_ci}
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_citemplate <typename T>
265e5c31af7Sopenharmony_ciMatrix<T, 4, 4> SquareMatrixOps<T, 4>::doInverse (const Matrix<T, 4, 4>& mat)
266e5c31af7Sopenharmony_ci{
267e5c31af7Sopenharmony_ci	// Blockwise inversion
268e5c31af7Sopenharmony_ci	using matrix::inverse;
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci	const T areaA[2*2] =
271e5c31af7Sopenharmony_ci	{
272e5c31af7Sopenharmony_ci		mat(0,0),	mat(0,1),
273e5c31af7Sopenharmony_ci		mat(1,0),	mat(1,1)
274e5c31af7Sopenharmony_ci	};
275e5c31af7Sopenharmony_ci	const T areaB[2*2] =
276e5c31af7Sopenharmony_ci	{
277e5c31af7Sopenharmony_ci		mat(0,2),	mat(0,3),
278e5c31af7Sopenharmony_ci		mat(1,2),	mat(1,3)
279e5c31af7Sopenharmony_ci	};
280e5c31af7Sopenharmony_ci	const T areaC[2*2] =
281e5c31af7Sopenharmony_ci	{
282e5c31af7Sopenharmony_ci		mat(2,0),	mat(2,1),
283e5c31af7Sopenharmony_ci		mat(3,0),	mat(3,1)
284e5c31af7Sopenharmony_ci	};
285e5c31af7Sopenharmony_ci	const T areaD[2*2] =
286e5c31af7Sopenharmony_ci	{
287e5c31af7Sopenharmony_ci		mat(2,2),	mat(2,3),
288e5c31af7Sopenharmony_ci		mat(3,2),	mat(3,3)
289e5c31af7Sopenharmony_ci	};
290e5c31af7Sopenharmony_ci	const T nullField[4] = { T(0.0f) };
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> invA = inverse(Matrix<T, 2, 2>(areaA));
293e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> matB =         Matrix<T, 2, 2>(areaB);
294e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> matC =         Matrix<T, 2, 2>(areaC);
295e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> matD =         Matrix<T, 2, 2>(areaD);
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
298e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> zeroMat         = Matrix<T, 2, 2>(nullField);
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
301e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
302e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
303e5c31af7Sopenharmony_ci	const Matrix<T, 2, 2> blockD = schurComplement;
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci	const T result[4*4] =
306e5c31af7Sopenharmony_ci	{
307e5c31af7Sopenharmony_ci		blockA(0,0),	blockA(0,1),	blockB(0,0),	blockB(0,1),
308e5c31af7Sopenharmony_ci		blockA(1,0),	blockA(1,1),	blockB(1,0),	blockB(1,1),
309e5c31af7Sopenharmony_ci		blockC(0,0),	blockC(0,1),	blockD(0,0),	blockD(0,1),
310e5c31af7Sopenharmony_ci		blockC(1,0),	blockC(1,1),	blockD(1,0),	blockD(1,1),
311e5c31af7Sopenharmony_ci	};
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_ci	return Matrix<T, 4, 4>(result);
314e5c31af7Sopenharmony_ci}
315e5c31af7Sopenharmony_ci
316e5c31af7Sopenharmony_ci// Initialize to identity.
317e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
318e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::Matrix (void)
319e5c31af7Sopenharmony_ci{
320e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
321e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
322e5c31af7Sopenharmony_ci			(*this)(row, col) = (row == col) ? T(1) : T(0);
323e5c31af7Sopenharmony_ci}
324e5c31af7Sopenharmony_ci
325e5c31af7Sopenharmony_ci// Initialize to diagonal matrix.
326e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
327e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::Matrix (const T& src)
328e5c31af7Sopenharmony_ci{
329e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
330e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
331e5c31af7Sopenharmony_ci			(*this)(row, col) = (row == col) ? src : T(0);
332e5c31af7Sopenharmony_ci}
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci// Initialize from data array.
335e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
336e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::Matrix (const T src[Rows*Cols])
337e5c31af7Sopenharmony_ci{
338e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
339e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
340e5c31af7Sopenharmony_ci			(*this)(row, col) = src[row*Cols + col];
341e5c31af7Sopenharmony_ci}
342e5c31af7Sopenharmony_ci
343e5c31af7Sopenharmony_ci// Initialize to diagonal matrix.
344e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
345e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::Matrix (const Vector<T, Rows>& src)
346e5c31af7Sopenharmony_ci{
347e5c31af7Sopenharmony_ci	DE_STATIC_ASSERT(Rows == Cols);
348e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
349e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
350e5c31af7Sopenharmony_ci			(*this)(row, col) = (row == col) ? src.m_data[row] : T(0);
351e5c31af7Sopenharmony_ci}
352e5c31af7Sopenharmony_ci
353e5c31af7Sopenharmony_ci// Copy constructor.
354e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
355e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::Matrix (const Matrix<T, Rows, Cols>& src)
356e5c31af7Sopenharmony_ci{
357e5c31af7Sopenharmony_ci	*this = src;
358e5c31af7Sopenharmony_ci}
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci// Destructor.
361e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
362e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>::~Matrix (void)
363e5c31af7Sopenharmony_ci{
364e5c31af7Sopenharmony_ci}
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_ci// Assignment operator.
367e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
368e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator= (const Matrix<T, Rows, Cols>& src)
369e5c31af7Sopenharmony_ci{
370e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
371e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
372e5c31af7Sopenharmony_ci			(*this)(row, col) = src(row, col);
373e5c31af7Sopenharmony_ci	return *this;
374e5c31af7Sopenharmony_ci}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci// Multipy and assign op
377e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
378e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator*= (const Matrix<T, Rows, Cols>& src)
379e5c31af7Sopenharmony_ci{
380e5c31af7Sopenharmony_ci	*this = *this * src;
381e5c31af7Sopenharmony_ci	return *this;
382e5c31af7Sopenharmony_ci}
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
385e5c31af7Sopenharmony_civoid Matrix<T, Rows, Cols>::setRow (int rowNdx, const Vector<T, Cols>& vec)
386e5c31af7Sopenharmony_ci{
387e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
388e5c31af7Sopenharmony_ci		(*this)(rowNdx, col) = vec.m_data[col];
389e5c31af7Sopenharmony_ci}
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
392e5c31af7Sopenharmony_civoid Matrix<T, Rows, Cols>::setColumn (int colNdx, const Vector<T, Rows>& vec)
393e5c31af7Sopenharmony_ci{
394e5c31af7Sopenharmony_ci	m_data[colNdx] = vec;
395e5c31af7Sopenharmony_ci}
396e5c31af7Sopenharmony_ci
397e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
398e5c31af7Sopenharmony_ciVector<T, Cols> Matrix<T, Rows, Cols>::getRow (int rowNdx) const
399e5c31af7Sopenharmony_ci{
400e5c31af7Sopenharmony_ci	Vector<T, Cols> res;
401e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
402e5c31af7Sopenharmony_ci		res[col] = (*this)(rowNdx, col);
403e5c31af7Sopenharmony_ci	return res;
404e5c31af7Sopenharmony_ci}
405e5c31af7Sopenharmony_ci
406e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
407e5c31af7Sopenharmony_ciVector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx)
408e5c31af7Sopenharmony_ci{
409e5c31af7Sopenharmony_ci	return m_data[colNdx];
410e5c31af7Sopenharmony_ci}
411e5c31af7Sopenharmony_ci
412e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
413e5c31af7Sopenharmony_ciconst Vector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx) const
414e5c31af7Sopenharmony_ci{
415e5c31af7Sopenharmony_ci	return m_data[colNdx];
416e5c31af7Sopenharmony_ci}
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
419e5c31af7Sopenharmony_ciArray<T, Rows*Cols> Matrix<T, Rows, Cols>::getColumnMajorData (void) const
420e5c31af7Sopenharmony_ci{
421e5c31af7Sopenharmony_ci	Array<T, Rows*Cols> a;
422e5c31af7Sopenharmony_ci	T* dst = a.getPtr();
423e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
424e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
425e5c31af7Sopenharmony_ci			*dst++ = (*this)(row, col);
426e5c31af7Sopenharmony_ci	return a;
427e5c31af7Sopenharmony_ci}
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
430e5c31af7Sopenharmony_ciArray<T, Rows*Cols> Matrix<T, Rows, Cols>::getRowMajorData (void) const
431e5c31af7Sopenharmony_ci{
432e5c31af7Sopenharmony_ci	Array<T, Rows*Cols> a;
433e5c31af7Sopenharmony_ci	T* dst = a.getPtr();
434e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
435e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
436e5c31af7Sopenharmony_ci			*dst++ = (*this)(row, col);
437e5c31af7Sopenharmony_ci	return a;
438e5c31af7Sopenharmony_ci}
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_ci// Multiplication of two matrices.
441e5c31af7Sopenharmony_citemplate <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
442e5c31af7Sopenharmony_ciMatrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b)
443e5c31af7Sopenharmony_ci{
444e5c31af7Sopenharmony_ci	DE_STATIC_ASSERT(Cols0 == Rows1);
445e5c31af7Sopenharmony_ci	Matrix<T, Rows0, Cols1> res;
446e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows0; row++)
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols1; col++)
449e5c31af7Sopenharmony_ci		{
450e5c31af7Sopenharmony_ci			T v = T(0);
451e5c31af7Sopenharmony_ci			for (int ndx = 0; ndx < Cols0; ndx++)
452e5c31af7Sopenharmony_ci				v += a(row,ndx) * b(ndx,col);
453e5c31af7Sopenharmony_ci			res(row,col) = v;
454e5c31af7Sopenharmony_ci		}
455e5c31af7Sopenharmony_ci	}
456e5c31af7Sopenharmony_ci	return res;
457e5c31af7Sopenharmony_ci}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci// Multiply of matrix with column vector.
460e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
461e5c31af7Sopenharmony_ciVector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec)
462e5c31af7Sopenharmony_ci{
463e5c31af7Sopenharmony_ci	Vector<T, Rows> res;
464e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
465e5c31af7Sopenharmony_ci	{
466e5c31af7Sopenharmony_ci		T v = T(0);
467e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
468e5c31af7Sopenharmony_ci			v += mtx(row,col) * vec.m_data[col];
469e5c31af7Sopenharmony_ci		res.m_data[row] = v;
470e5c31af7Sopenharmony_ci	}
471e5c31af7Sopenharmony_ci	return res;
472e5c31af7Sopenharmony_ci}
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci// Multiply of matrix with row vector.
475e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
476e5c31af7Sopenharmony_ciVector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx)
477e5c31af7Sopenharmony_ci{
478e5c31af7Sopenharmony_ci	Vector<T, Cols> res;
479e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
480e5c31af7Sopenharmony_ci	{
481e5c31af7Sopenharmony_ci		T v = T(0);
482e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
483e5c31af7Sopenharmony_ci			v += mtx(row,col) * vec.m_data[row];
484e5c31af7Sopenharmony_ci		res.m_data[col] = v;
485e5c31af7Sopenharmony_ci	}
486e5c31af7Sopenharmony_ci	return res;
487e5c31af7Sopenharmony_ci}
488e5c31af7Sopenharmony_ci
489e5c31af7Sopenharmony_ci// Common typedefs.
490e5c31af7Sopenharmony_citypedef Matrix<float, 2, 2>		Matrix2f;
491e5c31af7Sopenharmony_citypedef Matrix<float, 3, 3>		Matrix3f;
492e5c31af7Sopenharmony_citypedef Matrix<float, 4, 4>		Matrix4f;
493e5c31af7Sopenharmony_ci
494e5c31af7Sopenharmony_ci// GLSL-style naming \note CxR.
495e5c31af7Sopenharmony_citypedef Matrix2f			Mat2;
496e5c31af7Sopenharmony_citypedef Matrix<float, 3, 2>	Mat2x3;
497e5c31af7Sopenharmony_citypedef Matrix<float, 4, 2>	Mat2x4;
498e5c31af7Sopenharmony_citypedef Matrix<float, 2, 3>	Mat3x2;
499e5c31af7Sopenharmony_citypedef Matrix3f			Mat3;
500e5c31af7Sopenharmony_citypedef Matrix<float, 4, 3>	Mat3x4;
501e5c31af7Sopenharmony_citypedef Matrix<float, 2, 4>	Mat4x2;
502e5c31af7Sopenharmony_citypedef Matrix<float, 3, 4>	Mat4x3;
503e5c31af7Sopenharmony_citypedef Matrix4f			Mat4;
504e5c31af7Sopenharmony_ci
505e5c31af7Sopenharmony_ci//using tcu::Matrix;
506e5c31af7Sopenharmony_ci// Common typedefs 16Bit.
507e5c31af7Sopenharmony_citypedef Matrix<deUint16, 2, 2>	Matrix2f16b;
508e5c31af7Sopenharmony_citypedef Matrix<deUint16, 3, 3>	Matrix3f16b;
509e5c31af7Sopenharmony_citypedef Matrix<deUint16, 4, 4>	Matrix4f16b;
510e5c31af7Sopenharmony_ci
511e5c31af7Sopenharmony_ci// GLSL-style naming \note CxR.
512e5c31af7Sopenharmony_citypedef Matrix2f16b				Mat2_16b;
513e5c31af7Sopenharmony_citypedef Matrix<deUint16, 3, 2>	Mat2x3_16b;
514e5c31af7Sopenharmony_citypedef Matrix<deUint16, 4, 2>	Mat2x4_16b;
515e5c31af7Sopenharmony_citypedef Matrix<deUint16, 2, 3>	Mat3x2_16b;
516e5c31af7Sopenharmony_citypedef Matrix3f16b				Mat3_16b;
517e5c31af7Sopenharmony_citypedef Matrix<deUint16, 4, 3>	Mat3x4_16b;
518e5c31af7Sopenharmony_citypedef Matrix<deUint16, 2, 4>	Mat4x2_16b;
519e5c31af7Sopenharmony_citypedef Matrix<deUint16, 3, 4>	Mat4x3_16b;
520e5c31af7Sopenharmony_citypedef Matrix4f16b				Mat4_16b;
521e5c31af7Sopenharmony_ci
522e5c31af7Sopenharmony_ci// 64-bit matrices.
523e5c31af7Sopenharmony_citypedef Matrix<double, 2, 2>	Matrix2d;
524e5c31af7Sopenharmony_citypedef Matrix<double, 3, 3>	Matrix3d;
525e5c31af7Sopenharmony_citypedef Matrix<double, 4, 4>	Matrix4d;
526e5c31af7Sopenharmony_ci
527e5c31af7Sopenharmony_ci// GLSL-style naming \note CxR.
528e5c31af7Sopenharmony_citypedef Matrix2d				Mat2d;
529e5c31af7Sopenharmony_citypedef Matrix<double, 3, 2>	Mat2x3d;
530e5c31af7Sopenharmony_citypedef Matrix<double, 4, 2>	Mat2x4d;
531e5c31af7Sopenharmony_citypedef Matrix<double, 2, 3>	Mat3x2d;
532e5c31af7Sopenharmony_citypedef Matrix3d				Mat3d;
533e5c31af7Sopenharmony_citypedef Matrix<double, 4, 3>	Mat3x4d;
534e5c31af7Sopenharmony_citypedef Matrix<double, 2, 4>	Mat4x2d;
535e5c31af7Sopenharmony_citypedef Matrix<double, 3, 4>	Mat4x3d;
536e5c31af7Sopenharmony_citypedef Matrix4d				Mat4d;
537e5c31af7Sopenharmony_ci
538e5c31af7Sopenharmony_ci// Matrix-scalar operators.
539e5c31af7Sopenharmony_ci
540e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
541e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& mtx, T scalar)
542e5c31af7Sopenharmony_ci{
543e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
544e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
545e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
546e5c31af7Sopenharmony_ci			res(row, col) = mtx(row, col) + scalar;
547e5c31af7Sopenharmony_ci	return res;
548e5c31af7Sopenharmony_ci}
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
551e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& mtx, T scalar)
552e5c31af7Sopenharmony_ci{
553e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
554e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
555e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
556e5c31af7Sopenharmony_ci			res(row, col) = mtx(row, col) - scalar;
557e5c31af7Sopenharmony_ci	return res;
558e5c31af7Sopenharmony_ci}
559e5c31af7Sopenharmony_ci
560e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
561e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator* (const Matrix<T, Rows, Cols>& mtx, T scalar)
562e5c31af7Sopenharmony_ci{
563e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
564e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
565e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
566e5c31af7Sopenharmony_ci			res(row, col) = mtx(row, col) * scalar;
567e5c31af7Sopenharmony_ci	return res;
568e5c31af7Sopenharmony_ci}
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
571e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& mtx, T scalar)
572e5c31af7Sopenharmony_ci{
573e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
574e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
575e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
576e5c31af7Sopenharmony_ci			res(row, col) = mtx(row, col) / scalar;
577e5c31af7Sopenharmony_ci	return res;
578e5c31af7Sopenharmony_ci}
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci// Matrix-matrix component-wise operators.
581e5c31af7Sopenharmony_ci
582e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
583e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
584e5c31af7Sopenharmony_ci{
585e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
586e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
587e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
588e5c31af7Sopenharmony_ci			res(row, col) = a(row, col) + b(row, col);
589e5c31af7Sopenharmony_ci	return res;
590e5c31af7Sopenharmony_ci}
591e5c31af7Sopenharmony_ci
592e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
593e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
594e5c31af7Sopenharmony_ci{
595e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
596e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
597e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
598e5c31af7Sopenharmony_ci			res(row, col) = a(row, col) - b(row, col);
599e5c31af7Sopenharmony_ci	return res;
600e5c31af7Sopenharmony_ci}
601e5c31af7Sopenharmony_ci
602e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
603e5c31af7Sopenharmony_ciMatrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
604e5c31af7Sopenharmony_ci{
605e5c31af7Sopenharmony_ci	Matrix<T, Rows, Cols> res;
606e5c31af7Sopenharmony_ci	for (int col = 0; col < Cols; col++)
607e5c31af7Sopenharmony_ci		for (int row = 0; row < Rows; row++)
608e5c31af7Sopenharmony_ci			res(row, col) = a(row, col) / b(row, col);
609e5c31af7Sopenharmony_ci	return res;
610e5c31af7Sopenharmony_ci}
611e5c31af7Sopenharmony_ci
612e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
613e5c31af7Sopenharmony_cibool operator== (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs)
614e5c31af7Sopenharmony_ci{
615e5c31af7Sopenharmony_ci	for (int row = 0; row < Rows; row++)
616e5c31af7Sopenharmony_ci		for (int col = 0; col < Cols; col++)
617e5c31af7Sopenharmony_ci			if (lhs(row, col) != rhs(row, col))
618e5c31af7Sopenharmony_ci				return false;
619e5c31af7Sopenharmony_ci	return true;
620e5c31af7Sopenharmony_ci}
621e5c31af7Sopenharmony_ci
622e5c31af7Sopenharmony_citemplate <typename T, int Rows, int Cols>
623e5c31af7Sopenharmony_cibool operator!= (const Matrix<T, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs)
624e5c31af7Sopenharmony_ci{
625e5c31af7Sopenharmony_ci	return !(lhs == rhs);
626e5c31af7Sopenharmony_ci}
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci} // tcu
629e5c31af7Sopenharmony_ci
630e5c31af7Sopenharmony_ci#endif // _TCUMATRIX_HPP
631