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