MatrixExpression-Impl.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_MATRIX_EXPRESSION_IMPL_HPP
12 #define CUBBYFLOW_MATRIX_EXPRESSION_IMPL_HPP
13 
14 #include <Core/Math/MathUtils.hpp>
15 
16 #include <cassert>
17 
18 namespace CubbyFlow
19 {
20 template <typename T, size_t Rows, size_t Cols, typename D>
22 {
23  return static_cast<const D&>(*this).GetRows();
24 }
25 
26 template <typename T, size_t Rows, size_t Cols, typename D>
28 {
29  return static_cast<const D&>(*this).GetCols();
30 }
31 
32 template <typename T, size_t Rows, size_t Cols, typename D>
33 T MatrixExpression<T, Rows, Cols, D>::Eval(size_t i, size_t j) const
34 {
35  return GetDerived()(i, j);
36 }
37 
38 template <typename T, size_t Rows, size_t Cols, typename D>
40 {
41  return Matrix<T, Rows, Cols>(*this);
42 }
43 
44 template <typename T, size_t Rows, size_t Cols, typename D>
45 template <size_t R, size_t C, typename E>
47  const MatrixExpression<T, R, C, E>& expression, double tol) const
48 {
49  if (expression.GetRows() != GetRows() || expression.GetCols() != GetCols())
50  {
51  return false;
52  }
53 
54  SimilarTo<T> op{ tol };
55 
56  for (size_t i = 0; i < GetRows(); ++i)
57  {
58  for (size_t j = 0; j < GetCols(); ++j)
59  {
60  if (!op(Eval(i, j), expression.Eval(i, j)))
61  {
62  return false;
63  }
64  }
65  }
66 
67  return true;
68 }
69 
70 template <typename T, size_t Rows, size_t Cols, typename D>
72 {
73  return GetRows() == GetCols();
74 }
75 
76 template <typename T, size_t Rows, size_t Cols, typename D>
78 {
79  T s = 0;
80 
81  for (size_t i = 0; i < GetRows(); ++i)
82  {
83  for (size_t j = 0; j < GetCols(); ++j)
84  {
85  s += Eval(i, j);
86  }
87  }
88 
89  return s;
90 }
91 
92 template <typename T, size_t Rows, size_t Cols, typename D>
94 {
95  return Sum() / (GetRows() * GetCols());
96 }
97 
98 template <typename T, size_t Rows, size_t Cols, typename D>
100 {
101  T s = Eval(0, 0);
102 
103  for (size_t j = 1; j < GetCols(); ++j)
104  {
105  s = std::min(s, Eval(0, j));
106  }
107 
108  for (size_t i = 1; i < GetRows(); ++i)
109  {
110  for (size_t j = 0; j < GetCols(); ++j)
111  {
112  s = std::min(s, Eval(i, j));
113  }
114  }
115 
116  return s;
117 }
118 
119 template <typename T, size_t Rows, size_t Cols, typename D>
121 {
122  T s = Eval(0, 0);
123 
124  for (size_t j = 1; j < GetCols(); ++j)
125  {
126  s = std::max(s, Eval(0, j));
127  }
128 
129  for (size_t i = 1; i < GetRows(); ++i)
130  {
131  for (size_t j = 0; j < GetCols(); ++j)
132  {
133  s = std::max(s, Eval(i, j));
134  }
135  }
136 
137  return s;
138 }
139 
140 template <typename T, size_t Rows, size_t Cols, typename D>
142 {
143  T s = Eval(0, 0);
144 
145  for (size_t j = 1; j < GetCols(); ++j)
146  {
147  s = CubbyFlow::AbsMin(s, Eval(0, j));
148  }
149 
150  for (size_t i = 1; i < GetRows(); ++i)
151  {
152  for (size_t j = 0; j < GetCols(); ++j)
153  {
154  s = CubbyFlow::AbsMin(s, Eval(i, j));
155  }
156  }
157 
158  return s;
159 }
160 
161 template <typename T, size_t Rows, size_t Cols, typename D>
163 {
164  T s = Eval(0, 0);
165 
166  for (size_t j = 1; j < GetCols(); ++j)
167  {
168  s = CubbyFlow::AbsMax(s, Eval(0, j));
169  }
170 
171  for (size_t i = 1; i < GetRows(); ++i)
172  {
173  for (size_t j = 0; j < GetCols(); ++j)
174  {
175  s = CubbyFlow::AbsMax(s, Eval(i, j));
176  }
177  }
178 
179  return s;
180 }
181 
182 template <typename T, size_t Rows, size_t Cols, typename D>
184 {
185  assert(GetRows() == GetCols());
186 
187  T result = Eval(0, 0);
188 
189  for (size_t i = 1; i < GetRows(); ++i)
190  {
191  result += Eval(i, i);
192  }
193 
194  return result;
195 }
196 
197 template <typename T, size_t Rows, size_t Cols, typename D>
199 {
200  assert(GetRows() == GetCols());
201 
202  return Determinant(*this);
203 }
204 
205 template <typename T, size_t Rows, size_t Cols, typename D>
207 {
208  assert(GetCols() == 1);
209 
210  size_t ret = 0;
211  T best = Eval(0, 0);
212 
213  for (size_t i = 1; i < GetRows(); ++i)
214  {
215  T curr = Eval(i, 0);
216 
217  if (std::fabs(curr) > std::fabs(best))
218  {
219  best = curr;
220  ret = i;
221  }
222  }
223 
224  return ret;
225 }
226 
227 template <typename T, size_t Rows, size_t Cols, typename D>
229 {
230  assert(GetCols() == 1);
231 
232  size_t ret = 0;
233  T best = Eval(0, 0);
234 
235  for (size_t i = 1; i < GetRows(); ++i)
236  {
237  T curr = Eval(i, 0);
238 
239  if (std::fabs(curr) < std::fabs(best))
240  {
241  best = curr;
242  ret = i;
243  }
244  }
245 
246  return ret;
247 }
248 
249 template <typename T, size_t Rows, size_t Cols, typename D>
251 {
252  return std::sqrt(NormSquared());
253 }
254 
255 template <typename T, size_t Rows, size_t Cols, typename D>
257 {
258  T result = 0;
259 
260  for (size_t i = 0; i < GetRows(); ++i)
261  {
262  for (size_t j = 0; j < GetCols(); ++j)
263  {
264  result += Eval(i, j) * Eval(i, j);
265  }
266  }
267 
268  return result;
269 }
270 
271 template <typename T, size_t Rows, size_t Cols, typename D>
273 {
274  return Norm();
275 }
276 
277 template <typename T, size_t Rows, size_t Cols, typename D>
279 {
280  assert(GetCols() == 1);
281 
282  return Norm();
283 }
284 
285 template <typename T, size_t Rows, size_t Cols, typename D>
287 {
288  assert(GetCols() == 1);
289 
290  return NormSquared();
291 }
292 
293 template <typename T, size_t Rows, size_t Cols, typename D>
294 template <size_t R, size_t C, typename E>
296  const MatrixExpression<T, R, C, E>& other) const
297 {
298  assert(GetCols() == 1);
299 
300  return std::sqrt(DistanceSquaredTo(other));
301 };
302 
303 template <typename T, size_t Rows, size_t Cols, typename D>
304 template <size_t R, size_t C, typename E>
306  const MatrixExpression<T, R, C, E>& other) const
307 {
308  assert(GetCols() == 1);
309 
310  return D(GetDerived() - other.GetDerived()).NormSquared();
311 }
312 
313 template <typename T, size_t Rows, size_t Cols, typename D>
316 {
318  Norm() };
319 }
320 
321 template <typename T, size_t Rows, size_t Cols, typename D>
324 {
325  return MatrixDiagonal<T, Rows, Cols, const D&>{ GetDerived() };
326 }
327 
328 template <typename T, size_t Rows, size_t Cols, typename D>
331 {
332  return MatrixOffDiagonal<T, Rows, Cols, const D&>{ GetDerived() };
333 }
334 
335 template <typename T, size_t Rows, size_t Cols, typename D>
338 {
339  return MatrixTri<T, Rows, Cols, const D&>{ GetDerived(), false, true };
340 }
341 
342 template <typename T, size_t Rows, size_t Cols, typename D>
345 {
346  return MatrixTri<T, Rows, Cols, const D&>{ GetDerived(), true, true };
347 }
348 
349 template <typename T, size_t Rows, size_t Cols, typename D>
352 {
353  return MatrixTri<T, Rows, Cols, const D&>{ GetDerived(), false, false };
354 }
355 
356 template <typename T, size_t Rows, size_t Cols, typename D>
359 {
360  return MatrixTri<T, Rows, Cols, const D&>{ GetDerived(), true, false };
361 }
362 
363 template <typename T, size_t Rows, size_t Cols, typename D>
366 {
367  return MatrixTranspose<T, Rows, Cols, const D&>{ GetDerived() };
368 }
369 
370 template <typename T, size_t Rows, size_t Cols, typename D>
372 {
373  Matrix<T, Rows, Cols> result;
374  Inverse(*this, result);
375  return result;
376 }
377 
378 template <typename T, size_t Rows, size_t Cols, typename D>
379 template <typename U>
382 {
383  return MatrixTypeCast<T, Rows, Cols, U, const D&>{ GetDerived() };
384 }
385 
386 template <typename T, size_t Rows, size_t Cols, typename D>
387 template <size_t R, size_t C, typename E, typename U>
388 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() || Cols == 1) &&
389  (IsMatrixSizeDynamic<R, C>() || C == 1),
390  U>
392  const MatrixExpression<T, R, C, E>& expression) const
393 {
394  assert(expression.GetRows() == GetRows() && expression.GetCols() == 1);
395 
396  T sum = Eval(0, 0) * expression.Eval(0, 0);
397 
398  for (size_t i = 1; i < GetRows(); ++i)
399  {
400  sum += Eval(i, 0) * expression.Eval(i, 0);
401  }
402 
403  return sum;
404 }
405 
406 template <typename T, size_t Rows, size_t Cols, typename D>
407 template <size_t R, size_t C, typename E, typename U>
408 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
409  (Rows == 2 && Cols == 1)) &&
410  (IsMatrixSizeDynamic<R, C>() || (R == 2 && C == 1)),
411  U>
413  const MatrixExpression<T, R, C, E>& expression) const
414 {
415  assert(GetRows() == 2 && GetCols() == 1 && expression.GetRows() == 2 &&
416  expression.GetCols() == 1);
417 
418  return Eval(0, 0) * expression.Eval(1, 0) -
419  expression.Eval(0, 0) * Eval(1, 0);
420 }
421 
422 template <typename T, size_t Rows, size_t Cols, typename D>
423 template <size_t R, size_t C, typename E, typename U>
424 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
425  (Rows == 3 && Cols == 1)) &&
426  (IsMatrixSizeDynamic<R, C>() || (R == 3 && C == 1)),
429  const MatrixExpression<T, R, C, E>& exp) const
430 {
431  assert(GetRows() == 3 && GetCols() == 1 && exp.GetRows() == 3 &&
432  exp.GetCols() == 1);
433 
434  return Matrix<U, 3, 1>{
435  Eval(1, 0) * exp.Eval(2, 0) - exp.Eval(1, 0) * Eval(2, 0),
436  Eval(2, 0) * exp.Eval(0, 0) - exp.Eval(2, 0) * Eval(0, 0),
437  Eval(0, 0) * exp.Eval(1, 0) - exp.Eval(0, 0) * Eval(1, 0)
438  };
439 }
440 
441 template <typename T, size_t Rows, size_t Cols, typename D>
442 template <size_t R, size_t C, typename E, typename U>
443 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
444  ((Rows == 2 || Rows == 3) && Cols == 1)) &&
445  (IsMatrixSizeDynamic<R, C>() ||
446  ((R == 2 || R == 3) && C == 1)),
449  const MatrixExpression<T, R, C, E>& normal) const
450 {
451  assert((GetRows() == 2 || GetRows() == 3) && GetCols() == 1 &&
452  normal.GetRows() == GetRows() && normal.GetCols() == 1);
453 
454  // this - 2(this.n)n
455  return (*this) - 2 * Dot(normal) * normal;
456 }
457 
458 template <typename T, size_t Rows, size_t Cols, typename D>
459 template <size_t R, size_t C, typename E, typename U>
460 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
461  ((Rows == 2 || Rows == 3) && Cols == 1)) &&
462  (IsMatrixSizeDynamic<R, C>() ||
463  ((R == 2 || R == 3) && C == 1)),
466  const MatrixExpression<T, R, C, E>& normal) const
467 {
468  assert((GetRows() == 2 || GetRows() == 3) && GetCols() == 1 &&
469  normal.GetRows() == GetRows() && normal.GetCols() == 1);
470 
471  // this - this.n n
472  return (*this) - this->Dot(normal) * normal;
473 }
474 
475 template <typename T, size_t Rows, size_t Cols, typename D>
476 template <typename U>
477 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
478  (Rows == 2 && Cols == 1)),
481 {
482  assert(GetRows() == 2 && GetCols() == 1);
483 
484  return Matrix<U, 2, 1>{ -Eval(1, 0), Eval(0, 0) };
485 }
486 
487 template <typename T, size_t Rows, size_t Cols, typename D>
488 template <typename U>
489 std::enable_if_t<(IsMatrixSizeDynamic<Rows, Cols>() ||
490  (Rows == 3 && Cols == 1)),
491  std::tuple<Matrix<U, 3, 1>, Matrix<U, 3, 1>>>
493 {
494  assert(GetRows() == 3 && GetCols() == 1);
495 
496  using V = Matrix<T, 3, 1>;
497 
498  V a =
499  ((std::fabs(Eval(1, 0)) > 0 || std::fabs(Eval(2, 0)) > 0) ? V(1, 0, 0)
500  : V(0, 1, 0))
501  .Cross(*this)
502  .Normalized();
503  V b = this->Cross(a);
504 
505  return std::make_tuple(a, b);
506 }
507 
508 template <typename T, size_t Rows, size_t Cols, typename D>
510 {
511  return static_cast<D&>(*this);
512 }
513 
514 template <typename T, size_t Rows, size_t Cols, typename D>
516 {
517  return static_cast<const D&>(*this);
518 }
519 
520 template <typename T, size_t Rows, size_t Cols, typename D>
523 {
524  return m.Eval(0, 0);
525 }
526 
527 template <typename T, size_t Rows, size_t Cols, typename D>
530 {
531  return m.Eval(0, 0) * m.Eval(1, 1) - m.Eval(1, 0) * m.Eval(0, 1);
532 }
533 
534 template <typename T, size_t Rows, size_t Cols, typename D>
537 {
538  return m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(2, 2) -
539  m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(2, 1) +
540  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(2, 0) -
541  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(2, 2) +
542  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(2, 1) -
543  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(2, 0);
544 }
545 
546 template <typename T, size_t Rows, size_t Cols, typename D>
549 {
550  return m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(2, 2) * m.Eval(3, 3) +
551  m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(2, 3) * m.Eval(3, 1) +
552  m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(2, 1) * m.Eval(3, 2) +
553  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(2, 3) * m.Eval(3, 2) +
554  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(2, 0) * m.Eval(3, 3) +
555  m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(2, 2) * m.Eval(3, 0) +
556  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(2, 1) * m.Eval(3, 3) +
557  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(2, 3) * m.Eval(3, 0) +
558  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(2, 0) * m.Eval(3, 1) +
559  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(2, 2) * m.Eval(3, 1) +
560  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(2, 0) * m.Eval(3, 2) +
561  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(2, 1) * m.Eval(3, 0) -
562  m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(2, 3) * m.Eval(3, 2) -
563  m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(2, 1) * m.Eval(3, 3) -
564  m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(2, 2) * m.Eval(3, 1) -
565  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(2, 2) * m.Eval(3, 3) -
566  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(2, 3) * m.Eval(3, 0) -
567  m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(2, 0) * m.Eval(3, 2) -
568  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(2, 3) * m.Eval(3, 1) -
569  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(2, 0) * m.Eval(3, 3) -
570  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(2, 1) * m.Eval(3, 0) -
571  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(2, 1) * m.Eval(3, 2) -
572  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(2, 2) * m.Eval(3, 0) -
573  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(2, 0) * m.Eval(3, 1);
574 }
575 
576 template <typename T, size_t Rows, size_t Cols, typename D>
577 template <typename U>
578 std::enable_if_t<(Rows > 4 && Cols > 4) || IsMatrixSizeDynamic<Rows, Cols>(), U>
580 {
581  // Computes inverse matrix using Gaussian elimination method.
582  // https://martin-thoma.com/solving-linear-equations-with-gaussian-elimination/
584 
585  T result = 1;
586 
587  for (size_t i = 0; i < m.GetRows(); ++i)
588  {
589  // Search for maximum in this column
590  T maxEl = std::fabs(a(i, i));
591  size_t maxRow = i;
592 
593  for (size_t k = i + 1; k < m.GetRows(); ++k)
594  {
595  if (std::fabs(a(k, i)) > maxEl)
596  {
597  maxEl = std::fabs(a(k, i));
598  maxRow = k;
599  }
600  }
601 
602  // Swap maximum row with current row (column by column)
603  if (maxRow != i)
604  {
605  for (size_t k = i; k < m.GetRows(); ++k)
606  {
607  std::swap(a(maxRow, k), a(i, k));
608  }
609  result *= -1;
610  }
611 
612  // Make all rows below this one 0 in current column
613  for (size_t k = i + 1; k < m.GetRows(); ++k)
614  {
615  T c = -a(k, i) / a(i, i);
616 
617  for (size_t j = i; j < m.GetRows(); ++j)
618  {
619  if (i == j)
620  {
621  a(k, j) = 0;
622  }
623  else
624  {
625  a(k, j) += c * a(i, j);
626  }
627  }
628  }
629  }
630 
631  for (size_t i = 0; i < m.GetRows(); ++i)
632  {
633  result *= a(i, i);
634  }
635 
636  return result;
637 }
638 
639 template <typename T, size_t Rows, size_t Cols, typename D>
642 {
643  result(0, 0) = 1 / m(0, 0);
644 }
645 
646 template <typename T, size_t Rows, size_t Cols, typename D>
649 {
650  T d = Determinant(m);
651 
652  result(0, 0) = m.Eval(1, 1) / d;
653  result(0, 1) = -m.Eval(0, 1) / d;
654  result(1, 0) = -m.Eval(1, 0) / d;
655  result(1, 1) = m.Eval(0, 0) / d;
656 }
657 
658 template <typename T, size_t Rows, size_t Cols, typename D>
661 {
662  T d = Determinant(m);
663 
664  result(0, 0) =
665  (m.Eval(1, 1) * m.Eval(2, 2) - m.Eval(1, 2) * m.Eval(2, 1)) / d;
666  result(0, 1) =
667  (m.Eval(0, 2) * m.Eval(2, 1) - m.Eval(0, 1) * m.Eval(2, 2)) / d;
668  result(0, 2) =
669  (m.Eval(0, 1) * m.Eval(1, 2) - m.Eval(0, 2) * m.Eval(1, 1)) / d;
670  result(1, 0) =
671  (m.Eval(1, 2) * m.Eval(2, 0) - m.Eval(1, 0) * m.Eval(2, 2)) / d;
672  result(1, 1) =
673  (m.Eval(0, 0) * m.Eval(2, 2) - m.Eval(0, 2) * m.Eval(2, 0)) / d;
674  result(1, 2) =
675  (m.Eval(0, 2) * m.Eval(1, 0) - m.Eval(0, 0) * m.Eval(1, 2)) / d;
676  result(2, 0) =
677  (m.Eval(1, 0) * m.Eval(2, 1) - m.Eval(1, 1) * m.Eval(2, 0)) / d;
678  result(2, 1) =
679  (m.Eval(0, 1) * m.Eval(2, 0) - m.Eval(0, 0) * m.Eval(2, 1)) / d;
680  result(2, 2) =
681  (m.Eval(0, 0) * m.Eval(1, 1) - m.Eval(0, 1) * m.Eval(1, 0)) / d;
682 }
683 
684 template <typename T, size_t Rows, size_t Cols, typename D>
687 {
688  T d = Determinant(m);
689 
690  result(0, 0) = (m.Eval(1, 1) * m.Eval(2, 2) * m.Eval(3, 3) +
691  m.Eval(1, 2) * m.Eval(2, 3) * m.Eval(3, 1) +
692  m.Eval(1, 3) * m.Eval(2, 1) * m.Eval(3, 2) -
693  m.Eval(1, 1) * m.Eval(2, 3) * m.Eval(3, 2) -
694  m.Eval(1, 2) * m.Eval(2, 1) * m.Eval(3, 3) -
695  m.Eval(1, 3) * m.Eval(2, 2) * m.Eval(3, 1)) /
696  d;
697  result(0, 1) = (m.Eval(0, 1) * m.Eval(2, 3) * m.Eval(3, 2) +
698  m.Eval(0, 2) * m.Eval(2, 1) * m.Eval(3, 3) +
699  m.Eval(0, 3) * m.Eval(2, 2) * m.Eval(3, 1) -
700  m.Eval(0, 1) * m.Eval(2, 2) * m.Eval(3, 3) -
701  m.Eval(0, 2) * m.Eval(2, 3) * m.Eval(3, 1) -
702  m.Eval(0, 3) * m.Eval(2, 1) * m.Eval(3, 2)) /
703  d;
704  result(0, 2) = (m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(3, 3) +
705  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(3, 1) +
706  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(3, 2) -
707  m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(3, 2) -
708  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(3, 3) -
709  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(3, 1)) /
710  d;
711  result(0, 3) = (m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(2, 2) +
712  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(2, 3) +
713  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(2, 1) -
714  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(2, 3) -
715  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(2, 1) -
716  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(2, 2)) /
717  d;
718  result(1, 0) = (m.Eval(1, 0) * m.Eval(2, 3) * m.Eval(3, 2) +
719  m.Eval(1, 2) * m.Eval(2, 0) * m.Eval(3, 3) +
720  m.Eval(1, 3) * m.Eval(2, 2) * m.Eval(3, 0) -
721  m.Eval(1, 0) * m.Eval(2, 2) * m.Eval(3, 3) -
722  m.Eval(1, 2) * m.Eval(2, 3) * m.Eval(3, 0) -
723  m.Eval(1, 3) * m.Eval(2, 0) * m.Eval(3, 2)) /
724  d;
725  result(1, 1) = (m.Eval(0, 0) * m.Eval(2, 2) * m.Eval(3, 3) +
726  m.Eval(0, 2) * m.Eval(2, 3) * m.Eval(3, 0) +
727  m.Eval(0, 3) * m.Eval(2, 0) * m.Eval(3, 2) -
728  m.Eval(0, 0) * m.Eval(2, 3) * m.Eval(3, 2) -
729  m.Eval(0, 2) * m.Eval(2, 0) * m.Eval(3, 3) -
730  m.Eval(0, 3) * m.Eval(2, 2) * m.Eval(3, 0)) /
731  d;
732  result(1, 2) = (m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(3, 2) +
733  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(3, 3) +
734  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(3, 0) -
735  m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(3, 3) -
736  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(3, 0) -
737  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(3, 2)) /
738  d;
739  result(1, 3) = (m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(2, 3) +
740  m.Eval(0, 2) * m.Eval(1, 3) * m.Eval(2, 0) +
741  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(2, 2) -
742  m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(2, 2) -
743  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(2, 3) -
744  m.Eval(0, 3) * m.Eval(1, 2) * m.Eval(2, 0)) /
745  d;
746  result(2, 0) = (m.Eval(1, 0) * m.Eval(2, 1) * m.Eval(3, 3) +
747  m.Eval(1, 1) * m.Eval(2, 3) * m.Eval(3, 0) +
748  m.Eval(1, 3) * m.Eval(2, 0) * m.Eval(3, 1) -
749  m.Eval(1, 0) * m.Eval(2, 3) * m.Eval(3, 1) -
750  m.Eval(1, 1) * m.Eval(2, 0) * m.Eval(3, 3) -
751  m.Eval(1, 3) * m.Eval(2, 1) * m.Eval(3, 0)) /
752  d;
753  result(2, 1) = (m.Eval(0, 0) * m.Eval(2, 3) * m.Eval(3, 1) +
754  m.Eval(0, 1) * m.Eval(2, 0) * m.Eval(3, 3) +
755  m.Eval(0, 3) * m.Eval(2, 1) * m.Eval(3, 0) -
756  m.Eval(0, 0) * m.Eval(2, 1) * m.Eval(3, 3) -
757  m.Eval(0, 1) * m.Eval(2, 3) * m.Eval(3, 0) -
758  m.Eval(0, 3) * m.Eval(2, 0) * m.Eval(3, 1)) /
759  d;
760  result(2, 2) = (m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(3, 3) +
761  m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(3, 0) +
762  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(3, 1) -
763  m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(3, 1) -
764  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(3, 3) -
765  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(3, 0)) /
766  d;
767  result(2, 3) = (m.Eval(0, 0) * m.Eval(1, 3) * m.Eval(2, 1) +
768  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(2, 3) +
769  m.Eval(0, 3) * m.Eval(1, 1) * m.Eval(2, 0) -
770  m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(2, 3) -
771  m.Eval(0, 1) * m.Eval(1, 3) * m.Eval(2, 0) -
772  m.Eval(0, 3) * m.Eval(1, 0) * m.Eval(2, 1)) /
773  d;
774  result(3, 0) = (m.Eval(1, 0) * m.Eval(2, 2) * m.Eval(3, 1) +
775  m.Eval(1, 1) * m.Eval(2, 0) * m.Eval(3, 2) +
776  m.Eval(1, 2) * m.Eval(2, 1) * m.Eval(3, 0) -
777  m.Eval(1, 0) * m.Eval(2, 1) * m.Eval(3, 2) -
778  m.Eval(1, 1) * m.Eval(2, 2) * m.Eval(3, 0) -
779  m.Eval(1, 2) * m.Eval(2, 0) * m.Eval(3, 1)) /
780  d;
781  result(3, 1) = (m.Eval(0, 0) * m.Eval(2, 1) * m.Eval(3, 2) +
782  m.Eval(0, 1) * m.Eval(2, 2) * m.Eval(3, 0) +
783  m.Eval(0, 2) * m.Eval(2, 0) * m.Eval(3, 1) -
784  m.Eval(0, 0) * m.Eval(2, 2) * m.Eval(3, 1) -
785  m.Eval(0, 1) * m.Eval(2, 0) * m.Eval(3, 2) -
786  m.Eval(0, 2) * m.Eval(2, 1) * m.Eval(3, 0)) /
787  d;
788  result(3, 2) = (m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(3, 1) +
789  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(3, 2) +
790  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(3, 0) -
791  m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(3, 2) -
792  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(3, 0) -
793  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(3, 1)) /
794  d;
795  result(3, 3) = (m.Eval(0, 0) * m.Eval(1, 1) * m.Eval(2, 2) +
796  m.Eval(0, 1) * m.Eval(1, 2) * m.Eval(2, 0) +
797  m.Eval(0, 2) * m.Eval(1, 0) * m.Eval(2, 1) -
798  m.Eval(0, 0) * m.Eval(1, 2) * m.Eval(2, 1) -
799  m.Eval(0, 1) * m.Eval(1, 0) * m.Eval(2, 2) -
800  m.Eval(0, 2) * m.Eval(1, 1) * m.Eval(2, 0)) /
801  d;
802 }
803 
804 template <typename T, size_t Rows, size_t Cols, typename Derived>
805 template <typename M>
808  std::enable_if_t<
809  (Rows > 4 && Cols > 4) || IsMatrixSizeDynamic<Rows, Cols>(), M>& result)
810 {
811  // Computes inverse matrix using Gaussian elimination method.
812  // https://martin-thoma.com/solving-linear-equations-with-gaussian-elimination/
814 
815  using ConstType = MatrixConstant<T, Rows, Cols>;
816 
817  result = MatrixDiagonal<T, Rows, Cols, ConstType>{ ConstType{
818  a.GetRows(), a.GetCols(), 1 } };
819  const size_t n = m.GetRows();
820 
821  for (size_t i = 0; i < n; ++i)
822  {
823  // Search for maximum in this column
824  T maxEl = std::fabs(a(i, i));
825  size_t maxRow = i;
826 
827  for (size_t k = i + 1; k < n; ++k)
828  {
829  if (std::fabs(a(k, i)) > maxEl)
830  {
831  maxEl = std::fabs(a(k, i));
832  maxRow = k;
833  }
834  }
835 
836  // Swap maximum row with current row (column by column)
837  if (maxRow != i)
838  {
839  for (size_t k = i; k < n; ++k)
840  {
841  std::swap(a(maxRow, k), a(i, k));
842  }
843 
844  for (size_t k = 0; k < n; ++k)
845  {
846  std::swap(result(maxRow, k), result(i, k));
847  }
848  }
849 
850  // Make all rows except this one 0 in current column
851  for (size_t k = 0; k < n; ++k)
852  {
853  if (k == i)
854  {
855  continue;
856  }
857 
858  T c = -a(k, i) / a(i, i);
859 
860  for (size_t j = 0; j < n; ++j)
861  {
862  result(k, j) += c * result(i, j);
863 
864  if (i == j)
865  {
866  a(k, j) = 0;
867  }
868  else if (i < j)
869  {
870  a(k, j) += c * a(i, j);
871  }
872  }
873  }
874 
875  // Scale
876  for (size_t k = 0; k < n; ++k)
877  {
878  T c = 1 / a(k, k);
879 
880  for (size_t j = 0; j < n; ++j)
881  {
882  a(k, j) *= c;
883  result(k, j) *= c;
884  }
885  }
886  }
887 }
888 
889 template <typename T, size_t Rows, size_t Cols>
891 {
892  return m_rows;
893 }
894 
895 template <typename T, size_t Rows, size_t Cols>
897 {
898  return m_cols;
899 }
900 
901 template <typename T, size_t Rows, size_t Cols>
902 constexpr T MatrixConstant<T, Rows, Cols>::operator()(size_t, size_t) const
903 {
904  return m_val;
905 }
906 
907 template <typename T, size_t Rows, size_t Cols, typename M1>
909 {
910  return m_mat1.GetRows();
911 }
912 
913 template <typename T, size_t Rows, size_t Cols, typename M1>
915 {
916  return m_mat1.GetCols();
917 }
918 
919 template <typename T, size_t Rows, size_t Cols, typename M1>
921 {
922  if (i == j)
923  {
924  return m_mat1(i, j);
925  }
926 
927  return T{};
928 }
929 
930 template <typename T, size_t Rows, size_t Cols, typename M1>
932 {
933  return m_mat1.GetRows();
934 }
935 
936 template <typename T, size_t Rows, size_t Cols, typename M1>
938 {
939  return m_mat1.GetCols();
940 }
941 
942 template <typename T, size_t Rows, size_t Cols, typename M1>
944 {
945  if (i != j)
946  {
947  return m_mat1(i, j);
948  }
949 
950  return T{};
951 }
952 
953 template <typename T, size_t Rows, size_t Cols, typename M1>
955 {
956  return m_mat1.GetRows();
957 }
958 
959 template <typename T, size_t Rows, size_t Cols, typename M1>
961 {
962  return m_mat1.GetCols();
963 }
964 
965 template <typename T, size_t Rows, size_t Cols, typename M1>
966 T MatrixTri<T, Rows, Cols, M1>::operator()(size_t i, size_t j) const
967 {
968  if (m_isUpper)
969  {
970  if (m_isStrict)
971  {
972  return (j > i) ? m_mat1(i, j) : 0;
973  }
974 
975  return (j >= i) ? m_mat1(i, j) : 0;
976  }
977 
978  if (m_isStrict)
979  {
980  return (j < i) ? m_mat1(i, j) : 0;
981  }
982 
983  return (j <= i) ? m_mat1(i, j) : 0;
984 }
985 
986 template <typename T, size_t Rows, size_t Cols, typename M1>
988 {
989  return m_mat1.GetCols();
990 }
991 
992 template <typename T, size_t Rows, size_t Cols, typename M1>
994 {
995  return m_mat1.GetRows();
996 }
997 
998 template <typename T, size_t Rows, size_t Cols, typename M1>
1000  size_t j) const
1001 {
1002  return m_mat1(j, i);
1003 }
1004 
1005 template <typename T, size_t Rows, size_t Cols, typename M1, typename UOp>
1007 {
1008  return m_mat1.GetRows();
1009 }
1010 
1011 template <typename T, size_t Rows, size_t Cols, typename M1, typename UOp>
1013 {
1014  return m_mat1.GetCols();
1015 }
1016 
1017 template <typename T, size_t Rows, size_t Cols, typename M1, typename UOp>
1019  size_t j) const
1020 {
1021  return m_op(m_mat1(i, j));
1022 }
1023 
1024 template <typename T, size_t Rows, size_t Cols, typename M1>
1026 {
1028 }
1029 
1030 template <typename T, size_t Rows, size_t Cols, typename M1>
1032 {
1034 }
1035 
1036 template <typename T, size_t Rows, size_t Cols, typename M1>
1038 {
1040 }
1041 
1042 template <typename T, size_t Rows, size_t Cols, typename E1, typename E2,
1043  typename BOp>
1045  const
1046 {
1047  return m_mat1.GetRows();
1048 }
1049 
1050 template <typename T, size_t Rows, size_t Cols, typename E1, typename E2,
1051  typename BOp>
1053  const
1054 {
1055  return m_mat1.GetCols();
1056 }
1057 
1058 template <typename T, size_t Rows, size_t Cols, typename E1, typename E2,
1059  typename BOp>
1061  size_t i, size_t j) const
1062 {
1063  return m_op(m_mat1(i, j), m_mat2(i, j));
1064 }
1065 
1066 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1069 {
1071  a.GetDerived(), b.GetDerived()
1072  };
1073 }
1074 
1075 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1078 {
1080  a.GetDerived(), b.GetDerived()
1081  };
1082 }
1083 
1084 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1087 {
1089  a.GetDerived(), b.GetDerived()
1090  };
1091 }
1092 
1093 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1096 {
1098  a.GetDerived(), b.GetDerived()
1099  };
1100 }
1101 
1102 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1105 {
1107  a.GetDerived(), b.GetDerived()
1108  };
1109 }
1110 
1111 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1114 {
1116  a.GetDerived(), b.GetDerived()
1117  };
1118 }
1119 
1120 template <typename T, size_t Rows, size_t Cols, typename M1, typename BOp>
1122  const
1123 {
1124  return m_mat1.GetRows();
1125 }
1126 
1127 template <typename T, size_t Rows, size_t Cols, typename M1, typename BOp>
1129  const
1130 {
1131  return m_mat1.GetCols();
1132 }
1133 
1134 template <typename T, size_t Rows, size_t Cols, typename M1, typename BOp>
1136  size_t i, size_t j) const
1137 {
1138  return m_op(m_mat1(i, j), m_scalar2);
1139 }
1140 
1141 template <typename T, size_t Rows, size_t Cols, typename M1>
1143  const T& b)
1144 {
1146  b };
1147 }
1148 
1149 template <typename T, size_t Rows, size_t Cols, typename M1>
1151  const T& b)
1152 {
1154  b };
1155 }
1156 
1157 template <typename T, size_t Rows, size_t Cols, typename M1>
1159  const T& b)
1160 {
1162  b };
1163 }
1164 
1165 template <typename T, size_t Rows, size_t Cols, typename M1>
1167  const T& b)
1168 {
1170  b };
1171 }
1172 
1173 template <typename T, size_t Rows, size_t Cols, typename M2, typename BOp>
1175  const
1176 {
1177  return m_mat2.GetRows();
1178 }
1179 
1180 template <typename T, size_t Rows, size_t Cols, typename M2, typename BOp>
1182  const
1183 {
1184  return m_mat2.GetCols();
1185 }
1186 
1187 template <typename T, size_t Rows, size_t Cols, typename M2, typename BOp>
1189  size_t i, size_t j) const
1190 {
1191  return m_op(m_scalar1, m_mat2(i, j));
1192 }
1193 
1194 template <typename T, size_t Rows, size_t Cols, typename M2>
1195 constexpr auto operator+(const T& a,
1197 {
1199  b.GetDerived() };
1200 }
1201 
1202 template <typename T, size_t Rows, size_t Cols, typename M2>
1203 constexpr auto operator-(const T& a,
1205 {
1207  b.GetDerived() };
1208 }
1209 
1210 template <typename T, size_t Rows, size_t Cols, typename M2>
1211 constexpr auto operator*(const T& a,
1213 {
1215  b.GetDerived() };
1216 }
1217 
1218 template <typename T, size_t Rows, size_t Cols, typename M2>
1219 constexpr auto operator/(const T& a,
1221 {
1223  b.GetDerived() };
1224 }
1225 
1226 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1227  typename M3, typename TOp>
1229  const
1230 {
1231  return m_mat1.GetRows();
1232 }
1233 
1234 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1235  typename M3, typename TOp>
1237  const
1238 {
1239  return m_mat1.GetCols();
1240 }
1241 
1242 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1243  typename M3, typename TOp>
1245  size_t i, size_t j) const
1246 {
1247  return m_op(m_mat1(i, j), m_mat2(i, j), m_mat3(i, j));
1248 }
1249 
1250 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1251  typename M3>
1255 {
1256  assert(a.GetRows() == low.GetRows() && a.GetRows() == high.GetRows());
1257  assert(a.GetCols() == low.GetCols() && a.GetCols() == high.GetCols());
1258 
1260  a.GetDerived(), low.GetDerived(), high.GetDerived()
1261  };
1262 }
1263 
1264 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1266 {
1267  return m_mat1.GetRows();
1268 }
1269 
1270 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1272 {
1273  return m_mat2.GetCols();
1274 }
1275 
1276 template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1278 {
1279  T sum = m_mat1(i, 0) * m_mat2(0, j);
1280 
1281  for (size_t k = 1; k < m_mat1.GetCols(); ++k)
1282  {
1283  sum += m_mat1(i, k) * m_mat2(k, j);
1284  }
1285 
1286  return sum;
1287 }
1288 
1289 template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1290  typename M2>
1293 {
1294  assert(a.GetCols() == b.GetRows());
1295 
1297  b.GetDerived() };
1298 }
1299 } // namespace CubbyFlow
1300 
1301 #endif
ValueType DistanceSquaredTo(const MatrixExpression< T, R, C, E > &other) const
Returns the squared distance to the other vector.
Matrix expression for element-wise binary operation.
Definition: MatrixExpression.hpp:452
ValueType AbsMin() const
Definition: MatrixExpression-Impl.hpp:141
ValueType LengthSquared() const
Definition: MatrixExpression-Impl.hpp:286
constexpr bool IsSquare() const
Returns true if this matrix is a square matrix.
Definition: MatrixExpression-Impl.hpp:71
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:914
MatrixCSR< T > operator-(const MatrixCSR< T > &a)
Definition: MatrixCSR-Impl.hpp:1029
constexpr size_t GetCols() const
Returns the number of columns.
Definition: MatrixExpression-Impl.hpp:27
ValueType Sum() const
Definition: MatrixExpression-Impl.hpp:77
ValueType DistanceTo(const MatrixExpression< T, R, C, E > &other) const
Returns the distance to the other vector.
ValueType NormSquared() const
Definition: MatrixExpression-Impl.hpp:256
constexpr auto Ceil(const MatrixExpression< T, Rows, Cols, M1 > &a)
Definition: MatrixExpression-Impl.hpp:1025
std::enable_if_t< std::is_arithmetic< T >::value, T > Clamp(T val, T low, T high)
Returns the clamped value.
Definition: MathUtils-Impl.hpp:166
MatrixTri< T, Rows, Cols, const Derived & > StrictUpperTri() const
Returns strictly upper triangle part of this matrix.
Definition: MatrixExpression-Impl.hpp:344
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1006
constexpr auto ElemDiv(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1094
Definition: MatrixExpression.hpp:648
constexpr size_t GetRows() const
Returns the number of rows.
Definition: MatrixExpression-Impl.hpp:21
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1181
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1044
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:931
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1052
T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1277
ValueType FrobeniusNorm() const
Definition: MatrixExpression-Impl.hpp:272
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1128
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1265
Definition: MatrixExpression.hpp:75
size_t SubdominantAxis() const
Definition: MatrixExpression-Impl.hpp:228
T Eval(size_t i, size_t j) const
Returns the evaluated value for (i, j).
Definition: MatrixExpression-Impl.hpp:33
constexpr auto Floor(const MatrixExpression< T, Rows, Cols, M1 > &a)
Definition: MatrixExpression-Impl.hpp:1031
ValueType Length() const
Definition: MatrixExpression-Impl.hpp:278
constexpr auto Max(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1112
MatrixCSR< T > operator/(const MatrixCSR< T > &a, T b)
Definition: MatrixCSR-Impl.hpp:1090
constexpr T operator()(size_t, size_t) const
Definition: MatrixExpression-Impl.hpp:902
ValueType Norm() const
Definition: MatrixExpression-Impl.hpp:250
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1018
ValueType Min() const
Definition: MatrixExpression-Impl.hpp:99
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:896
T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:966
Definition: Matrix.hpp:27
std::enable_if_t<(IsMatrixSizeDynamic< Rows, Cols >)||Cols==1) &&(IsMatrixSizeDynamic< R, C >)||C==1), U > Dot(const MatrixExpression< T, R, C, E > &expression) const
Definition: MatrixExpression-Impl.hpp:391
MatrixTranspose< T, Rows, Cols, const Derived & > Transposed() const
Definition: MatrixExpression-Impl.hpp:365
bool IsSimilar(const MatrixExpression< T, R, C, E > &m, double tol=std::numeric_limits< double >::epsilon()) const
Definition: MatrixExpression-Impl.hpp:46
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:937
Definition: pybind11Utils.hpp:20
size_t DominantAxis() const
Definition: MatrixExpression-Impl.hpp:206
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1174
MatrixDiagonal< T, Rows, Cols, const Derived & > Diagonal() const
Returns diagonal part of this matrix.
Definition: MatrixExpression-Impl.hpp:323
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1271
constexpr auto ElemMul(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1085
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1244
ValueType Trace() const
Definition: MatrixExpression-Impl.hpp:183
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:993
ValueType AbsMax() const
Definition: MatrixExpression-Impl.hpp:162
MatrixOffDiagonal< T, Rows, Cols, const Derived & > OffDiagonal() const
Returns off-diagonal part of this matrix.
Definition: MatrixExpression-Impl.hpp:330
std::enable_if_t<(IsMatrixSizeDynamic< Rows, Cols >)||((Rows==2||Rows==3) &&Cols==1)) &&(IsMatrixSizeDynamic< R, C >)||((R==2||R==3) &&C==1)), Matrix< U, Rows, 1 > > Reflected(const MatrixExpression< T, R, C, E > &normal) const
Returns the reflection vector to the surface with given surface normal.
Definition: MatrixExpression-Impl.hpp:448
MatrixTri< T, Rows, Cols, const Derived & > LowerTri() const
Returns lower triangle part of this matrix (including the diagonal).
Definition: MatrixExpression-Impl.hpp:351
std::enable_if_t<(IsMatrixSizeDynamic< Rows, Cols >)||(Rows==2 &&Cols==1)) &&(IsMatrixSizeDynamic< R, C >)||(R==2 &&C==1)), U > Cross(const MatrixExpression< T, R, C, E > &expression) const
Definition: MatrixExpression-Impl.hpp:412
Definition: Matrix.hpp:312
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:908
Matrix< T, Rows, Cols > Eval() const
Definition: MatrixExpression-Impl.hpp:39
Definition: MatrixExpression.hpp:71
constexpr auto Min(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1103
Definition: MatrixExpression.hpp:590
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1228
MatrixCSR< T > operator+(const MatrixCSR< T > &a, const MatrixCSR< T > &b)
Definition: MatrixCSR-Impl.hpp:1035
ValueType Avg() const
Definition: MatrixExpression-Impl.hpp:93
Derived & GetDerived()
Returns actual implementation (the subclass).
Definition: MatrixExpression-Impl.hpp:509
MatrixTri< T, Rows, Cols, const Derived & > UpperTri() const
Returns upper triangle part of this matrix (including the diagonal).
Definition: MatrixExpression-Impl.hpp:358
MatrixTri< T, Rows, Cols, const Derived & > StrictLowerTri() const
Returns strictly lower triangle part of this matrix.
Definition: MatrixExpression-Impl.hpp:337
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1135
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:890
Definition: MatrixExpression.hpp:68
Definition: MatrixExpression.hpp:65
Base class for matrix expression.
Definition: MatrixExpression.hpp:93
std::enable_if_t< std::is_arithmetic< T >::value, T > AbsMax(T x, T y)
Returns the absolute maximum value among the two inputs.
Definition: MathUtils-Impl.hpp:84
std::enable_if_t< std::is_arithmetic< T >::value, T > AbsMin(T x, T y)
Returns the absolute minimum value among the two inputs.
Definition: MathUtils-Impl.hpp:78
Definition: MatrixExpression.hpp:62
std::enable_if_t<(IsMatrixSizeDynamic< Rows, Cols >)||((Rows==2||Rows==3) &&Cols==1)) &&(IsMatrixSizeDynamic< R, C >)||((R==2||R==3) &&C==1)), Matrix< U, Rows, 1 > > Projected(const MatrixExpression< T, R, C, E > &normal) const
Returns the projected vector to the surface with given surface normal.
Definition: MatrixExpression-Impl.hpp:465
Definition: MatrixExpression.hpp:289
True if similar.
Definition: Functors.hpp:90
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:999
MatrixUnaryOp< U, Rows, Cols, const Derived &, TypeCast< T, U > > CastTo() const
Matrix< T, Rows, Cols > Inverse() const
Returns inverse matrix.
Definition: MatrixExpression-Impl.hpp:371
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:960
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1188
Vector< T, 3 > operator*(const Quaternion< T > &q, const Vector< T, 3 > &v)
Returns quaternion q * vector v.
Definition: Quaternion-Impl.hpp:543
constexpr T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:1060
ValueType Max() const
Definition: MatrixExpression-Impl.hpp:120
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1012
constexpr size_t GetCols() const
Definition: MatrixExpression-Impl.hpp:1236
MatrixScalarElemWiseBinaryOp< T, Rows, Cols, const Derived &, std::divides< T > > Normalized() const
Definition: MatrixExpression-Impl.hpp:315
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:1121
Definition: MatrixExpression.hpp:79
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:954
ValueType Determinant() const
Definition: MatrixExpression-Impl.hpp:198
T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:920
constexpr size_t GetRows() const
Definition: MatrixExpression-Impl.hpp:987
T operator()(size_t i, size_t j) const
Definition: MatrixExpression-Impl.hpp:943
Definition: MatrixExpression.hpp:684