liballofw
matrix.h
Go to the documentation of this file.
1 #ifndef IV_MATH_MATRIX_H
2 #define IV_MATH_MATRIX_H
3 
4 #include "vector.h"
5 #include <algorithm>
6 
7 namespace allofw {
8 
9  namespace internal {
10  template<typename number_t, int size>
11  void matrix_inversion(const number_t* data, number_t* output);
12 
13  extern template void matrix_inversion<double, 3>(const double*, double*);
14  extern template void matrix_inversion<float, 3>(const float*, float*);
15  extern template void matrix_inversion<double, 4>(const double*, double*);
16  extern template void matrix_inversion<float, 4>(const float*, float*);
17 
18  // template<typename number_t, int size>
19  // void matrix_svd(const number_t* data, number_t* s, number_t* U, number_t* V);
20 
21  // extern template void matrix_svd<double, 3>(const double*, double*, double*, double*);
22  // extern template void matrix_svd<float, 3>(const float*, float*, float*, float*);
23  // extern template void matrix_svd<double, 4>(const double*, double*, double*, double*);
24  // extern template void matrix_svd<float, 4>(const float*, float*, float*, float*);
25  }
26 
27  template <typename T>
28  struct Matrix3_ {
29 
30  typedef T number_t;
32  static const size_t size = 9;
33 
34  // Data stored in column-major order.
35  number_t a11, a21, a31;
36  number_t a12, a22, a32;
37  number_t a13, a23, a33;
38 
39 
40  number_t* data() { return &a11; }
41  const number_t* data() const { return &a11; }
42  std::pair<int, int> shape() const { return std::make_pair(3, 3); }
43 
44  Matrix3_() = default;
45 
46  static Matrix3_ zero() {
47  Matrix3_ r;
48  r.a11 = r.a12 = r.a13 = 0;
49  r.a21 = r.a22 = r.a23 = 0;
50  r.a31 = r.a32 = r.a33 = 0;
51  return r;
52  }
53 
54  static Matrix3_ eye() {
55  Matrix3_ r;
56  r.a11 = r.a22 = r.a33 = 1;
57  r.a12 = r.a21 = r.a13 = 0;
58  r.a31 = r.a32 = r.a23 = 0;
59  return r;
60  }
61 
62  template<typename Generator>
63  static Matrix3_ random(Generator generator) {
64  Matrix3_ r;
65  for(int i = 0; i < size; i++) r.data()[i] = generator();
66  return r;
67  }
68 
69  static Matrix3_ fromDiagonal(const vector_t& diag) {
70  Matrix3_ r;
71  r.a11 = diag.x;
72  r.a22 = diag.y;
73  r.a33 = diag.z;
74  r.a12 = r.a21 = r.a13 = 0;
75  r.a31 = r.a32 = r.a23 = 0;
76  return r;
77  }
78 
79  static Matrix3_ fromColumns(const vector_t& e1, const vector_t& e2, const vector_t& e3) {
80  Matrix3_ r;
81  r.a11 = e1.x; r.a12 = e2.x; r.a13 = e3.x;
82  r.a21 = e1.y; r.a22 = e2.y; r.a23 = e3.y;
83  r.a31 = e1.z; r.a32 = e2.z; r.a33 = e3.z;
84  return r;
85  }
86 
87  static Matrix3_ fromRows(const vector_t& e1, const vector_t& e2, const vector_t& e3) {
88  Matrix3_ r;
89  r.a11 = e1.x; r.a12 = e1.y; r.a13 = e1.z;
90  r.a21 = e2.x; r.a22 = e2.y; r.a23 = e2.z;
91  r.a31 = e3.x; r.a32 = e3.y; r.a33 = e3.z;
92  return r;
93  }
94 
95  vector_t operator * (const vector_t& v) const {
96  return vector_t(a11 * v.x + a12 * v.y + a13 * v.z,
97  a21 * v.x + a22 * v.y + a23 * v.z,
98  a31 * v.x + a32 * v.y + a33 * v.z);
99  }
100 
101  Matrix3_ operator + (const Matrix3_& m) const {
102  Matrix3_ r;
103  r.a11 = a11 + m.a11; r.a12 = a12 + m.a12; r.a13 = a13 + m.a13;
104  r.a21 = a21 + m.a21; r.a22 = a22 + m.a22; r.a23 = a23 + m.a23;
105  r.a31 = a31 + m.a31; r.a32 = a32 + m.a32; r.a33 = a33 + m.a33;
106  return r;
107  }
108  Matrix3_ operator - (const Matrix3_& m) const {
109  Matrix3_ r;
110  r.a11 = a11 - m.a11; r.a12 = a12 - m.a12; r.a13 = a13 - m.a13;
111  r.a21 = a21 - m.a21; r.a22 = a22 - m.a22; r.a23 = a23 - m.a23;
112  r.a31 = a31 - m.a31; r.a32 = a32 - m.a32; r.a33 = a33 - m.a33;
113  return r;
114  }
115  Matrix3_ operator * (number_t s) const {
116  Matrix3_ r;
117  r.a11 = a11 * s; r.a12 = a12 * s; r.a13 = a13 * s;
118  r.a21 = a21 * s; r.a22 = a22 * s; r.a23 = a23 * s;
119  r.a31 = a31 * s; r.a32 = a32 * s; r.a33 = a33 * s;
120  return r;
121  }
122  Matrix3_ operator * (const Matrix3_& m) const {
123  Matrix3_ r;
124  r.a11 = a11 * m.a11 + a12 * m.a21 + a13 * m.a31;
125  r.a12 = a11 * m.a12 + a12 * m.a22 + a13 * m.a32;
126  r.a13 = a11 * m.a13 + a12 * m.a23 + a13 * m.a33;
127  r.a21 = a21 * m.a11 + a22 * m.a21 + a23 * m.a31;
128  r.a22 = a21 * m.a12 + a22 * m.a22 + a23 * m.a32;
129  r.a23 = a21 * m.a13 + a22 * m.a23 + a23 * m.a33;
130  r.a31 = a31 * m.a11 + a32 * m.a21 + a33 * m.a31;
131  r.a32 = a31 * m.a12 + a32 * m.a22 + a33 * m.a32;
132  r.a33 = a31 * m.a13 + a32 * m.a23 + a33 * m.a33;
133  return r;
134  }
135 
136  number_t determinant() const {
137  return a11 * (a22 * a33 - a32 * a23) +
138  a12 * (a23 * a31 - a21 * a33) +
139  a13 * (a21 * a32 - a22 * a31);
140  }
141 
142  Matrix3_ inversion() const {
143  Matrix3_ r;
144  internal::matrix_inversion<number_t, 3>(data(), r.data());
145  return r;
146  }
147  inline Matrix3_ i() const { return inversion(); }
148 
149  // vector_t svd() const {
150  // vector_t r;
151  // internal::matrix_svd<number_t, 3>(data(), r.data(), nullptr, nullptr);
152  // return r;
153  // }
154 
155  // vector_t svd(Matrix3_& U, Matrix3_& V) const {
156  // vector_t r;
157  // internal::matrix_svd<number_t, 3>(data(), r.data(), U.data(), V.data());
158  // return r;
159  // }
160 
161  Matrix3_ transpose() const {
162  Matrix3_ r;
163  r.a11 = a11; r.a21 = a12; r.a31 = a13;
164  r.a12 = a21; r.a22 = a22; r.a32 = a23;
165  r.a13 = a31; r.a23 = a32; r.a33 = a33;
166  return r;
167  }
168  inline Matrix3_ t() const { return transpose(); }
169 
170  static Matrix3_ skew(const vector_t& v) {
171  Matrix3_ r;
172  r.a11 = 0; r.a22 = 0; r.a33 = 0;
173  r.a12 = -v.z; r.a21 = v.z;
174  r.a23 = -v.x; r.a32 = v.x;
175  r.a31 = -v.y; r.a13 = v.y;
176  return r;
177  }
178 
179  number_t max() const { return *std::max_element(data(), data() + size); }
180  number_t min() const { return *std::min_element(data(), data() + size); }
181 
182  friend number_t max(const Matrix3_& m) {
183  return m.max();
184  }
185 
186  friend number_t min(const Matrix3_& m) {
187  return m.min();
188  }
189 
190  Matrix3_ abs() const {
191  Matrix3_ r;
192  for(int i = 0; i < size; i++) { r.data()[i] = std::abs(data()[i]); }
193  return r;
194  }
195  friend Matrix3_ abs(const Matrix3_& m) { return m.abs(); }
196  };
197 
200  typedef Matrix3d Matrix3;
201 
202  static_assert(sizeof(Matrix3d) == sizeof(double) * 9, "Matrix3d alignment error.");
203  static_assert(sizeof(Matrix3f) == sizeof(float) * 9, "Matrix3f alignment error.");
204 
205  template <typename T>
206  struct Matrix4_ {
207 
208  typedef T number_t;
210  static const size_t size = 16;
211 
212  number_t a11, a21, a31, a41;
213  number_t a12, a22, a32, a42;
214  number_t a13, a23, a33, a43;
215  number_t a14, a24, a34, a44;
216 
217  number_t* data() { return &a11; }
218  const number_t* data() const { return &a11; }
219  std::pair<int, int> shape() const { return std::make_pair(4, 4); }
220 
221  Matrix4_() = default;
222 
223  static Matrix4_ zero() {
224  Matrix4_ r;
225  r.a11 = r.a12 = r.a13 = r.a14 = 0;
226  r.a21 = r.a22 = r.a23 = r.a24 = 0;
227  r.a31 = r.a32 = r.a33 = r.a34 = 0;
228  r.a41 = r.a42 = r.a43 = r.a44 = 0;
229  return r;
230  }
231 
232  static Matrix4_ eye() {
233  Matrix4_ r;
234  r.a11 = r.a22 = r.a33 = r.a44 = 1;
235  r.a21 = r.a31 = r.a41 = 0;
236  r.a12 = r.a32 = r.a42 = 0;
237  r.a13 = r.a23 = r.a43 = 0;
238  r.a14 = r.a24 = r.a34 = 0;
239  return r;
240  }
241 
242  template<typename Generator>
243  static Matrix4_ random(Generator generator) {
244  Matrix4_ r;
245  for(int i = 0; i < size; i++) r.data()[i] = generator();
246  return r;
247  }
248 
249  static Matrix4_ fromDiagonal(const vector_t& diag) {
250  Matrix4_ r;
251  r.a11 = diag.x;
252  r.a22 = diag.y;
253  r.a33 = diag.z;
254  r.a44 = diag.w;
255  r.a21 = r.a31 = r.a41 = 0;
256  r.a12 = r.a32 = r.a42 = 0;
257  r.a13 = r.a23 = r.a43 = 0;
258  r.a14 = r.a24 = r.a34 = 0;
259  return r;
260  }
261 
262  static Matrix4_ fromColumns(const vector_t& e1, const vector_t& e2, const vector_t& e3, const vector_t& e4) {
263  Matrix4_ r;
264  r.a11 = e1.x; r.a12 = e2.x; r.a13 = e3.x; r.a14 = e4.x;
265  r.a21 = e1.y; r.a22 = e2.y; r.a23 = e3.y; r.a24 = e4.y;
266  r.a31 = e1.z; r.a32 = e2.z; r.a33 = e3.z; r.a34 = e4.z;
267  r.a41 = e1.w; r.a42 = e2.w; r.a43 = e3.w; r.a44 = e4.w;
268  return r;
269  }
270  static Matrix4_ fromRows(const vector_t& e1, const vector_t& e2, const vector_t& e3, const vector_t& e4) {
271  Matrix4_ r;
272  r.a11 = e1.x; r.a12 = e1.y; r.a13 = e1.z; r.a14 = e1.w;
273  r.a21 = e2.x; r.a22 = e2.y; r.a23 = e2.z; r.a24 = e2.w;
274  r.a31 = e3.x; r.a32 = e3.y; r.a33 = e3.z; r.a34 = e3.w;
275  r.a41 = e4.x; r.a42 = e4.y; r.a43 = e4.z; r.a44 = e4.w;
276  return r;
277  }
278  template<typename T1>
279  vector_t operator * (const vector_t& v) const {
280  return vector_t(a11 * v.x + a12 * v.y + a13 * v.z + a14 * v.w,
281  a21 * v.x + a22 * v.y + a23 * v.z + a24 * v.w,
282  a31 * v.x + a32 * v.y + a33 * v.z + a34 * v.w,
283  a41 * v.x + a42 * v.y + a43 * v.z + a44 * v.w);
284  }
285  Matrix4_ operator + (const Matrix4_& m) const {
286  Matrix4_ r;
287  r.a11 = a11 + m.a11; r.a12 = a12 + m.a12; r.a13 = a13 + m.a13; r.a14 = a14 + m.a14;
288  r.a21 = a21 + m.a21; r.a22 = a22 + m.a22; r.a23 = a23 + m.a23; r.a24 = a24 + m.a24;
289  r.a31 = a31 + m.a31; r.a32 = a32 + m.a32; r.a33 = a33 + m.a33; r.a34 = a34 + m.a34;
290  r.a41 = a41 + m.a41; r.a42 = a42 + m.a42; r.a43 = a43 + m.a43; r.a44 = a44 + m.a44;
291  return r;
292  }
293  Matrix4_ operator - (const Matrix4_& m) const {
294  Matrix4_ r;
295  r.a11 = a11 - m.a11; r.a12 = a12 - m.a12; r.a13 = a13 - m.a13; r.a14 = a14 - m.a14;
296  r.a21 = a21 - m.a21; r.a22 = a22 - m.a22; r.a23 = a23 - m.a23; r.a24 = a24 - m.a24;
297  r.a31 = a31 - m.a31; r.a32 = a32 - m.a32; r.a33 = a33 - m.a33; r.a34 = a34 - m.a34;
298  r.a41 = a41 - m.a41; r.a42 = a42 - m.a42; r.a43 = a43 - m.a43; r.a44 = a44 - m.a44;
299  return r;
300  }
301  Matrix4_ operator * (number_t s) const {
302  Matrix4_ r;
303  r.a11 = a11 * s; r.a12 = a12 * s; r.a13 = a13 * s; r.a14 = a14 * s;
304  r.a21 = a21 * s; r.a22 = a22 * s; r.a23 = a23 * s; r.a24 = a24 * s;
305  r.a31 = a31 * s; r.a32 = a32 * s; r.a33 = a33 * s; r.a34 = a34 * s;
306  r.a41 = a41 * s; r.a42 = a42 * s; r.a43 = a43 * s; r.a44 = a44 * s;
307  return r;
308  }
309  Matrix4_ operator * (const Matrix4_& m) const {
310  Matrix4_ r;
311  r.a11 = a11 * m.a11 + a12 * m.a21 + a13 * m.a31 + a14 * m.a41;
312  r.a12 = a11 * m.a12 + a12 * m.a22 + a13 * m.a32 + a14 * m.a42;
313  r.a13 = a11 * m.a13 + a12 * m.a23 + a13 * m.a33 + a14 * m.a43;
314  r.a14 = a11 * m.a14 + a12 * m.a24 + a13 * m.a34 + a14 * m.a44;
315  r.a21 = a21 * m.a11 + a22 * m.a21 + a23 * m.a31 + a24 * m.a41;
316  r.a22 = a21 * m.a12 + a22 * m.a22 + a23 * m.a32 + a24 * m.a42;
317  r.a23 = a21 * m.a13 + a22 * m.a23 + a23 * m.a33 + a24 * m.a43;
318  r.a24 = a21 * m.a14 + a22 * m.a24 + a23 * m.a34 + a24 * m.a44;
319  r.a31 = a31 * m.a11 + a32 * m.a21 + a33 * m.a31 + a34 * m.a41;
320  r.a32 = a31 * m.a12 + a32 * m.a22 + a33 * m.a32 + a34 * m.a42;
321  r.a33 = a31 * m.a13 + a32 * m.a23 + a33 * m.a33 + a34 * m.a43;
322  r.a34 = a31 * m.a14 + a32 * m.a24 + a33 * m.a34 + a34 * m.a44;
323  r.a41 = a41 * m.a11 + a42 * m.a21 + a43 * m.a31 + a44 * m.a41;
324  r.a42 = a41 * m.a12 + a42 * m.a22 + a43 * m.a32 + a44 * m.a42;
325  r.a43 = a41 * m.a13 + a42 * m.a23 + a43 * m.a33 + a44 * m.a43;
326  r.a44 = a41 * m.a14 + a42 * m.a24 + a43 * m.a34 + a44 * m.a44;
327  return r;
328  }
329 
330  number_t determinant() const {
331  return
332  + a44 * (a11 * (a22 * a33 - a32 * a23) + a12 * (a23 * a31 - a21 * a33) + a13 * (a21 * a32 - a22 * a31))
333  - a34 * (a11 * (a22 * a43 - a42 * a23) + a12 * (a23 * a41 - a21 * a43) + a13 * (a21 * a42 - a22 * a41))
334  + a24 * (a11 * (a32 * a43 - a42 * a33) + a12 * (a33 * a41 - a31 * a43) + a13 * (a31 * a42 - a32 * a41))
335  - a14 * (a21 * (a32 * a43 - a42 * a33) + a22 * (a33 * a41 - a31 * a43) + a23 * (a31 * a42 - a32 * a41));
336  }
337 
338  Matrix4_ inversion() const {
339  Matrix4_ r;
340  internal::matrix_inversion<number_t, 4>(data(), r.data());
341  return r;
342  }
343  inline Matrix4_ i() const { return inversion(); }
344 
345  // vector_t svd() const {
346  // vector_t r;
347  // internal::matrix_svd<number_t, 4>(data(), r.data(), nullptr, nullptr);
348  // return r;
349  // }
350 
351  // vector_t svd(Matrix4_& U, Matrix4_& V) const {
352  // vector_t r;
353  // internal::matrix_svd<number_t, 4>(data(), r.data(), U.data(), V.data());
354  // return r;
355  // }
356 
357  Matrix4_ transpose() const {
358  Matrix4_ r;
359  r.a11 = a11; r.a21 = a12; r.a31 = a13; r.a41 = a14;
360  r.a12 = a21; r.a22 = a22; r.a32 = a23; r.a42 = a24;
361  r.a13 = a31; r.a23 = a32; r.a33 = a33; r.a43 = a34;
362  r.a14 = a41; r.a24 = a42; r.a34 = a43; r.a44 = a44;
363  return r;
364  }
365  inline Matrix4_ t() const { return transpose(); }
366 
367  number_t max() const { return *std::max_element(data(), data() + size); }
368  number_t min() const { return *std::min_element(data(), data() + size); }
369 
370  friend number_t max(const Matrix4_& m) {
371  return m.max();
372  }
373 
374  friend number_t min(const Matrix4_& m) {
375  return m.min();
376  }
377 
378  Matrix4_ abs() const {
379  Matrix4_ r;
380  for(int i = 0; i < size; i++) { r.data()[i] = std::abs(data()[i]); }
381  return r;
382  }
383  friend Matrix4_ abs(const Matrix4_& m) { return m.abs(); }
384  };
385 
388  typedef Matrix4d Matrix4;
389 
390  static_assert(sizeof(Matrix4d) == sizeof(double) * 16, "Matrix4d alignment error.");
391  static_assert(sizeof(Matrix4f) == sizeof(float) * 16, "Matrixf alignment error.");
392 
393 }
394 
395 #endif
number_t a12
Definition: matrix.h:213
number_t a12
Definition: matrix.h:36
Matrix3_ t() const
Definition: matrix.h:168
number_t a13
Definition: matrix.h:37
static Matrix3_ zero()
Definition: matrix.h:46
number_t z
Definition: vector.h:157
number_t determinant() const
Definition: matrix.h:330
friend Matrix3_ abs(const Matrix3_ &m)
Definition: matrix.h:195
number_t min() const
Definition: matrix.h:368
number_t a33
Definition: matrix.h:37
number_t x
Definition: vector.h:110
number_t y
Definition: vector.h:157
number_t a34
Definition: matrix.h:215
number_t a44
Definition: matrix.h:215
static Matrix4_ eye()
Definition: matrix.h:232
number_t a33
Definition: matrix.h:214
number_t a21
Definition: matrix.h:212
Matrix3_ transpose() const
Definition: matrix.h:161
number_t * data()
Definition: matrix.h:40
Matrix4d Matrix4
Definition: matrix.h:388
number_t max() const
Definition: matrix.h:179
Vector4_< T > vector_t
Definition: matrix.h:209
number_t a24
Definition: matrix.h:215
number_t a21
Definition: matrix.h:35
static Matrix4_ fromRows(const vector_t &e1, const vector_t &e2, const vector_t &e3, const vector_t &e4)
Definition: matrix.h:270
static Matrix3_ skew(const vector_t &v)
Definition: matrix.h:170
number_t a11
Definition: matrix.h:35
Definition: allofw.h:12
static Matrix4_ fromColumns(const vector_t &e1, const vector_t &e2, const vector_t &e3, const vector_t &e4)
Definition: matrix.h:262
Matrix4_ i() const
Definition: matrix.h:343
template void matrix_inversion< double, 4 >(const double *, double *)
number_t w
Definition: vector.h:157
template void matrix_inversion< double, 3 >(const double *, double *)
number_t a42
Definition: matrix.h:213
Matrix4_ transpose() const
Definition: matrix.h:357
const number_t * data() const
Definition: matrix.h:41
T number_t
Definition: matrix.h:30
friend number_t max(const Matrix3_ &m)
Definition: matrix.h:182
T number_t
Definition: matrix.h:208
number_t a32
Definition: matrix.h:213
Matrix4_< double > Matrix4d
Definition: matrix.h:387
static Matrix4_ random(Generator generator)
Definition: matrix.h:243
number_t a23
Definition: matrix.h:214
Matrix4_ abs() const
Definition: matrix.h:378
static Matrix3_ eye()
Definition: matrix.h:54
number_t a41
Definition: matrix.h:212
number_t * data()
Definition: matrix.h:217
friend number_t min(const Matrix3_ &m)
Definition: matrix.h:186
Vector3_< T > vector_t
Definition: matrix.h:31
number_t a43
Definition: matrix.h:214
Definition: matrix.h:28
Matrix3_< float > Matrix3f
Definition: matrix.h:198
Definition: matrix.h:206
Matrix3_ i() const
Definition: matrix.h:147
std::pair< int, int > shape() const
Definition: matrix.h:219
Matrix4_ inversion() const
Definition: matrix.h:338
Matrix3_ abs() const
Definition: matrix.h:190
number_t a23
Definition: matrix.h:37
static Matrix3_ fromColumns(const vector_t &e1, const vector_t &e2, const vector_t &e3)
Definition: matrix.h:79
void matrix_inversion(const number_t *data, number_t *output)
template void matrix_inversion< float, 3 >(const float *, float *)
number_t a14
Definition: matrix.h:215
number_t a31
Definition: matrix.h:212
number_t y
Definition: vector.h:110
number_t max() const
Definition: matrix.h:367
number_t min() const
Definition: matrix.h:180
friend number_t max(const Matrix4_ &m)
Definition: matrix.h:370
static Matrix4_ zero()
Definition: matrix.h:223
Definition: vector.h:63
static Matrix3_ fromRows(const vector_t &e1, const vector_t &e2, const vector_t &e3)
Definition: matrix.h:87
Definition: vector.h:114
Matrix3_ inversion() const
Definition: matrix.h:142
number_t a22
Definition: matrix.h:213
number_t z
Definition: vector.h:110
Matrix3_< double > Matrix3d
Definition: matrix.h:199
template void matrix_inversion< float, 4 >(const float *, float *)
number_t a22
Definition: matrix.h:36
number_t abs(number_t a)
Compute absolute value.
Definition: basic.h:27
std::pair< int, int > shape() const
Definition: matrix.h:42
Matrix4_ t() const
Definition: matrix.h:365
friend number_t min(const Matrix4_ &m)
Definition: matrix.h:374
friend Matrix4_ abs(const Matrix4_ &m)
Definition: matrix.h:383
const number_t * data() const
Definition: matrix.h:218
Vector3_< T1 > operator*(const Vector3_< T1 > &v, const Matrix3_< T2 > &m)
Definition: quaternion.h:85
number_t x
Definition: vector.h:157
number_t determinant() const
Definition: matrix.h:136
Matrix3d Matrix3
Definition: matrix.h:200
static Matrix3_ random(Generator generator)
Definition: matrix.h:63
number_t a31
Definition: matrix.h:35
number_t a11
Definition: matrix.h:212
static Matrix3_ fromDiagonal(const vector_t &diag)
Definition: matrix.h:69
number_t a32
Definition: matrix.h:36
Matrix4_< float > Matrix4f
Definition: matrix.h:386
number_t a13
Definition: matrix.h:214
static Matrix4_ fromDiagonal(const vector_t &diag)
Definition: matrix.h:249