Matrix2x2-Impl.h
Go to the documentation of this file.
1 /*************************************************************************
2 > File Name: Matrix2x2-Impl.h
3 > Project Name: CubbyFlow
4 > Author: Dongmin Kim
5 > Purpose: 2-D matrix class.
6 > Created Time: 2017/03/06
7 > Copyright (c) 2018, Dongmin Kim
8 *************************************************************************/
9 #ifndef CUBBYFLOW_MATRIX2X2_IMPL_H
10 #define CUBBYFLOW_MATRIX2X2_IMPL_H
11 
12 #include <algorithm>
13 #include <cassert>
14 
15 namespace CubbyFlow
16 {
17  template <typename T>
19  {
20  Set(1, 0,
21  0, 1);
22  }
23 
24  template <typename T>
26  {
27  Set(s);
28  }
29 
30  template <typename T>
32  T m10, T m11)
33  {
34  Set(m00, m01,
35  m10, m11);
36  }
37 
38  template <typename T>
39  template <typename U>
40  Matrix<T, 2, 2>::Matrix(const std::initializer_list<std::initializer_list<U>>& list)
41  {
42  Set(list);
43  }
44 
45  template <typename T>
47  {
48  Set(m);
49  }
50 
51  template <typename T>
53  {
54  Set(arr);
55  }
56 
57  template <typename T>
59  {
60  m_elements[0] = s;
61  m_elements[1] = s;
62  m_elements[2] = s;
63  m_elements[3] = s;
64  }
65 
66  template <typename T>
67  void Matrix<T, 2, 2>::Set(T m00, T m01,
68  T m10, T m11)
69  {
70  m_elements[0] = m00;
71  m_elements[1] = m01;
72  m_elements[2] = m10;
73  m_elements[3] = m11;
74  }
75 
76  template <typename T>
77  template <typename U>
78  void Matrix<T, 2, 2>::Set(const std::initializer_list<std::initializer_list<U>>& list)
79  {
80  size_t height = list.size();
81  size_t width = (height > 0) ? list.begin()->size() : 0;
82 
83  assert(width == 2);
84  assert(height == 2);
85 
86  auto rowIter = list.begin();
87  for (size_t i = 0; i < height; ++i)
88  {
89  assert(width == rowIter->size());
90 
91  auto colIter = rowIter->begin();
92  for (size_t j = 0; j < width; ++j)
93  {
94  (*this)(i, j) = static_cast<T>(*colIter);
95  ++colIter;
96  }
97 
98  ++rowIter;
99  }
100  }
101 
102  template <typename T>
104  {
105  for (size_t i = 0; i < 4; ++i)
106  {
107  m_elements[i] = m.m_elements[i];
108  }
109  }
110 
111  template <typename T>
112  void Matrix<T, 2, 2>::Set(const T* arr)
113  {
114  for (size_t i = 0; i < 4; ++i)
115  {
116  m_elements[i] = arr[i];
117  }
118  }
119 
120  template <typename T>
122  {
123  m_elements[0] = s;
124  m_elements[3] = s;
125  }
126 
127  template <typename T>
129  {
130  m_elements[1] = s;
131  m_elements[2] = s;
132  }
133 
134  template <typename T>
135  void Matrix<T, 2, 2>::SetRow(size_t i, const Vector2<T>& row)
136  {
137  m_elements[i * 2] = row.x;
138  m_elements[i * 2 + 1] = row.y;
139  }
140 
141  template <typename T>
142  void Matrix<T, 2, 2>::SetColumn(size_t i, const Vector2<T>& col)
143  {
144  m_elements[i] = col.x;
145  m_elements[i + 2] = col.y;
146  }
147 
148  template <typename T>
149  bool Matrix<T, 2, 2>::IsSimilar(const Matrix& m, double tol) const
150  {
151  return
152  (std::fabs(m_elements[0] - m.m_elements[0]) < tol) &&
153  (std::fabs(m_elements[1] - m.m_elements[1]) < tol) &&
154  (std::fabs(m_elements[2] - m.m_elements[2]) < tol) &&
155  (std::fabs(m_elements[3] - m.m_elements[3]) < tol);
156  }
157 
158  template <typename T>
160  {
161  return true;
162  }
163 
164  template <typename T>
165  size_t Matrix<T, 2, 2>::Rows() const
166  {
167  return 2;
168  }
169 
170  template <typename T>
171  size_t Matrix<T, 2, 2>::Cols() const
172  {
173  return 2;
174  }
175 
176  template <typename T>
178  {
179  return m_elements.data();
180  }
181 
182  template <typename T>
183  const T* Matrix<T, 2, 2>::data() const
184  {
185  return m_elements.data();
186  }
187 
188  template <typename T>
190  {
191  return Matrix<T, 2, 2>(
192  m_elements[0] + s, m_elements[1] + s,
193  m_elements[2] + s, m_elements[3] + s);
194  }
195 
196  template <typename T>
198  {
199  return Matrix<T, 2, 2>(
200  m_elements[0] + m.m_elements[0], m_elements[1] + m.m_elements[1],
201  m_elements[2] + m.m_elements[2], m_elements[3] + m.m_elements[3]);
202  }
203 
204  template <typename T>
206  {
207  return Matrix<T, 2, 2>(
208  m_elements[0] - s, m_elements[1] - s,
209  m_elements[2] - s, m_elements[3] - s);
210  }
211 
212  template <typename T>
214  {
215  return Matrix<T, 2, 2>(
216  m_elements[0] - m.m_elements[0], m_elements[1] - m.m_elements[1],
217  m_elements[2] - m.m_elements[2], m_elements[3] - m.m_elements[3]);
218  }
219 
220  template <typename T>
222  {
223  return Matrix<T, 2, 2>(
224  m_elements[0] * s, m_elements[1] * s,
225  m_elements[2] * s, m_elements[3] * s);
226  }
227 
228  template <typename T>
230  {
231  return Vector<T, 2>(
232  m_elements[0] * v.x + m_elements[1] * v.y,
233  m_elements[2] * v.x + m_elements[3] * v.y);
234  }
235 
236  template <typename T>
238  {
239  return Matrix<T, 2, 2>(
240  m_elements[0] * m.m_elements[0] + m_elements[1] * m.m_elements[2],
241  m_elements[0] * m.m_elements[1] + m_elements[1] * m.m_elements[3],
242  m_elements[2] * m.m_elements[0] + m_elements[3] * m.m_elements[2],
243  m_elements[2] * m.m_elements[1] + m_elements[3] * m.m_elements[3]);
244  }
245 
246  template <typename T>
248  {
249  return Matrix<T, 2, 2>(
250  m_elements[0] / s, m_elements[1] / s,
251  m_elements[2] / s, m_elements[3] / s);
252  }
253 
254  template <typename T>
256  {
257  return Matrix<T, 2, 2>(
258  s + m_elements[0], s + m_elements[1],
259  s + m_elements[2], s + m_elements[3]);
260  }
261 
262  template <typename T>
264  {
265  return Matrix<T, 2, 2>(
266  m.m_elements[0] + m_elements[0], m.m_elements[1] + m_elements[1],
267  m.m_elements[2] + m_elements[2], m.m_elements[3] + m_elements[3]);
268  }
269 
270  template <typename T>
272  {
273  return Matrix<T, 2, 2>(
274  s - m_elements[0], s - m_elements[1],
275  s - m_elements[2], s - m_elements[3]);
276  }
277 
278  template <typename T>
280  {
281  return Matrix<T, 2, 2>(
282  m.m_elements[0] - m_elements[0], m.m_elements[1] - m_elements[1],
283  m.m_elements[2] - m_elements[2], m.m_elements[3] - m_elements[3]);
284  }
285 
286  template <typename T>
288  {
289  return Matrix<T, 2, 2>(
290  s * m_elements[0], s * m_elements[1],
291  s * m_elements[2], s * m_elements[3]);
292  }
293 
294  template <typename T>
296  {
297  return m.Mul(*this);
298  }
299 
300  template <typename T>
302  {
303  return Matrix<T, 2, 2>(
304  s / m_elements[0], s / m_elements[1],
305  s / m_elements[2], s / m_elements[3]);
306  }
307 
308  template <typename T>
310  {
311  m_elements[0] += s;
312  m_elements[1] += s;
313  m_elements[2] += s;
314  m_elements[3] += s;
315  }
316 
317  template <typename T>
319  {
320  m_elements[0] += m.m_elements[0];
321  m_elements[1] += m.m_elements[1];
322  m_elements[2] += m.m_elements[2];
323  m_elements[3] += m.m_elements[3];
324  }
325 
326  template <typename T>
328  {
329  m_elements[0] -= s;
330  m_elements[1] -= s;
331  m_elements[2] -= s;
332  m_elements[3] -= s;
333  }
334 
335  template <typename T>
337  {
338  m_elements[0] -= m.m_elements[0];
339  m_elements[1] -= m.m_elements[1];
340  m_elements[2] -= m.m_elements[2];
341  m_elements[3] -= m.m_elements[3];
342  }
343 
344  template <typename T>
346  {
347  m_elements[0] *= s;
348  m_elements[1] *= s;
349  m_elements[2] *= s;
350  m_elements[3] *= s;
351  }
352 
353  template <typename T>
355  {
356  Set(Mul(m));
357  }
358 
359  template <typename T>
361  {
362  m_elements[0] /= s;
363  m_elements[1] /= s;
364  m_elements[2] /= s;
365  m_elements[3] /= s;
366  }
367 
368  template <typename T>
370  {
371  std::swap(m_elements[1], m_elements[2]);
372  }
373 
374  template <typename T>
376  {
377  T d = Determinant();
378 
379  Matrix m;
380  m.m_elements[0] = m_elements[3];
381  m.m_elements[1] = -m_elements[1];
382  m.m_elements[2] = -m_elements[2];
383  m.m_elements[3] = m_elements[0];
384  m.IDiv(d);
385 
386  Set(m);
387  }
388 
389  template <typename T>
391  {
392  T sum = 0;
393 
394  for (size_t i = 0; i < 4; ++i)
395  {
396  sum += m_elements[i];
397  }
398 
399  return sum;
400  }
401 
402  template <typename T>
404  {
405  return Sum() / 4;
406  }
407 
408  template <typename T>
410  {
411  return m_elements[std::distance(std::begin(m_elements), std::min_element(std::begin(m_elements), std::end(m_elements)))];
412  }
413 
414  template <typename T>
416  {
417  return m_elements[std::distance(std::begin(m_elements), std::max_element(std::begin(m_elements), std::end(m_elements)))];
418  }
419 
420  template <typename T>
422  {
423  return CubbyFlow::AbsMinN(data(), 4);
424  }
425 
426  template <typename T>
428  {
429  return CubbyFlow::AbsMaxN(data(), 4);
430  }
431 
432  template <typename T>
434  {
435  return m_elements[0] + m_elements[3];
436  }
437 
438  template <typename T>
440  {
441  return
442  m_elements[0] * m_elements[3] -
443  m_elements[1] * m_elements[2];
444  }
445 
446  template <typename T>
448  {
449  return Matrix<T, 2, 2>(
450  m_elements[0], 0,
451  0, m_elements[3]);
452  }
453 
454  template <typename T>
456  {
457  return Matrix<T, 2, 2>(
458  0, m_elements[1],
459  m_elements[2], 0);
460  }
461 
462  template <typename T>
464  {
465  return Matrix<T, 2, 2>(
466  0, 0,
467  m_elements[2], 0);
468  }
469 
470  template <typename T>
472  {
473  return Matrix<T, 2, 2>(
474  0, m_elements[1],
475  0, 0);
476  }
477 
478  template <typename T>
480  {
481  return Matrix<T, 2, 2>(
482  m_elements[0], 0,
483  m_elements[2], m_elements[3]);
484  }
485 
486  template <typename T>
488  {
489  return Matrix<T, 2, 2>(
490  m_elements[0], m_elements[1],
491  0, m_elements[3]);
492  }
493 
494  template <typename T>
496  {
497  return Matrix<T, 2, 2>(
498  m_elements[0], m_elements[2],
499  m_elements[1], m_elements[3]);
500  }
501 
502  template <typename T>
504  {
505  Matrix m(*this);
506  m.Invert();
507  return m;
508  }
509 
510  template <typename T>
511  template <typename U>
513  {
514  return Matrix<U, 2, 2>(
515  static_cast<U>(m_elements[0]),
516  static_cast<U>(m_elements[1]),
517  static_cast<U>(m_elements[2]),
518  static_cast<U>(m_elements[3]));
519  }
520 
521  template <typename T>
523  {
524  Set(m);
525  return *this;
526  }
527 
528  template <typename T>
530  {
531  IAdd(m);
532  return *this;
533  }
534 
535  template <typename T>
537  {
538  IAdd(s);
539  return *this;
540  }
541 
542  template <typename T>
544  {
545  ISub(m);
546  return *this;
547  }
548 
549  template <typename T>
551  {
552  ISub(s);
553  return *this;
554  }
555 
556  template <typename T>
558  {
559  IMul(m);
560  return *this;
561  }
562 
563  template <typename T>
565  {
566  IMul(s);
567  return *this;
568  }
569 
570  template <typename T>
572  {
573  IDiv(s);
574  return *this;
575  }
576 
577  template <typename T>
579  {
580  return m_elements[i];
581  }
582 
583  template <typename T>
584  const T& Matrix<T, 2, 2>::operator[](size_t i) const
585  {
586  return m_elements[i];
587  }
588 
589  template <typename T>
590  T& Matrix<T, 2, 2>::operator()(size_t i, size_t j)
591  {
592  return m_elements[i * 2 + j];
593  }
594 
595  template <typename T>
596  const T& Matrix<T, 2, 2>::operator()(size_t i, size_t j) const
597  {
598  return m_elements[i * 2 + j];
599  }
600 
601  template <typename T>
602  bool Matrix<T, 2, 2>::operator==(const Matrix& m) const
603  {
604  return
605  m_elements[0] == m.m_elements[0] &&
606  m_elements[1] == m.m_elements[1] &&
607  m_elements[2] == m.m_elements[2] &&
608  m_elements[3] == m.m_elements[3];
609  }
610 
611  template <typename T>
612  bool Matrix<T, 2, 2>::operator!=(const Matrix& m) const
613  {
614  return
615  m_elements[0] != m.m_elements[0] ||
616  m_elements[1] != m.m_elements[1] ||
617  m_elements[2] != m.m_elements[2] ||
618  m_elements[3] != m.m_elements[3];
619  }
620 
621  template <typename T>
623  {
624  return Matrix<T, 2, 2>(0, 0, 0, 0);
625  }
626 
627  template <typename T>
629  {
630  return Matrix<T, 2, 2>(1, 0, 0, 1);
631  }
632 
633  template <typename T>
635  {
636  return Matrix<T, 2, 2>(sx, 0, 0, sy);
637  }
638 
639  template <typename T>
641  {
642  return MakeScaleMatrix(s.x, s.y);
643  }
644 
645  template <typename T>
647  {
648  return Matrix<T, 2, 2>(
649  std::cos(rad), -std::sin(rad),
650  std::sin(rad), std::cos(rad));
651  }
652 
653  template <typename T>
655  {
656  return a.Mul(-1);
657  }
658 
659  template <typename T>
661  {
662  return a.Add(b);
663  }
664 
665  template <typename T>
667  {
668  return a.Add(b);
669  }
670 
671  template <typename T>
673  {
674  return b.RAdd(a);
675  }
676 
677  template <typename T>
679  {
680  return a.Sub(b);
681  }
682 
683  template <typename T>
685  {
686  return a.Sub(b);
687  }
688 
689  template <typename T>
691  {
692  return b.RSub(a);
693  }
694 
695  template <typename T>
697  {
698  return a.Mul(b);
699  }
700 
701  template <typename T>
703  {
704  return b.RMul(a);
705  }
706 
707  template <typename T>
709  {
710  return a.Mul(b);
711  }
712 
713  template <typename T>
715  {
716  return a.Mul(b);
717  }
718 
719  template <typename T>
721  {
722  return a.Div(b);
723  }
724 
725  template <typename T>
727  {
728  return b.RDiv(a);
729  }
730 }
731 
732 #endif
Matrix RAdd(T s) const
Returns input scalar + this matrix.
Definition: Matrix2x2-Impl.h:255
bool IsSimilar(const MatrixExpression< T, E > &other, double tol=std::numeric_limits< double >::epsilon()) const
Definition: Matrix-Impl.h:169
T x
X (or the first) component of the vector.
Definition: Vector2.h:29
static MatrixConstant< T > MakeZero()
Makes a M x N matrix with zeros.
Definition: Matrix-Impl.h:823
MatrixDiagonal< T, Matrix > Diagonal() const
Returns diagonal part of this matrix.
Definition: Matrix-Impl.h:633
MatrixDiagonal< T, Matrix > OffDiagonal() const
Returns off-diagonal part of this matrix.
Definition: Matrix-Impl.h:639
T Sum() const
Returns sum of all elements.
Definition: Matrix-Impl.h:483
Matrix & operator*=(const T &s)
Multiplication assignment with input scalar.
Definition: Matrix-Impl.h:737
Matrix & operator/=(const T &s)
Division assignment with input scalar.
Definition: Matrix-Impl.h:752
T * data()
Returns data pointer of this matrix.
Definition: Matrix-Impl.h:217
void SetDiagonal(const T &s)
Sets diagonal elements with input scalar.
Definition: Matrix-Impl.h:92
Matrix< T, 2, 2 > operator+(const Matrix< T, 2, 2 > &a, const Matrix< T, 2, 2 > &b)
Returns a + b (element-size).
Definition: Matrix2x2-Impl.h:660
void IMul(const T &s)
Multiplies input scalar to this matrix.
Definition: Matrix-Impl.h:376
MatrixScalarRSub< T, Matrix > RSub(const T &s) const
Returns input scalar - this matrix.
Definition: Matrix-Impl.h:318
T AbsMaxN(const T *x, size_t n)
Returns absolute maximum among n-elements.
Definition: MathUtils-Impl.h:64
void IAdd(const T &s)
Adds input scalar to this matrix.
Definition: Matrix-Impl.h:350
void Set(const T &s)
Sets whole matrix with input scalar.
Definition: Matrix-Impl.h:52
MatrixScalarAdd< T, Matrix > Add(const T &s) const
Returns this matrix + input scalar.
Definition: Matrix-Impl.h:253
Matrix Sub(T s) const
Returns this matrix - input scalar.
Definition: Matrix2x2-Impl.h:205
void SetRow(size_t i, const VectorExpression< T, E > &row)
Sets i-th row with input vector.
Definition: Matrix-Impl.h:116
void IDiv(const T &s)
Divides this matrix with input scalar.
Definition: Matrix-Impl.h:390
bool operator!=(const MatrixExpression< T, E > &m) const
Returns true if is not equal to m.
Definition: Matrix-Impl.h:791
Matrix RDiv(T s) const
Returns input scalar / this matrix.
Definition: Matrix2x2-Impl.h:301
void ISub(const T &s)
Subtracts input scalar from this matrix.
Definition: Matrix-Impl.h:363
constexpr size_t Cols() const
Returns number of columns of this matrix.
Definition: Matrix-Impl.h:211
T Max() const
Returns maximum among all elements.
Definition: Matrix-Impl.h:515
Matrix & operator+=(const T &s)
Addition assignment with input scalar.
Definition: Matrix-Impl.h:707
MatrixScalarDiv< T, Matrix > Div(const T &s) const
Returns this matrix / input scalar.
Definition: Matrix-Impl.h:299
MatrixScalarSub< T, Matrix > Sub(const T &s) const
Returns this matrix - input scalar.
Definition: Matrix-Impl.h:266
Matrix Inverse() const
Returns inverse matrix.
Definition: Matrix-Impl.h:677
Matrix Add(T s) const
Returns this matrix + input scalar.
Definition: Matrix2x2-Impl.h:189
MatrixScalarMul< T, Matrix > RMul(const T &s) const
Returns input scalar * this matrix.
Definition: Matrix-Impl.h:331
MatrixScalarAdd< T, Matrix > RAdd(const T &s) const
Returns input scalar + this matrix.
Definition: Matrix-Impl.h:305
T AbsMinN(const T *x, size_t n)
Returns absolute minimum among n-elements.
Definition: MathUtils-Impl.h:51
Static-sized M x N matrix class.
Definition: Matrix.h:30
MatrixScalarMul< T, Matrix > Mul(const T &s) const
Returns this matrix * input scalar.
Definition: Matrix-Impl.h:279
void Invert()
Inverts this matrix.
Definition: Matrix-Impl.h:402
Matrix< T, 2, 2 > operator/(const Matrix< T, 2, 2 > &a, T b)
Definition: Matrix2x2-Impl.h:720
Definition: pybind11Utils.h:24
T & operator[](size_t i)
Returns reference of i-th element.
Definition: Matrix-Impl.h:759
bool operator==(const MatrixExpression< T, E > &m) const
Returns true if is equal to m.
Definition: Matrix-Impl.h:784
Matrix Mul(T s) const
Returns this matrix * input scalar.
Definition: Matrix2x2-Impl.h:221
Matrix RSub(T s) const
Returns input scalar - this matrix.
Definition: Matrix2x2-Impl.h:271
constexpr bool IsSquare() const
Returns true if this matrix is a square matrix.
Definition: Matrix-Impl.h:193
Matrix< T, 2, 2 > operator-(const Matrix< T, 2, 2 > &a)
Returns a matrix with opposite sign.
Definition: Matrix2x2-Impl.h:654
T y
Y (or the second) component of the vector.
Definition: Vector2.h:35
Matrix & operator-=(const T &s)
Subtraction assignment with input scalar.
Definition: Matrix-Impl.h:722
Matrix & operator=(const E &m)
Assigns input matrix.
const Matrix< T, M, N > & operator()() const
Returns actual implementation (the subclass).
Definition: MatrixExpression-Impl.h:34
T Trace() const
Definition: Matrix-Impl.h:554
T Avg() const
Returns average of all elements.
Definition: Matrix-Impl.h:496
Matrix RMul(T s) const
Returns input scalar * this matrix.
Definition: Matrix2x2-Impl.h:287
T Determinant() const
Returns determinant of this matrix.
Definition: Matrix-Impl.h:569
2-D vector class.
Definition: Vector2.h:26
void Transpose()
Transposes this matrix.
Definition: Matrix-Impl.h:396
static MatrixIdentity< T > MakeIdentity()
Makes a M x N matrix with all diagonal elements to 1, and other elements to 0.
Definition: Matrix-Impl.h:829
T Min() const
Returns minimum among all elements.
Definition: Matrix-Impl.h:502
T AbsMin() const
Returns absolute minimum among all elements.
Definition: Matrix-Impl.h:528
Vector< T, 3 > operator*(const Quaternion< T > &q, const Vector< T, 3 > &v)
Returns quaternion q * vector v.
Definition: Quaternion-Impl.h:481
void SetOffDiagonal(const T &s)
Sets off-diagonal elements with input scalar.
Definition: Matrix-Impl.h:103
MatrixTypeCast< U, Matrix, T > CastTo() const
MatrixScalarRDiv< T, Matrix > RDiv(const T &s) const
Returns input matrix / this scalar.
Definition: Matrix-Impl.h:344
constexpr size_t Rows() const
Returns number of rows of this matrix.
Definition: Matrix-Impl.h:205
Matrix< T, N, M > Transposed() const
Returns transposed matrix.
Definition: Matrix-Impl.h:669
T AbsMax() const
Returns absolute maximum among all elements.
Definition: Matrix-Impl.h:541
Matrix Div(T s) const
Returns this matrix / input scalar.
Definition: Matrix2x2-Impl.h:247
Matrix()
Definition: Matrix-Impl.h:15
2-D matrix class.
Definition: Matrix2x2.h:28
void SetColumn(size_t j, const VectorExpression< T, E > &col)
Sets j-th column with input vector.
Definition: Matrix-Impl.h:130