13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _TCUMATRIX_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _TCUMATRIX_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief 	Templatized matrix class.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Array
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Array			(void) {}
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~Array			(void) {}
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline T		operator[]		(int ndx) const		{ return m_data[ndx]; }
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline T&		operator[]		(int ndx)			{ return m_data[ndx]; }
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline const T*	getPtr			(void) const		{ return m_data; }
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline T*		getPtr			(void)				{ return m_data; }
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T				m_data[Size];
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Templated matrix class.
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Matrix
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef	Vector<T, Rows>			Element;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef	T						Scalar;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SIZE = Cols,
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ROWS = Rows,
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		COLS = Cols,
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Matrix				(void);
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	explicit						Matrix				(const T& src);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	explicit						Matrix				(const T src[Rows*Cols]);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Matrix				(const Vector<T, Rows>& src);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									Matrix				(const Matrix<T, Rows, Cols>& src);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~Matrix				(void);
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols>&			operator=			(const Matrix<T, Rows, Cols>& src);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols>&			operator*=			(const Matrix<T, Rows, Cols>& src);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							setRow				(int rowNdx, const Vector<T, Cols>& vec);
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							setColumn			(int colNdx, const Vector<T, Rows>& vec);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Cols>					getRow				(int ndx) const;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Rows>&				getColumn			(int ndx);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vector<T, Rows>&			getColumn			(int ndx) const;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Rows>&				operator[]			(int ndx)					{ return getColumn(ndx);	}
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vector<T, Rows>&			operator[]			(int ndx) const				{ return getColumn(ndx);	}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline const T&					operator()			(int row, int col) const	{ return m_data[col][row];	}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	inline T&						operator()			(int row, int col)			{ return m_data[col][row];	}
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Array<T, Rows*Cols>				getRowMajorData		(void) const;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Array<T, Rows*Cols>				getColumnMajorData	(void) const;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<Vector<T, Rows>, Cols>	m_data;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Operators.
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Mat * Mat.
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Mat * Vec (column vector).
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
1023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec);
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Vec * Mat (row vector).
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
1063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx);
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Further operations
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size>
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct SquareMatrixOps
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static T						doDeterminant	(const Matrix<T, Size, Size>& mat);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static Matrix<T, Size, Size>	doInverse		(const Matrix<T, Size, Size>& mat);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct SquareMatrixOps<T, 2>
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static T						doDeterminant	(const Matrix<T, 2, 2>& mat);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static Matrix<T, 2, 2>			doInverse		(const Matrix<T, 2, 2>& mat);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct SquareMatrixOps<T, 3>
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static T						doDeterminant	(const Matrix<T, 3, 3>& mat);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static Matrix<T, 3, 3>			doInverse		(const Matrix<T, 3, 3>& mat);
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct SquareMatrixOps<T, 4>
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static T						doDeterminant	(const Matrix<T, 4, 4>& mat);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static Matrix<T, 4, 4>			doInverse		(const Matrix<T, 4, 4>& mat);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace matrix
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size>
1423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryT determinant (const Matrix<T, Size, Size>& mat)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return SquareMatrixOps<T, Size>::doDeterminant(mat);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Size>
1483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Size, Size> inverse (const Matrix<T, Size, Size>& mat)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return SquareMatrixOps<T, Size>::doInverse(mat);
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // matrix
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Template implementations.
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryT SquareMatrixOps<T, 2>::doDeterminant (const Matrix<T, 2, 2>& mat)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryT SquareMatrixOps<T, 3>::doDeterminant (const Matrix<T, 3, 3>& mat)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	+ mat(0,0) * mat(1,1) * mat(2,2)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,1) * mat(1,2) * mat(2,0)
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,2) * mat(1,0) * mat(2,1)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,0) * mat(1,2) * mat(2,1)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,1) * mat(1,0) * mat(2,2)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,2) * mat(1,1) * mat(2,0);
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryT SquareMatrixOps<T, 4>::doDeterminant (const Matrix<T, 4, 4>& mat)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using matrix::determinant;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T minorMatrices[4][3*3] =
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	+ mat(0,0) * determinant(Matrix<T, 3, 3>(minorMatrices[0]))
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,1) * determinant(Matrix<T, 3, 3>(minorMatrices[1]))
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,2) * determinant(Matrix<T, 3, 3>(minorMatrices[2]))
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,3) * determinant(Matrix<T, 3, 3>(minorMatrices[3]));
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, 2, 2> SquareMatrixOps<T, 2>::doInverse (const Matrix<T, 2, 2>& mat)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using matrix::determinant;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T			det		= determinant(mat);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, 2, 2>	retVal;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(0, 0) =  mat(1, 1) / det;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(0, 1) = -mat(0, 1) / det;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(1, 0) = -mat(1, 0) / det;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(1, 1) =  mat(0, 0) / det;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, 3, 3> SquareMatrixOps<T, 3>::doInverse (const Matrix<T, 3, 3>& mat)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Blockwise inversion
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using matrix::inverse;
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaA[2*2] =
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,0),	mat(0,1),
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,0),	mat(1,1)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaB[2] =
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,2),
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,2),
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaC[2] =
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,0),	mat(2,1),
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaD[1] =
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,2)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T nullField[4] = { T(0.0f) };
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2>	invA = inverse(Matrix<T, 2, 2>(areaA));
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 1>	matB =         Matrix<T, 2, 1>(areaB);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 1, 2>	matC =         Matrix<T, 1, 2>(areaC);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 1, 1>	matD =         Matrix<T, 1, 1>(areaD);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T					schurComplement = T(1.0f) / (matD - matC*invA*matB)(0,0);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2>	zeroMat         = Matrix<T, 2, 2>(nullField);
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2>	blockA = invA + invA*matB*schurComplement*matC*invA;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 1>	blockB = (zeroMat-invA)*matB*schurComplement;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 1, 2>	blockC = matC*invA*(-schurComplement);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T					blockD = schurComplement;
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T result[3*3] =
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(0,0),	blockA(0,1),	blockB(0,0),
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(1,0),	blockA(1,1),	blockB(1,0),
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(0,0),	blockC(0,1),	blockD,
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Matrix<T, 3, 3>(result);
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, 4, 4> SquareMatrixOps<T, 4>::doInverse (const Matrix<T, 4, 4>& mat)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Blockwise inversion
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using matrix::inverse;
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaA[2*2] =
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,0),	mat(0,1),
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,0),	mat(1,1)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaB[2*2] =
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,2),	mat(0,3),
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,2),	mat(1,3)
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaC[2*2] =
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,0),	mat(2,1),
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(3,0),	mat(3,1)
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T areaD[2*2] =
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,2),	mat(2,3),
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(3,2),	mat(3,3)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T nullField[4] = { T(0.0f) };
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> invA = inverse(Matrix<T, 2, 2>(areaA));
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> matB =         Matrix<T, 2, 2>(areaB);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> matC =         Matrix<T, 2, 2>(areaC);
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> matD =         Matrix<T, 2, 2>(areaD);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> zeroMat         = Matrix<T, 2, 2>(nullField);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Matrix<T, 2, 2> blockD = schurComplement;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const T result[4*4] =
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(0,0),	blockA(0,1),	blockB(0,0),	blockB(0,1),
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(1,0),	blockA(1,1),	blockB(1,0),	blockB(1,1),
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(0,0),	blockC(0,1),	blockD(0,0),	blockD(0,1),
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(1,0),	blockC(1,1),	blockD(1,0),	blockD(1,1),
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Matrix<T, 4, 4>(result);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Initialize to identity.
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3283c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::Matrix (void)
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*this)(row, col) = (row == col) ? T(1) : T(0);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Initialize to diagonal matrix.
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::Matrix (const T& src)
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*this)(row, col) = (row == col) ? src : T(0);
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Initialize from data array.
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::Matrix (const T src[Rows*Cols])
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*this)(row, col) = src[row*Cols + col];
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Initialize to diagonal matrix.
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::Matrix (const Vector<T, Rows>& src)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(Rows == Cols);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*this)(row, col) = (row == col) ? src.m_data[row] : T(0);
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Copy constructor.
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::Matrix (const Matrix<T, Rows, Cols>& src)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	*this = src;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Destructor.
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>::~Matrix (void)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Assignment operator.
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator= (const Matrix<T, Rows, Cols>& src)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(*this)(row, col) = src(row, col);
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Multipy and assign op
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols>& Matrix<T, Rows, Cols>::operator*= (const Matrix<T, Rows, Cols>& src)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	*this = *this * src;
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return *this;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Matrix<T, Rows, Cols>::setRow (int rowNdx, const Vector<T, Cols>& vec)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*this)(rowNdx, col) = vec.m_data[col];
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Matrix<T, Rows, Cols>::setColumn (int colNdx, const Vector<T, Rows>& vec)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data[colNdx] = vec;
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Cols> Matrix<T, Rows, Cols>::getRow (int rowNdx) const
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Cols> res;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res[col] = (*this)(rowNdx, col);
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_data[colNdx];
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst Vector<T, Rows>& Matrix<T, Rows, Cols>::getColumn (int colNdx) const
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_data[colNdx];
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryArray<T, Rows*Cols> Matrix<T, Rows, Cols>::getColumnMajorData (void) const
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Array<T, Rows*Cols> a;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T* dst = a.getPtr();
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*dst++ = (*this)(row, col);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryArray<T, Rows*Cols> Matrix<T, Rows, Cols>::getRowMajorData (void) const
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Array<T, Rows*Cols> a;
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	T* dst = a.getPtr();
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			*dst++ = (*this)(row, col);
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Multiplication of two matrices.
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows0, int Cols0, int Rows1, int Cols1>
4523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows0, Cols1> operator* (const Matrix<T, Rows0, Cols0>& a, const Matrix<T, Rows1, Cols1>& b)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(Cols0 == Rows1);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows0, Cols1> res;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows0; row++)
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols1; col++)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			T v = T(0);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < Cols0; ndx++)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				v += a(row,ndx) * b(ndx,col);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row,col) = v;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Multiply of matrix with column vector.
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Rows> operator* (const Matrix<T, Rows, Cols>& mtx, const Vector<T, Cols>& vec)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Rows> res;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int row = 0; row < Rows; row++)
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		T v = T(0);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int col = 0; col < Cols; col++)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			v += mtx(row,col) * vec.m_data[col];
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res.m_data[row] = v;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Multiply of matrix with row vector.
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVector<T, Cols> operator* (const Vector<T, Rows>& vec, const Matrix<T, Rows, Cols>& mtx)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vector<T, Cols> res;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		T v = T(0);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			v += mtx(row,col) * vec.m_data[row];
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res.m_data[col] = v;
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Common typedefs.
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 2, 2>		Matrix2f;
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 3, 3>		Matrix3f;
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 4, 4>		Matrix4f;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<double, 2, 2>	Matrix2d;
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<double, 3, 3>	Matrix3d;
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<double, 4, 4>	Matrix4d;
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// GLSL-style naming \note CxR.
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix2f			Mat2;
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 3, 2>	Mat2x3;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 4, 2>	Mat2x4;
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 2, 3>	Mat3x2;
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix3f			Mat3;
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 4, 3>	Mat3x4;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 2, 4>	Mat4x2;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix<float, 3, 4>	Mat4x3;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef Matrix4f			Mat4;
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Matrix-scalar operators.
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& mtx, T scalar)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = mtx(row, col) + scalar;
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& mtx, T scalar)
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = mtx(row, col) - scalar;
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator* (const Matrix<T, Rows, Cols>& mtx, T scalar)
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = mtx(row, col) * scalar;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& mtx, T scalar)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = mtx(row, col) / scalar;
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Matrix-matrix component-wise operators.
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator+ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = a(row, col) + b(row, col);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator- (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = a(row, col) - b(row, col);
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
5833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrix<T, Rows, Cols> operator/ (const Matrix<T, Rows, Cols>& a, const Matrix<T, Rows, Cols>& b)
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Matrix<T, Rows, Cols> res;
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int col = 0; col < Cols; col++)
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int row = 0; row < Rows; row++)
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			res(row, col) = a(row, col) / b(row, col);
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // namespace tcu
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _TCUMATRIX_HPP
595