MatrixDenseBase-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_DENSE_BASE_IMPL_HPP
12 #define CUBBYFLOW_MATRIX_DENSE_BASE_IMPL_HPP
13 
14 #include <algorithm>
15 #include <cassert>
16 
17 namespace CubbyFlow
18 {
19 template <typename T, size_t Rows, size_t Cols, typename D>
20 template <size_t R, size_t C, typename E>
22  const MatrixExpression<T, R, C, E>& expression)
23 {
24  for (size_t i = 0; i < GetRows(); ++i)
25  {
26  for (size_t j = 0; j < GetCols(); ++j)
27  {
28  (*this)(i, j) = expression.Eval(i, j);
29  }
30  }
31 }
32 
33 template <typename T, size_t Rows, size_t Cols, typename D>
35 {
36  const size_t n = std::min(GetRows(), GetCols());
37 
38  for (size_t i = 0; i < n; ++i)
39  {
40  (*this)(i, i) = val;
41  }
42 }
43 
44 template <typename T, size_t Rows, size_t Cols, typename D>
46 {
47  for (size_t i = 0; i < GetRows(); ++i)
48  {
49  for (size_t j = 0; j < GetCols(); ++j)
50  {
51  if (i != j)
52  {
53  (*this)(i, j) = val;
54  }
55  }
56  }
57 }
58 
59 template <typename T, size_t Rows, size_t Cols, typename D>
60 template <size_t R, size_t C, typename E>
62  size_t i, const MatrixExpression<T, R, C, E>& row)
63 {
64  assert(row.GetRows() == GetCols() && row.GetCols() == 1);
65 
66  for (size_t j = 0; j < GetCols(); ++j)
67  {
68  (*this)(i, j) = row.Eval(j, 0);
69  }
70 }
71 
72 template <typename T, size_t Rows, size_t Cols, typename D>
73 template <size_t R, size_t C, typename E>
75  size_t j, const MatrixExpression<T, R, C, E>& col)
76 {
77  assert(col.GetRows() == GetRows() && col.GetCols() == 1);
78 
79  for (size_t i = 0; i < GetRows(); ++i)
80  {
81  (*this)(i, j) = col.Eval(i, 0);
82  }
83 }
84 
85 template <typename T, size_t Rows, size_t Cols, typename D>
87 {
88  GetDerived() /= GetDerived().Norm();
89 }
90 
91 template <typename T, size_t Rows, size_t Cols, typename D>
93 {
94  D tmp = GetDerived().Transposed();
95 
96  CopyFrom(tmp);
97 }
98 
99 template <typename T, size_t Rows, size_t Cols, typename D>
101 {
102  CopyFrom(GetDerived().Inverse());
103 }
104 
105 template <typename T, size_t Rows, size_t Cols, typename D>
108 {
109  assert(i < GetRows() && j < GetCols());
110 
111  return GetDerived()[j + i * GetCols()];
112 }
113 
114 template <typename T, size_t Rows, size_t Cols, typename D>
117 {
118  assert(i < GetRows() && j < GetCols());
119 
120  return GetDerived()[j + i * GetCols()];
121 }
122 
123 template <typename T, size_t Rows, size_t Cols, typename D>
124 template <size_t R, size_t C, typename E>
126  const MatrixExpression<T, R, C, E>& expression)
127 {
128  CopyFrom(expression);
129 
130  return *this;
131 }
132 
133 template <typename T, size_t Rows, size_t Cols, typename Derived>
134 template <typename D>
135 std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), D>
137 {
138  return MatrixConstant<T, Rows, Cols>{ Rows, Cols, 0 };
139 }
140 
141 template <typename T, size_t Rows, size_t Cols, typename Derived>
142 template <typename D>
143 std::enable_if_t<IsMatrixSizeDynamic<Rows, Cols>(), D>
145 {
146  return MatrixConstant<T, Rows, Cols>{ rows, cols, 0 };
147 }
148 
149 template <typename T, size_t Rows, size_t Cols, typename Derived>
150 template <typename D>
151 std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), D>
153 {
154  return MatrixConstant<T, Rows, Cols>{ Rows, Cols, val };
155 }
156 
157 template <typename T, size_t Rows, size_t Cols, typename Derived>
158 template <typename D>
159 std::enable_if_t<IsMatrixSizeDynamic<Rows, Cols>(), D>
161  ValueType val)
162 {
163  return MatrixConstant<T, Rows, Cols>{ rows, cols, val };
164 }
165 
166 template <typename T, size_t Rows, size_t Cols, typename Derived>
167 template <typename D>
168 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>(), D>
170 {
171  using ConstType = MatrixConstant<T, Rows, Cols>;
172 
173  return MatrixDiagonal<T, Rows, Cols, ConstType>{ ConstType{ Rows, Cols,
174  1 } };
175 }
176 
177 template <typename T, size_t Rows, size_t Cols, typename Derived>
178 template <typename D>
179 std::enable_if_t<IsMatrixSizeDynamic<Rows, Cols>(), D>
181 {
182  using ConstType = MatrixConstant<T, Rows, Cols>;
183 
184  return MatrixDiagonal<T, Rows, Cols, ConstType>{ ConstType{ rows, rows,
185  1 } };
186 }
187 
188 template <typename T, size_t Rows, size_t Cols, typename Derived>
189 template <typename... Args, typename D>
190 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>(), D>
192  Args... rest)
193 {
194  static_assert(sizeof...(rest) == Rows - 1,
195  "Number of parameters should match the size of diagonal.");
196 
197  D m{};
198  std::array<T, Rows> diag{ { first, rest... } };
199 
200  for (size_t i = 0; i < Rows; ++i)
201  {
202  m(i, i) = diag[i];
203  }
204 
205  return m;
206 }
207 
208 template <typename T, size_t Rows, size_t Cols, typename Derived>
209 template <size_t R, size_t C, typename E, typename D>
210 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>(), D>
212  const MatrixExpression<T, R, C, E>& expression)
213 {
214  assert(expression.GetCols() == 1);
215 
216  D m{};
217 
218  for (size_t i = 0; i < Rows; ++i)
219  {
220  m(i, i) = expression.Eval(i, 0);
221  }
222 
223  return m;
224 }
225 
226 template <typename T, size_t Rows, size_t Cols, typename Derived>
227 template <typename D>
228 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>() && (Rows == 2), D>
230 {
231  return D{ std::cos(rad), -std::sin(rad), std::sin(rad), std::cos(rad) };
232 }
233 
234 template <typename T, size_t Rows, size_t Cols, typename Derived>
235 template <size_t R, size_t C, typename E, typename D>
236 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>() && (Rows == 3 || Rows == 4),
237  D>
239  const MatrixExpression<T, R, C, E>& axis, T rad)
240 {
241  assert(axis.GetRows() == 3 && axis.GetCols() == 1);
242 
243  D result = MakeIdentity();
244 
245  result(0, 0) =
246  1 + (1 - std::cos(rad)) * (axis.Eval(0, 0) * axis.Eval(0, 0) - 1);
247  result(0, 1) = -axis.Eval(2, 0) * std::sin(rad) +
248  (1 - std::cos(rad)) * axis.Eval(0, 0) * axis.Eval(1, 0);
249  result(0, 2) = axis.Eval(1, 0) * std::sin(rad) +
250  (1 - std::cos(rad)) * axis.Eval(0, 0) * axis.Eval(2, 0);
251 
252  result(1, 0) = axis.Eval(2, 0) * std::sin(rad) +
253  (1 - std::cos(rad)) * axis.Eval(0, 0) * axis.Eval(1, 0);
254  result(1, 1) =
255  1 + (1 - std::cos(rad)) * (axis.Eval(1, 0) * axis.Eval(1, 0) - 1);
256  result(1, 2) = -axis.Eval(0, 0) * std::sin(rad) +
257  (1 - std::cos(rad)) * axis.Eval(1, 0) * axis.Eval(2, 0);
258 
259  result(2, 0) = -axis.Eval(1, 0) * std::sin(rad) +
260  (1 - std::cos(rad)) * axis.Eval(0, 0) * axis.Eval(2, 0);
261  result(2, 1) = axis.Eval(0, 0) * std::sin(rad) +
262  (1 - std::cos(rad)) * axis.Eval(1, 0) * axis.Eval(2, 0);
263  result(2, 2) =
264  1 + (1 - std::cos(rad)) * (axis.Eval(2, 0) * axis.Eval(2, 0) - 1);
265 
266  return result;
267 }
268 
269 template <typename T, size_t Rows, size_t Cols, typename Derived>
270 template <size_t R, size_t C, typename E, typename D>
271 std::enable_if_t<IsMatrixStaticSquare<Rows, Cols>() && (Rows == 4), D>
274 {
275  assert(t.GetRows() == 3 && t.GetCols() == 1);
276 
277  D result = MakeIdentity();
278 
279  result(0, 3) = t.Eval(0, 0);
280  result(1, 3) = t.Eval(1, 0);
281  result(2, 3) = t.Eval(2, 0);
282 
283  return result;
284 }
285 
286 template <typename T, size_t Rows, size_t Cols, typename D>
287 constexpr size_t MatrixDenseBase<T, Rows, Cols, D>::GetRows() const
288 {
289  return static_cast<const D&>(*this).GetRows();
290 }
291 
292 template <typename T, size_t Rows, size_t Cols, typename D>
293 constexpr size_t MatrixDenseBase<T, Rows, Cols, D>::GetCols() const
294 {
295  return static_cast<const D&>(*this).GetCols();
296 }
297 
298 template <typename T, size_t Rows, size_t Cols, typename D>
300 {
301  return GetDerived().begin();
302 }
303 
304 template <typename T, size_t Rows, size_t Cols, typename D>
305 constexpr auto MatrixDenseBase<T, Rows, Cols, D>::begin() const
306 {
307  return GetDerived().begin();
308 }
309 
310 template <typename T, size_t Rows, size_t Cols, typename D>
312 {
313  return GetDerived().end();
314 }
315 
316 template <typename T, size_t Rows, size_t Cols, typename D>
317 constexpr auto MatrixDenseBase<T, Rows, Cols, D>::end() const
318 {
319  return GetDerived().end();
320 }
321 
322 template <typename T, size_t Rows, size_t Cols, typename D>
325 {
326  assert(i < GetRows() * GetCols());
327 
328  return GetDerived()[i];
329 }
330 
331 template <typename T, size_t Rows, size_t Cols, typename D>
334 {
335  assert(i < GetRows() * GetCols());
336 
337  return GetDerived()[i];
338 }
339 
340 template <typename T, size_t Rows, size_t Cols, typename D>
342 {
343  return static_cast<D&>(*this);
344 }
345 
346 template <typename T, size_t Rows, size_t Cols, typename D>
348 {
349  return static_cast<const D&>(*this);
350 }
351 } // namespace CubbyFlow
352 
353 #endif
constexpr size_t GetCols() const
Returns the number of columns.
Definition: MatrixExpression-Impl.hpp:27
Definition: MatrixDenseBase.hpp:20
constexpr size_t GetRows() const
Returns the number of rows.
Definition: MatrixExpression-Impl.hpp:21
void SetDiagonal(ConstReference val)
Sets diagonal elements with input scalar.
Definition: MatrixDenseBase-Impl.hpp:34
void CopyFrom(const MatrixExpression< T, R, C, E > &expression)
Copies from generic expression.
Definition: MatrixDenseBase-Impl.hpp:21
MatrixDenseBase & operator=(const MatrixExpression< T, R, C, E > &expression)
Copies from generic expression.
T Eval(size_t i, size_t j) const
Returns the evaluated value for (i, j).
Definition: MatrixExpression-Impl.hpp:33
void SetColumn(size_t j, const MatrixExpression< T, R, C, E > &col)
Sets j-th column with input vector.
Definition: MatrixDenseBase-Impl.hpp:74
Definition: pybind11Utils.hpp:20
void Transpose()
Transposes this matrix.
Definition: MatrixDenseBase-Impl.hpp:92
void SetRow(size_t i, const MatrixExpression< T, R, C, E > &row)
Sets i-th row with input column vector.
Definition: MatrixDenseBase-Impl.hpp:61
T & Reference
Definition: MatrixDenseBase.hpp:24
static std::enable_if_t< IsMatrixStaticSquare< Rows, Cols >) &&(Rows==2), D > MakeRotationMatrix(T rad)
Definition: MatrixDenseBase-Impl.hpp:229
void Normalize()
Definition: MatrixDenseBase-Impl.hpp:86
Base class for matrix expression.
Definition: MatrixExpression.hpp:93
Definition: MatrixExpression.hpp:62
void SetOffDiagonal(ConstReference val)
Sets off-diagonal elements with input scalar.
Definition: MatrixDenseBase-Impl.hpp:45
Definition: MatrixExpression.hpp:289
void Invert()
Inverts this matrix.
Definition: MatrixDenseBase-Impl.hpp:100
static std::enable_if_t< IsMatrixStaticSquare< Rows, Cols >) &&(Rows==4), D > MakeTranslationMatrix(const MatrixExpression< T, R, C, E > &t)
Makes translation matrix.
Definition: MatrixDenseBase-Impl.hpp:272
Reference operator()(size_t i, size_t j)
Definition: MatrixDenseBase-Impl.hpp:107