webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
matrix_utils.h
Go to the documentation of this file.
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Matrix:
7 // Utility class implementing various matrix operations.
8 // Supports matrices with minimum 2 and maximum 4 number of rows/columns.
9 //
10 // TODO: Check if we can merge Matrix.h in sample_util with this and replace it with this implementation.
11 // TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util.
12 
13 #ifndef COMMON_MATRIX_UTILS_H_
14 #define COMMON_MATRIX_UTILS_H_
15 
16 #include <vector>
17 
18 #include "common/debug.h"
19 #include "common/mathutil.h"
20 
21 namespace angle
22 {
23 
24 template<typename T>
25 class Matrix
26 {
27  public:
28  Matrix(const std::vector<T> &elements, const unsigned int &numRows, const unsigned int &numCols)
29  : mElements(elements),
30  mRows(numRows),
31  mCols(numCols)
32  {
33  ASSERT(rows() >= 1 && rows() <= 4);
34  ASSERT(columns() >= 1 && columns() <= 4);
35  }
36 
37  Matrix(const std::vector<T> &elements, const unsigned int &size)
38  : mElements(elements),
39  mRows(size),
40  mCols(size)
41  {
42  ASSERT(rows() >= 1 && rows() <= 4);
43  ASSERT(columns() >= 1 && columns() <= 4);
44  }
45 
46  Matrix(const T *elements, const unsigned int &size)
47  : mRows(size),
48  mCols(size)
49  {
50  ASSERT(rows() >= 1 && rows() <= 4);
51  ASSERT(columns() >= 1 && columns() <= 4);
52  for (size_t i = 0; i < size * size; i++)
53  mElements.push_back(elements[i]);
54  }
55 
56  const T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) const
57  {
58  return mElements[rowIndex * columns() + columnIndex];
59  }
60 
61  T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex)
62  {
63  return mElements[rowIndex * columns() + columnIndex];
64  }
65 
66  const T &at(const unsigned int &rowIndex, const unsigned int &columnIndex) const
67  {
68  return operator()(rowIndex, columnIndex);
69  }
70 
72  {
73  ASSERT(columns() == m.rows());
74 
75  unsigned int resultRows = rows();
76  unsigned int resultCols = m.columns();
77  Matrix<T> result(std::vector<T>(resultRows * resultCols), resultRows, resultCols);
78  for (unsigned int i = 0; i < resultRows; i++)
79  {
80  for (unsigned int j = 0; j < resultCols; j++)
81  {
82  T tmp = 0.0f;
83  for (unsigned int k = 0; k < columns(); k++)
84  tmp += at(i, k) * m(k, j);
85  result(i, j) = tmp;
86  }
87  }
88 
89  return result;
90  }
91 
92  unsigned int size() const
93  {
94  ASSERT(rows() == columns());
95  return rows();
96  }
97 
98  unsigned int rows() const { return mRows; }
99 
100  unsigned int columns() const { return mCols; }
101 
102  std::vector<T> elements() const { return mElements; }
103 
104  Matrix<T> compMult(const Matrix<T> &mat1) const
105  {
106  Matrix result(std::vector<T>(mElements.size()), size());
107  for (unsigned int i = 0; i < columns(); i++)
108  for (unsigned int j = 0; j < rows(); j++)
109  result(i, j) = at(i, j) * mat1(i, j);
110 
111  return result;
112  }
113 
114  Matrix<T> outerProduct(const Matrix<T> &mat1) const
115  {
116  unsigned int cols = mat1.columns();
117  Matrix result(std::vector<T>(rows() * cols), rows(), cols);
118  for (unsigned int i = 0; i < rows(); i++)
119  for (unsigned int j = 0; j < cols; j++)
120  result(i, j) = at(i, 0) * mat1(0, j);
121 
122  return result;
123  }
124 
126  {
127  Matrix result(std::vector<T>(mElements.size()), columns(), rows());
128  for (unsigned int i = 0; i < columns(); i++)
129  for (unsigned int j = 0; j < rows(); j++)
130  result(i, j) = at(j, i);
131 
132  return result;
133  }
134 
135  T determinant() const
136  {
137  ASSERT(rows() == columns());
138 
139  switch (size())
140  {
141  case 2:
142  return at(0, 0) * at(1, 1) - at(0, 1) * at(1, 0);
143 
144  case 3:
145  return at(0, 0) * at(1, 1) * at(2, 2) +
146  at(0, 1) * at(1, 2) * at(2, 0) +
147  at(0, 2) * at(1, 0) * at(2, 1) -
148  at(0, 2) * at(1, 1) * at(2, 0) -
149  at(0, 1) * at(1, 0) * at(2, 2) -
150  at(0, 0) * at(1, 2) * at(2, 1);
151 
152  case 4:
153  {
154  const float minorMatrices[4][3 * 3] =
155  {
156  {
157  at(1, 1), at(2, 1), at(3, 1),
158  at(1, 2), at(2, 2), at(3, 2),
159  at(1, 3), at(2, 3), at(3, 3),
160  },
161  {
162  at(1, 0), at(2, 0), at(3, 0),
163  at(1, 2), at(2, 2), at(3, 2),
164  at(1, 3), at(2, 3), at(3, 3),
165  },
166  {
167  at(1, 0), at(2, 0), at(3, 0),
168  at(1, 1), at(2, 1), at(3, 1),
169  at(1, 3), at(2, 3), at(3, 3),
170  },
171  {
172  at(1, 0), at(2, 0), at(3, 0),
173  at(1, 1), at(2, 1), at(3, 1),
174  at(1, 2), at(2, 2), at(3, 2),
175  }
176  };
177  return at(0, 0) * Matrix<T>(minorMatrices[0], 3).determinant() -
178  at(0, 1) * Matrix<T>(minorMatrices[1], 3).determinant() +
179  at(0, 2) * Matrix<T>(minorMatrices[2], 3).determinant() -
180  at(0, 3) * Matrix<T>(minorMatrices[3], 3).determinant();
181  }
182 
183  default:
184  UNREACHABLE();
185  break;
186  }
187 
188  return T();
189  }
190 
192  {
193  ASSERT(rows() == columns());
194 
195  Matrix<T> cof(std::vector<T>(mElements.size()), rows(), columns());
196  switch (size())
197  {
198  case 2:
199  cof(0, 0) = at(1, 1);
200  cof(0, 1) = -at(1, 0);
201  cof(1, 0) = -at(0, 1);
202  cof(1, 1) = at(0, 0);
203  break;
204 
205  case 3:
206  cof(0, 0) = at(1, 1) * at(2, 2) -
207  at(2, 1) * at(1, 2);
208  cof(0, 1) = -(at(1, 0) * at(2, 2) -
209  at(2, 0) * at(1, 2));
210  cof(0, 2) = at(1, 0) * at(2, 1) -
211  at(2, 0) * at(1, 1);
212  cof(1, 0) = -(at(0, 1) * at(2, 2) -
213  at(2, 1) * at(0, 2));
214  cof(1, 1) = at(0, 0) * at(2, 2) -
215  at(2, 0) * at(0, 2);
216  cof(1, 2) = -(at(0, 0) * at(2, 1) -
217  at(2, 0) * at(0, 1));
218  cof(2, 0) = at(0, 1) * at(1, 2) -
219  at(1, 1) * at(0, 2);
220  cof(2, 1) = -(at(0, 0) * at(1, 2) -
221  at(1, 0) * at(0, 2));
222  cof(2, 2) = at(0, 0) * at(1, 1) -
223  at(1, 0) * at(0, 1);
224  break;
225 
226  case 4:
227  cof(0, 0) = at(1, 1) * at(2, 2) * at(3, 3) +
228  at(2, 1) * at(3, 2) * at(1, 3) +
229  at(3, 1) * at(1, 2) * at(2, 3) -
230  at(1, 1) * at(3, 2) * at(2, 3) -
231  at(2, 1) * at(1, 2) * at(3, 3) -
232  at(3, 1) * at(2, 2) * at(1, 3);
233  cof(0, 1) = -(at(1, 0) * at(2, 2) * at(3, 3) +
234  at(2, 0) * at(3, 2) * at(1, 3) +
235  at(3, 0) * at(1, 2) * at(2, 3) -
236  at(1, 0) * at(3, 2) * at(2, 3) -
237  at(2, 0) * at(1, 2) * at(3, 3) -
238  at(3, 0) * at(2, 2) * at(1, 3));
239  cof(0, 2) = at(1, 0) * at(2, 1) * at(3, 3) +
240  at(2, 0) * at(3, 1) * at(1, 3) +
241  at(3, 0) * at(1, 1) * at(2, 3) -
242  at(1, 0) * at(3, 1) * at(2, 3) -
243  at(2, 0) * at(1, 1) * at(3, 3) -
244  at(3, 0) * at(2, 1) * at(1, 3);
245  cof(0, 3) = -(at(1, 0) * at(2, 1) * at(3, 2) +
246  at(2, 0) * at(3, 1) * at(1, 2) +
247  at(3, 0) * at(1, 1) * at(2, 2) -
248  at(1, 0) * at(3, 1) * at(2, 2) -
249  at(2, 0) * at(1, 1) * at(3, 2) -
250  at(3, 0) * at(2, 1) * at(1, 2));
251  cof(1, 0) = -(at(0, 1) * at(2, 2) * at(3, 3) +
252  at(2, 1) * at(3, 2) * at(0, 3) +
253  at(3, 1) * at(0, 2) * at(2, 3) -
254  at(0, 1) * at(3, 2) * at(2, 3) -
255  at(2, 1) * at(0, 2) * at(3, 3) -
256  at(3, 1) * at(2, 2) * at(0, 3));
257  cof(1, 1) = at(0, 0) * at(2, 2) * at(3, 3) +
258  at(2, 0) * at(3, 2) * at(0, 3) +
259  at(3, 0) * at(0, 2) * at(2, 3) -
260  at(0, 0) * at(3, 2) * at(2, 3) -
261  at(2, 0) * at(0, 2) * at(3, 3) -
262  at(3, 0) * at(2, 2) * at(0, 3);
263  cof(1, 2) = -(at(0, 0) * at(2, 1) * at(3, 3) +
264  at(2, 0) * at(3, 1) * at(0, 3) +
265  at(3, 0) * at(0, 1) * at(2, 3) -
266  at(0, 0) * at(3, 1) * at(2, 3) -
267  at(2, 0) * at(0, 1) * at(3, 3) -
268  at(3, 0) * at(2, 1) * at(0, 3));
269  cof(1, 3) = at(0, 0) * at(2, 1) * at(3, 2) +
270  at(2, 0) * at(3, 1) * at(0, 2) +
271  at(3, 0) * at(0, 1) * at(2, 2) -
272  at(0, 0) * at(3, 1) * at(2, 2) -
273  at(2, 0) * at(0, 1) * at(3, 2) -
274  at(3, 0) * at(2, 1) * at(0, 2);
275  cof(2, 0) = at(0, 1) * at(1, 2) * at(3, 3) +
276  at(1, 1) * at(3, 2) * at(0, 3) +
277  at(3, 1) * at(0, 2) * at(1, 3) -
278  at(0, 1) * at(3, 2) * at(1, 3) -
279  at(1, 1) * at(0, 2) * at(3, 3) -
280  at(3, 1) * at(1, 2) * at(0, 3);
281  cof(2, 1) = -(at(0, 0) * at(1, 2) * at(3, 3) +
282  at(1, 0) * at(3, 2) * at(0, 3) +
283  at(3, 0) * at(0, 2) * at(1, 3) -
284  at(0, 0) * at(3, 2) * at(1, 3) -
285  at(1, 0) * at(0, 2) * at(3, 3) -
286  at(3, 0) * at(1, 2) * at(0, 3));
287  cof(2, 2) = at(0, 0) * at(1, 1) * at(3, 3) +
288  at(1, 0) * at(3, 1) * at(0, 3) +
289  at(3, 0) * at(0, 1) * at(1, 3) -
290  at(0, 0) * at(3, 1) * at(1, 3) -
291  at(1, 0) * at(0, 1) * at(3, 3) -
292  at(3, 0) * at(1, 1) * at(0, 3);
293  cof(2, 3) = -(at(0, 0) * at(1, 1) * at(3, 2) +
294  at(1, 0) * at(3, 1) * at(0, 2) +
295  at(3, 0) * at(0, 1) * at(1, 2) -
296  at(0, 0) * at(3, 1) * at(1, 2) -
297  at(1, 0) * at(0, 1) * at(3, 2) -
298  at(3, 0) * at(1, 1) * at(0, 2));
299  cof(3, 0) = -(at(0, 1) * at(1, 2) * at(2, 3) +
300  at(1, 1) * at(2, 2) * at(0, 3) +
301  at(2, 1) * at(0, 2) * at(1, 3) -
302  at(0, 1) * at(2, 2) * at(1, 3) -
303  at(1, 1) * at(0, 2) * at(2, 3) -
304  at(2, 1) * at(1, 2) * at(0, 3));
305  cof(3, 1) = at(0, 0) * at(1, 2) * at(2, 3) +
306  at(1, 0) * at(2, 2) * at(0, 3) +
307  at(2, 0) * at(0, 2) * at(1, 3) -
308  at(0, 0) * at(2, 2) * at(1, 3) -
309  at(1, 0) * at(0, 2) * at(2, 3) -
310  at(2, 0) * at(1, 2) * at(0, 3);
311  cof(3, 2) = -(at(0, 0) * at(1, 1) * at(2, 3) +
312  at(1, 0) * at(2, 1) * at(0, 3) +
313  at(2, 0) * at(0, 1) * at(1, 3) -
314  at(0, 0) * at(2, 1) * at(1, 3) -
315  at(1, 0) * at(0, 1) * at(2, 3) -
316  at(2, 0) * at(1, 1) * at(0, 3));
317  cof(3, 3) = at(0, 0) * at(1, 1) * at(2, 2) +
318  at(1, 0) * at(2, 1) * at(0, 2) +
319  at(2, 0) * at(0, 1) * at(1, 2) -
320  at(0, 0) * at(2, 1) * at(1, 2) -
321  at(1, 0) * at(0, 1) * at(2, 2) -
322  at(2, 0) * at(1, 1) * at(0, 2);
323  break;
324 
325  default:
326  UNREACHABLE();
327  break;
328  }
329 
330  // The inverse of A is the transpose of the cofactor matrix times the reciprocal of the determinant of A.
331  Matrix<T> adjugateMatrix(cof.transpose());
332  T det = determinant();
333  Matrix<T> result(std::vector<T>(mElements.size()), rows(), columns());
334  for (unsigned int i = 0; i < rows(); i++)
335  for (unsigned int j = 0; j < columns(); j++)
336  result(i, j) = det ? adjugateMatrix(i, j) / det : T();
337 
338  return result;
339  }
340 
342  {
343  ASSERT(rows() == columns());
344 
345  const auto one = T(1);
346  const auto zero = T(0);
347 
348  for (auto &e : mElements)
349  e = zero;
350 
351  for (unsigned int i = 0; i < rows(); ++i)
352  {
353  const auto pos = i * columns() + (i % columns());
354  mElements[pos] = one;
355  }
356  }
357 
358  template <unsigned int Size>
359  static void setToIdentity(T(&matrix)[Size])
360  {
361  static_assert(gl::iSquareRoot<Size>() != 0, "Matrix is not square.");
362 
363  const auto cols = gl::iSquareRoot<Size>();
364  const auto one = T(1);
365  const auto zero = T(0);
366 
367  for (auto &e : matrix)
368  e = zero;
369 
370  for (unsigned int i = 0; i < cols; ++i)
371  {
372  const auto pos = i * cols + (i % cols);
373  matrix[pos] = one;
374  }
375  }
376 
377  private:
378  std::vector<T> mElements;
379  unsigned int mRows;
380  unsigned int mCols;
381 };
382 
383 } // namespace angle
384 
385 #endif // COMMON_MATRIX_UTILS_H_
386 
static void setToIdentity(T(&matrix)[Size])
Definition: matrix_utils.h:359
EGLStreamKHR EGLint EGLint EGLint size
Definition: eglext.h:984
Matrix< T > operator*(const Matrix< T > &m)
Definition: matrix_utils.h:71
std::vector< T > elements() const
Definition: matrix_utils.h:102
T & operator()(const unsigned int &rowIndex, const unsigned int &columnIndex)
Definition: matrix_utils.h:61
uint32_t Size
Definition: wav_header.cc:30
Definition: matrix_utils.h:25
const GLfloat * m
Definition: gl2ext.h:850
Matrix< T > transpose() const
Definition: matrix_utils.h:125
Matrix(const std::vector< T > &elements, const unsigned int &size)
Definition: matrix_utils.h:37
#define UNREACHABLE
Definition: utils.h:36
const T & at(const unsigned int &rowIndex, const unsigned int &columnIndex) const
Definition: matrix_utils.h:66
unsigned int size() const
Definition: matrix_utils.h:92
unsigned int rows() const
Definition: matrix_utils.h:98
DOMString k
Definition: WebCryptoAPI.idl:122
TestSubObjConstructor T
Definition: TestTypedefs.idl:84
Definition: Platform.h:33
Matrix< T > inverse() const
Definition: matrix_utils.h:191
Matrix< T > outerProduct(const Matrix< T > &mat1) const
Definition: matrix_utils.h:114
result
Definition: target-blank-opener-post-window.php:5
const T & operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) const
Definition: matrix_utils.h:56
for i
Definition: complexityMeasures.m:24
Matrix(const T *elements, const unsigned int &size)
Definition: matrix_utils.h:46
Matrix(const std::vector< T > &elements, const unsigned int &numRows, const unsigned int &numCols)
Definition: matrix_utils.h:28
DOMString e
Definition: WebCryptoAPI.idl:115
void matrix(float &red, float &green, float &blue, float &alpha, const Vector< float > &values)
Definition: FEColorMatrix.cpp:73
unsigned int columns() const
Definition: matrix_utils.h:100
void setToIdentity()
Definition: matrix_utils.h:341
T determinant() const
Definition: matrix_utils.h:135
#define ASSERT(assertion)
Definition: Assertions.h:283
for for j
Definition: complexityMeasures.m:25
Matrix< T > compMult(const Matrix< T > &mat1) const
Definition: matrix_utils.h:104
#define T(a)
Definition: row_common.cc:1964