Berserk
TMatMxN.hpp
Go to the documentation of this file.
1 /**********************************************************************************/
2 /* This file is part of Berserk Engine project */
3 /* https://github.com/EgorOrachyov/Berserk */
4 /**********************************************************************************/
5 /* MIT License */
6 /* */
7 /* Copyright (c) 2018 - 2021 Egor Orachyov */
8 /* */
9 /* Permission is hereby granted, free of charge, to any person obtaining a copy */
10 /* of this software and associated documentation files (the "Software"), to deal */
11 /* in the Software without restriction, including without limitation the rights */
12 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13 /* copies of the Software, and to permit persons to whom the Software is */
14 /* furnished to do so, subject to the following conditions: */
15 /* */
16 /* The above copyright notice and this permission notice shall be included in all */
17 /* copies or substantial portions of the Software. */
18 /* */
19 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25 /* SOFTWARE. */
26 /**********************************************************************************/
27 
28 #ifndef BERSERK_TMATMXN_H
29 #define BERSERK_TMATMXN_H
30 
31 #include <core/Config.hpp>
32 #include <core/Typedefs.hpp>
33 #include <core/math/MathUtils.hpp>
34 #include <core/math/TVecN.hpp>
35 
36 #include <array>
37 #include <cassert>
38 
40 
55 template<typename T, uint32 M, uint32 N>
56 class TMatMxN {
57 public:
58  TMatMxN() noexcept {
59  Zero();
60  }
61 
62  explicit TMatMxN(const std::array<TVecN<T, N>, M> &rows) noexcept {
63  uint32 row = 0;
64 
65  for (auto &r : rows) {
66  for (uint32 j = 0; j < N; j++) {
67  values[row * N + j] = r[j];
68  }
69  }
70  }
71 
72  TMatMxN(const T *vs, size_t count) {
73  assert(count == GetSize());
74  Memory::Copy(values, vs, sizeof(T) * count);
75  }
76 
77  TMatMxN(T m_00, T m_01,
78  T m_10, T m_11) noexcept : TMatMxN() {
79  static_assert(M >= 2 && N >= 2, "Cannot apply to this type");
80 
81  values[0 * N + 0] = m_00;
82  values[0 * N + 1] = m_01;
83  values[1 * N + 0] = m_10;
84  values[1 * N + 1] = m_11;
85  }
86 
87  TMatMxN(T m_00, T m_01, T m_02,
88  T m_10, T m_11, T m_12,
89  T m_20, T m_21, T m_22) noexcept : TMatMxN() {
90  static_assert(M >= 3 && N >= 3, "Cannot apply to this type");
91 
92  values[0 * N + 0] = m_00;
93  values[0 * N + 1] = m_01;
94  values[0 * N + 2] = m_02;
95 
96  values[1 * N + 0] = m_10;
97  values[1 * N + 1] = m_11;
98  values[1 * N + 2] = m_12;
99 
100  values[2 * N + 0] = m_20;
101  values[2 * N + 1] = m_21;
102  values[2 * N + 2] = m_22;
103  }
104 
105  TMatMxN(T m_00, T m_01, T m_02, T m_03,
106  T m_10, T m_11, T m_12, T m_13,
107  T m_20, T m_21, T m_22, T m_23,
108  T m_30, T m_31, T m_32, T m_33) noexcept : TMatMxN() {
109  static_assert(M >= 3 && N >= 3, "Cannot apply to this type");
110 
111  values[0 * N + 0] = m_00;
112  values[0 * N + 1] = m_01;
113  values[0 * N + 2] = m_02;
114  values[0 * N + 3] = m_03;
115 
116  values[1 * N + 0] = m_10;
117  values[1 * N + 1] = m_11;
118  values[1 * N + 2] = m_12;
119  values[1 * N + 3] = m_13;
120 
121  values[2 * N + 0] = m_20;
122  values[2 * N + 1] = m_21;
123  values[2 * N + 2] = m_22;
124  values[2 * N + 3] = m_23;
125 
126  values[3 * N + 0] = m_30;
127  values[3 * N + 1] = m_31;
128  values[3 * N + 2] = m_32;
129  values[3 * N + 3] = m_33;
130  }
131 
132  TMatMxN(const TMatMxN &other) noexcept {
133  for (uint32 i = 0; i < M * N; i++) {
134  values[i] = other.values[i];
135  }
136  }
137 
138  TMatMxN(TMatMxN &&other) noexcept {
139  for (uint32 i = 0; i < M * N; i++) {
140  values[i] = other.values[i];
141  }
142  }
143 
144  template<uint32 M1, uint32 N1>
145  TMatMxN(const TMatMxN<T, M1, N1> &other) : TMatMxN() {
146  static_assert(M1 <= M, "Matrix too large");
147  static_assert(N1 <= N, "Matrix too large");
148 
149  for (uint32 i = 0; i < M1; i++) {
150  for (uint32 j = 0; j < N1; j++) {
151  values[i * N + j] = other.values[i * N1 + j];
152  }
153  }
154 
155  for (uint32 i = M1; i < M; i++) {
156  values[i * N + i] = 1;
157  }
158  }
159 
160  TMatMxN &operator+=(const TMatMxN &other) {
161  for (uint32 i = 0; i < M * N; i++) {
162  values[i] += other.values[i];
163  }
164  return *this;
165  }
166 
167  TMatMxN &operator-=(const TMatMxN &other) {
168  for (uint32 i = 0; i < M * N; i++) {
169  values[i] -= other.values[i];
170  }
171  return *this;
172  }
173 
174  TMatMxN operator+(const TMatMxN &other) const {
175  TMatMxN result = *this;
176  result += other;
177  return result;
178  }
179 
180  TMatMxN operator-(const TMatMxN &other) const {
181  TMatMxN result = *this;
182  result -= other;
183  return result;
184  }
185 
186  template<uint32 K>
188  TMatMxN<T, M, K> result;
189 
190  for (uint32 i = 0; i < M; i++) {
191  for (uint32 j = 0; j < K; j++) {
192  T v = 0;
193 
194  for (uint32 f = 0; f < N; f++) {
195  v += values[i * N + f] * other.values[f * K + j];
196  }
197 
198  result.values[i * K + j] = v;
199  }
200  }
201 
202  return result;
203  }
204 
205  TMatMxN &operator*=(T other) {
206  for (uint32 i = 0; i < M * N; i++) {
207  values[i] *= other;
208  }
209  return *this;
210  }
211 
212  TMatMxN &operator/=(T other) {
213  for (uint32 i = 0; i < M * N; i++) {
214  values[i] /= other;
215  }
216  return *this;
217  }
218 
219  TMatMxN &operator+=(T other) {
220  for (uint32 i = 0; i < M * N; i++) {
221  values[i] += other;
222  }
223  return *this;
224  }
225 
226  TMatMxN &operator-=(T other) {
227  for (uint32 i = 0; i < M * N; i++) {
228  values[i] -= other;
229  }
230  return *this;
231  }
232 
233  TMatMxN operator*(T value) const {
234  TMatMxN result = *this;
235  result *= value;
236  return result;
237  }
238 
239  TMatMxN operator/(T value) const {
240  TMatMxN result = *this;
241  result /= value;
242  return result;
243  }
244 
245  TMatMxN operator+(T value) const {
246  TMatMxN result = *this;
247  result += value;
248  return result;
249  }
250 
251  TMatMxN operator-(T value) const {
252  TMatMxN result = *this;
253  result -= value;
254  return result;
255  }
256 
257  TMatMxN &operator=(const TMatMxN &other) {
258  for (uint32 i = 0; i < M * N; i++) {
259  values[i] = other.values[i];
260  }
261  return *this;
262  }
263 
264  template<uint32 M1, uint32 N1>
266  if (i + M1 > M) return {};
267  if (j + N1 > N) return {};
268 
269  TMatMxN<T, M1, N1> result;
270 
271  for (uint32 si = 0; si < M1; si++) {
272  const T *row = &values[(si + i) * N + j];
273  for (uint32 sj = 0; sj < N1; sj++) {
274  result.values[si * N1 + sj] = *row;
275  row += 1;
276  }
277  }
278 
279  return result;
280  }
281 
282  template<uint32 M1, uint32 N1>
283  void SubMatrix(TMatMxN<T, M1, N1> &result, uint32 i, uint32 j) const {
284  if (i + M1 > M) return;
285  if (j + N1 > N) return;
286 
287  for (uint32 si = 0; si < M1; si++) {
288  const T *row = &values[(si + i) * N + j];
289  for (uint32 sj = 0; sj < N1; sj++) {
290  result.values[si * N1 + sj] = *row;
291  row += 1;
292  }
293  }
294  }
295 
296  TMatMxN<T, M, N - 1> ExcludeColumn(uint32 columnIndex) const {
297  TMatMxN<T, M, N - 1> result;
298 
299  for (uint32 i = 0; i < M; i++) {
300  for (uint32 j = 0; j < columnIndex; j++) {
301  result.values[i * result.GetDimN() + j] = values[i * N + j];
302  }
303 
304  for (uint32 j = columnIndex; j < result.GetDimN(); j++) {
305  result.values[i * result.GetDimN() + j] = values[i * N + j + 1];
306  }
307  }
308 
309  return result;
310  }
311 
313  TMatMxN<T, N, M> result;
314 
315  for (uint32 i = 0; i < M; i++) {
316  for (uint32 j = 0; j < N; j++) {
317  result.values[j * M + i] = values[i * N + j];
318  }
319  }
320 
321  return result;
322  }
323 
324  TVecN<T, M> GetColumn(uint32 index) const {
325  assert(index < N);
326 
327  TVecN<T, M> result;
328  for (uint32 i = 0; i < M; i++) {
329  result.values[i] = values[i * N + index];
330  }
331 
332  return result;
333  }
334 
335  TVecN<T, N> GetRow(uint32 index) const {
336  assert(index < M);
337 
338  TVecN<T, N> result;
339  for (uint32 i = 0; i < N; i++) {
340  result.values[i] = values[index * N + i];
341  }
342 
343  return result;
344  }
345 
347  TVecN<T, M> result;
348 
349  for (uint32 i = 0; i < M; i++) {
350  for (uint32 j = 0; j < N; j++) {
351  result.values[i] += values[i * N + j] * v[j];
352  }
353  }
354 
355  return result;
356  }
357 
358  void Zero() {
359  for (auto &v : values) {
360  v = 0;
361  }
362  }
363 
364  T *operator[](uint32 i) { return &values[i * N]; }
365  const T *operator[](uint32 i) const { return &values[i * N]; }
366 
367  T *GetData() { return values; }
368  const T *GetData() const { return values; }
369 
370  constexpr static uint32 GetStride() { return N * sizeof(T); }
371  constexpr static uint32 GetSize() { return N * M; }
372 
373  constexpr static uint32 GetDimM() { return M; }
374  constexpr static uint32 GetDimN() { return N; }
375 
376 public:
377  T values[M * N];
378 };
379 
383 
392 template<typename T, uint32 DM, uint32 DN>
393 struct TDetMxN;
394 
395 template<typename T>
396 struct TDetMxN<T, 1, 1> {
397  T operator()(const TMatMxN<T, 1, 1> &m) const {
398  return m.values[0];
399  }
400 };
401 
402 template<typename T>
403 struct TDetMxN<T, 2, 2> {
404  T operator()(const TMatMxN<T, 2, 2> &m) const {
405  return m.values[0] * m.values[3] - m.values[1] * m.values[2];
406  }
407 };
408 
409 template<typename T, uint32 DN>
410 struct TDetMxN<T, DN, DN> {
411  T operator()(const TMatMxN<T, DN, DN> &m) const {
412  T result = 0;
413  TMatMxN<T, DN - 1, DN> sub;
414  m.Submatrix(sub, 1, 0);
415 
416  for (uint32 i = 0; i < DN; i++) {
417  result += (i % 2 ? -1 : 1) * m.values[i] * sub.ExcludeColumn(i).Det();
418  }
419 
420  return result;
421  }
422 };
423 
424 template<typename T, uint32 DM, uint32 DN>
425 struct TDetMxN {
426  T operator()(const TMatMxN<T, DM, DN> &m) const {
427  return 0;
428  }
429 };
430 
436 
437 #endif//BERSERK_TMATMXN_H
#define BRK_NS_END
Definition: Config.hpp:48
std::uint32_t uint32
Definition: Typedefs.hpp:44
static void Copy(void *destination, const void *source, size_t sizeInBytes)
Definition: Memory.hpp:58
Generic matrix of M x N size for space of type T.
Definition: TMatMxN.hpp:56
TVecN< T, M > GetColumn(uint32 index) const
Definition: TMatMxN.hpp:324
T * operator[](uint32 i)
Definition: TMatMxN.hpp:364
TMatMxN< T, M, K > operator*(const TMatMxN< T, N, K > &other) const
Definition: TMatMxN.hpp:187
TMatMxN() noexcept
Definition: TMatMxN.hpp:58
TMatMxN operator+(T value) const
Definition: TMatMxN.hpp:245
TMatMxN & operator/=(T other)
Definition: TMatMxN.hpp:212
constexpr static uint32 GetSize()
Definition: TMatMxN.hpp:371
TVecN< T, N > GetRow(uint32 index) const
Definition: TMatMxN.hpp:335
constexpr static uint32 GetDimN()
Definition: TMatMxN.hpp:374
TMatMxN(T m_00, T m_01, T m_02, T m_03, T m_10, T m_11, T m_12, T m_13, T m_20, T m_21, T m_22, T m_23, T m_30, T m_31, T m_32, T m_33) noexcept
Definition: TMatMxN.hpp:105
TMatMxN(const std::array< TVecN< T, N >, M > &rows) noexcept
Definition: TMatMxN.hpp:62
TVecN< T, M > operator*(const TVecN< T, N > &v) const
Definition: TMatMxN.hpp:346
TMatMxN< T, N, M > Transpose() const
Definition: TMatMxN.hpp:312
TMatMxN & operator+=(const TMatMxN &other)
Definition: TMatMxN.hpp:160
TMatMxN< T, M1, N1 > SubMatrix(uint32 i, uint32 j) const
Definition: TMatMxN.hpp:265
TMatMxN(TMatMxN &&other) noexcept
Definition: TMatMxN.hpp:138
T * GetData()
Definition: TMatMxN.hpp:367
TMatMxN(const T *vs, size_t count)
Definition: TMatMxN.hpp:72
TMatMxN operator/(T value) const
Definition: TMatMxN.hpp:239
TMatMxN & operator-=(T other)
Definition: TMatMxN.hpp:226
constexpr static uint32 GetDimM()
Definition: TMatMxN.hpp:373
void Zero()
Definition: TMatMxN.hpp:358
constexpr static uint32 GetStride()
Definition: TMatMxN.hpp:370
TMatMxN & operator=(const TMatMxN &other)
Definition: TMatMxN.hpp:257
TMatMxN(T m_00, T m_01, T m_02, T m_10, T m_11, T m_12, T m_20, T m_21, T m_22) noexcept
Definition: TMatMxN.hpp:87
TMatMxN operator-(const TMatMxN &other) const
Definition: TMatMxN.hpp:180
TMatMxN(const TMatMxN< T, M1, N1 > &other)
Definition: TMatMxN.hpp:145
T values[M *N]
Definition: TMatMxN.hpp:377
void SubMatrix(TMatMxN< T, M1, N1 > &result, uint32 i, uint32 j) const
Definition: TMatMxN.hpp:283
TMatMxN operator-(T value) const
Definition: TMatMxN.hpp:251
TMatMxN & operator*=(T other)
Definition: TMatMxN.hpp:205
const T * GetData() const
Definition: TMatMxN.hpp:368
TMatMxN(const TMatMxN &other) noexcept
Definition: TMatMxN.hpp:132
TMatMxN< T, M, N - 1 > ExcludeColumn(uint32 columnIndex) const
Definition: TMatMxN.hpp:296
TMatMxN operator*(T value) const
Definition: TMatMxN.hpp:233
TMatMxN operator+(const TMatMxN &other) const
Definition: TMatMxN.hpp:174
TMatMxN & operator-=(const TMatMxN &other)
Definition: TMatMxN.hpp:167
TMatMxN(T m_00, T m_01, T m_10, T m_11) noexcept
Definition: TMatMxN.hpp:77
TMatMxN & operator+=(T other)
Definition: TMatMxN.hpp:219
const T * operator[](uint32 i) const
Definition: TMatMxN.hpp:365
Generic vector class for an N dimensional space base on type T.
Definition: TVecN.hpp:55
T values[N]
Definition: TVecN.hpp:595
Definition: GLDevice.cpp:46
T operator()(const TMatMxN< T, 1, 1 > &m) const
Definition: TMatMxN.hpp:397
T operator()(const TMatMxN< T, 2, 2 > &m) const
Definition: TMatMxN.hpp:404
T operator()(const TMatMxN< T, DN, DN > &m) const
Definition: TMatMxN.hpp:411
Matrix det evaluation helper.
Definition: TMatMxN.hpp:425
T operator()(const TMatMxN< T, DM, DN > &m) const
Definition: TMatMxN.hpp:426