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