cgv
Loading...
Searching...
No Matches
fmat.h
1#pragma once
2
3#include "fvec.h"
4#include <cassert>
5#include <initializer_list>
6
7namespace cgv {
8namespace math {
9
11
21template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
22class fmat : public fvec<T,N*M>
23{
24public:
30 fmat() {}
32 fmat(std::initializer_list<T> components) : fvec<T,N*M>((cgv::type::uint32_type)components.size(), components.begin()) {}
34 fmat(std::initializer_list<fvec<T,N>> cols) : fvec<T,N*M>(N*(cgv::type::uint32_type)cols.size(), (T*)cols.begin()) {}
36 fmat(const T& c) : base_type(c) {}
38 fmat(cgv::type::uint32_type n, cgv::type::uint32_type m, const T* a, bool column_major = true) {
40 for (j = 0; j < std::min(m, M); ++j) {
42 for (i = 0; i < std::min(n, N); ++i)
43 (*this)(i, j) = a[column_major ? j * n + i : i * m + j];
44 for (; i < N; ++i)
45 (*this)(i, j) = (i == j) ? T(1) : T(0);
46 }
47 for (; j < M; ++j)
48 for (cgv::type::uint32_type i = 0; i < N; ++i)
49 (*this)(i, j) = (i == j) ? T(1) : T(0);
50 }
52 template <typename S>
53 fmat(cgv::type::uint32_type n, cgv::type::uint32_type m, const S* a, bool column_major = true) {
54 for (cgv::type::uint32_type j = 0; j < std::min(m, M); ++j)
55 for (cgv::type::uint32_type i = 0; i < std::min(n, N); ++i)
56 (*this)(i, j) = (T)a[column_major ? j * n + i : i * m + j];
57 }
59 template <typename S>
60 fmat(const fmat<S,N,M>& m) : base_type(m) {}
62 template <typename T1, typename T2>
63 fmat(const fvec<T1,N>& v, const fvec<T2,M>& w) {
64 for(unsigned i = 0; i < N; i++)
65 for(unsigned j = 0; j < M; j++)
66 (*this)(i,j) = (T)(v(i)*w(j));
67 }
69 constexpr static unsigned nrows() { return N; }
71 constexpr static unsigned ncols() { return M; }
73 template <typename S>
75 base_type::operator = (m);
76 return *this;
77 }
79 this_type& operator = (const T& s) {
80 fill (s);
81 return *this;
82 }
84 bool is_square() const { return N == M; }
86 T& operator () (unsigned i, unsigned j) {
87 assert(i < N && j < M);
88 return base_type::v[j*N+i];
89 }
91 const T& operator () (unsigned i, unsigned j) const {
92 assert(i < N && j < M);
93 return base_type::v[j*N+i];
94 }
95 //in place scalar multiplication
96 this_type& operator *= (const T& s) { base_type::operator *= (s); return *this; }
98 this_type operator * (const T& s) const { this_type r=(*this); r*=(T)s; return r; }
100 fmat<T,N,M>& operator /= (const T& s) { base_type::operator /= (s); return *this; }
102 const fmat<T,N,M> operator / (const T& s) const { this_type r=(*this); r/=(T)s; return r; }
104 fmat<T,N,M>& operator += (const T& s) { base_type::operator += (s); return *this; }
106 const fmat<T,N,M> operator + (const T& s) { this_type r=(*this); r+=(T)s; return r; }
108 fmat<T,N,M>& operator -= (const T& s) { base_type::operator -= (s); return *this; }
110 const fmat<T,N,M> operator - (const T& s) { this_type r=(*this); r-=(T)s; return r; }
112 const fmat<T,N,M> operator-() const { return (*this)*(-1); }
114 template <typename S>
117 template <typename S>
120 template <typename S>
121 const fmat<T,N,M> operator+(const fmat<S,N,M> m2)const { fmat<T,N,M> r=(*this); r += m2; return r; }
123 template <typename S>
124 const fmat<T,N,M> operator-(const fmat<S,N,M> m2)const { fmat<T,N,M> r=(*this); r -= m2; return r; }
126 template <typename S>
128 {
129 assert(N == M);
130 fmat<T,N,N> r(T(0));
131 for(unsigned i = 0; i < N; i++)
132 for(unsigned j = 0; j < N;j++)
133 for(unsigned k = 0; k < N; k++)
134 r(i,j) += operator()(i,k) * (T)(m2(k,j));
135 (*this)=r;
136 return *this;
137 }
139 template <typename S, cgv::type::uint32_type L>
140 const fmat<T,N,L> operator*(const fmat<S,M,L>& m2) const
141 {
142 fmat<T,N,L> r; r.zeros();
143 for(unsigned i = 0; i < N; i++)
144 for(unsigned j = 0; j < L;j++)
145 for(unsigned k = 0; k < M; k++)
146 r(i,j) += operator()(i,k) * (T)(m2(k,j));
147 return r;
148 }
152 template <typename S>
153 const fmat<T,N,N> mul_h (const fmat<S,N-1,N-1>& m2) const
154 {
155 static_assert(N == M, "Number of rows and columns must be equal");
156 static const auto vzero = fvec<T, N-1>(0);
157 fvec<T,N> rows[N]; // extracting a row takes linear time so we only want to do it once for each row
158 for (unsigned i=0; i<N; i++)
159 rows[i] = row(i);
160 fmat<T,N,N> r;
161 // (1) multiply with implied N x (N-1) matrix that is assumed to have an all-zero last row
162 for (unsigned j=0; j<N-1; j++)
163 for (unsigned i=0; i<N; i++)
164 r(i,j) = dot_dir(rows[i], m2.col(j));
165 // (2) assume homogeneous zero position vector in last column of 2nd operand for calculating last result column
166 for (unsigned i=0; i<N; i++)
167 r(i,N-1) = dot_pos(rows[i], vzero);
168 return r;
169 }
170
172 template <typename S>
173 const fvec<S,N> operator * (const fvec<S,M>& v) const {
174 fvec<S,N> r;
175 for(unsigned i = 0; i < N; i++)
176 r(i) = dot(row(i),v);
177 return r;
178 }
180 template <typename S>
181 const fvec<S,N> mul_pos (const fvec<S,M-1>& v) const {
182 fvec<S,N> r;
183 for(unsigned i = 0; i < N; i++)
184 r(i) = dot_pos(row(i), v);
185 return r;
186 }
188 template <typename S>
189 const fvec<S,N> mul_dir (const fvec<S,M-1>& v) const {
190 fvec<S,N> r;
191 for(unsigned i = 0; i < N; i++)
192 r(i) = dot_dir(row(i), v);
193 return r;
194 }
195
197 fvec<T,M> row(unsigned i) const {
198 fvec<T,M> r;
199 for(unsigned j = 0; j < M; j++)
200 r(j)=operator()(i,j);
201 return r;
202 }
204 void set_row(unsigned i,const fvec<T,M>& v) {
205 for(unsigned j = 0; j < M;j++)
206 operator()(i,j)=v(j);
207 }
209 fvec<T,N>& col(unsigned j) {
210 return reinterpret_cast<fvec<T,N>*>(this)[j];
211 }
213 const fvec<T,N>& col(unsigned j) const {
214 return reinterpret_cast<const fvec<T,N>*>(this)[j];
215 }
217 void set_col(unsigned j,const fvec<T,N>& v) {
218 reinterpret_cast<fvec<T,N>*>(this)[j] = v;
219 }
220
222 T trace() const {
223 assert(N == M);
224 T t = 0;
225 for(unsigned i = 0; i < N;i++)
226 t+=operator()(i,i);
227 return t;
228 }
229
231 void transpose() {
232 assert(N == M);
233 for(unsigned i = 1; i < N; i++)
234 for(unsigned j = 0; j < i; j++)
235 std::swap(operator()(i,j), operator()(j,i));
236 }
238 T frobenius_norm() const { return base_type::length(); }
240 void identity()
241 {
242 base_type::zeros();
243 for(unsigned i = 0; i < M && i < N; ++i)
244 operator()(i,i)=1;
245 }
246};
247
249#define CGV_MATH_FMAT_DECLARED
250
252// For N > 4, convert to mat first and use inv function from inv.h
253// Example:
254// mat<T> M(N, N, &m(0, 0));
255// return fmat<T, N, N>(N, N, &(inv(M)(0, 0)));
256template <typename T, cgv::type::uint32_type N>
257fmat<T, N, N> inverse(const fmat<T, N, N>& m) = delete;
258
260template <typename T>
261fmat<T, 2, 2> inverse(const fmat<T, 2, 2>& m)
262{
263 fmat<T, 2, 2> im;
264 T t4 = T(1) / (-m(0, 0) * m(1, 1) + m(0, 1) * m(1, 0));
265 im(0, 0) = -m(1, 1) * t4;
266 im(1, 0) = +m(1, 0) * t4;
267 im(0, 1) = +m(0, 1) * t4;
268 im(1, 1) = -m(0, 0) * t4;
269
270 return im;
271}
272
274template <typename T>
275fmat<T, 3, 3> inverse(const fmat<T, 3, 3>& m)
276{
277 T inv_det = (T)1 / (
278 +m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1))
279 - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0))
280 + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)));
281
282 fmat<T, 3, 3> im;
283 im(0, 0) = +(m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) * inv_det;
284 im(0, 1) = -(m(0, 1) * m(2, 2) - m(0, 2) * m(2, 1)) * inv_det;
285 im(0, 2) = +(m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * inv_det;
286 im(1, 0) = -(m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) * inv_det;
287 im(1, 1) = +(m(0, 0) * m(2, 2) - m(0, 2) * m(2, 0)) * inv_det;
288 im(1, 2) = -(m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * inv_det;
289 im(2, 0) = +(m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)) * inv_det;
290 im(2, 1) = -(m(0, 0) * m(2, 1) - m(0, 1) * m(2, 0)) * inv_det;
291 im(2, 2) = +(m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * inv_det;
292 return im;
293}
294
296template <typename T>
297fmat<T, 4, 4> inverse(const fmat<T, 4, 4>& m)
298{
299 T coef00 = m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2);
300 T coef02 = m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1);
301 T coef03 = m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1);
302
303 T coef04 = m(1, 2) * m(3, 3) - m(1, 3) * m(3, 2);
304 T coef06 = m(1, 1) * m(3, 3) - m(1, 3) * m(3, 1);
305 T coef07 = m(1, 1) * m(3, 2) - m(1, 2) * m(3, 1);
306
307 T coef08 = m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2);
308 T coef10 = m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1);
309 T coef11 = m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1);
310
311 T coef12 = m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2);
312 T coef14 = m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1);
313 T coef15 = m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1);
314
315 T coef16 = m(0, 2) * m(2, 3) - m(0, 3) * m(2, 2);
316 T coef18 = m(0, 1) * m(2, 3) - m(0, 3) * m(2, 1);
317 T coef19 = m(0, 1) * m(2, 2) - m(0, 2) * m(2, 1);
318
319 T coef20 = m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2);
320 T coef22 = m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1);
321 T coef23 = m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1);
322
323 fvec<T, 4> fac0(coef00, coef00, coef02, coef03);
324 fvec<T, 4> fac1(coef04, coef04, coef06, coef07);
325 fvec<T, 4> fac2(coef08, coef08, coef10, coef11);
326 fvec<T, 4> fac3(coef12, coef12, coef14, coef15);
327 fvec<T, 4> fac4(coef16, coef16, coef18, coef19);
328 fvec<T, 4> fac5(coef20, coef20, coef22, coef23);
329
330 fvec<T, 4> vec0(m(0, 1), m(0, 0), m(0, 0), m(0, 0));
331 fvec<T, 4> vec1(m(1, 1), m(1, 0), m(1, 0), m(1, 0));
332 fvec<T, 4> vec2(m(2, 1), m(2, 0), m(2, 0), m(2, 0));
333 fvec<T, 4> vec3(m(3, 1), m(3, 0), m(3, 0), m(3, 0));
334
335 fvec<T, 4> inv0(vec1 * fac0 - vec2 * fac1 + vec3 * fac2);
336 fvec<T, 4> inv1(vec0 * fac0 - vec2 * fac3 + vec3 * fac4);
337 fvec<T, 4> inv2(vec0 * fac1 - vec1 * fac3 + vec3 * fac5);
338 fvec<T, 4> inv3(vec0 * fac2 - vec1 * fac4 + vec2 * fac5);
339
340 fvec<T, 4> sign_a(+(T)1, -(T)1, +(T)1, -(T)1);
341 fvec<T, 4> sign_b(-(T)1, +(T)1, -(T)1, +(T)1);
342
343 fmat<T, 4, 4> im;
344 im.set_col(0, inv0 * sign_a);
345 im.set_col(1, inv1 * sign_b);
346 im.set_col(2, inv2 * sign_a);
347 im.set_col(3, inv3 * sign_b);
348 fvec<T, 4> row0(im(0, 0), im(1, 0), im(2, 0), im(3, 0));
349 fvec<T, 4> dot0(m.row(0) * row0);
350 T dot1 = (dot0[0] + dot0[1]) + (dot0[2] + dot0[3]);
351 T inv_det = (T)1 / dot1;
352 return im * inv_det;
353}
354
356template <typename T, cgv::type::uint32_type N>
357fmat<T,N,N> transpose(const fmat<T,N,N>& m)
358{
359 fmat<T,N,N> m_t(m);
360 m_t.transpose();
361 return m_t;
362}
363
365template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
366fmat<T,N,M> operator * (const T& s, const fmat<T,N,M>& m)
367{
368 return m*s;
369}
370
372template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
373fvec<T, M> operator * (const fvec<T, N>& v_row, const fmat<T, N, M>& m)
374{
375 fvec<T, M> r_row;
376 for (unsigned i = 0; i < M; i++)
377 r_row(i) = dot(m.col(i), v_row);
378 return r_row;
379}
380
382template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
383std::ostream& operator<<(std::ostream& out, const fmat<T,N,M>& m)
384{
385 for (unsigned i=0;i<N;++i) {
386 for(unsigned j =0;j < M-1;++j)
387 out << m(i,j) << " ";
388 out << m(i,M-1);
389 if(i != N-1)
390 out <<"\n";
391 }
392 return out;
393}
394
396template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
397std::istream& operator>>(std::istream& in, fmat<T,N,M>& m)
398{
399 for (unsigned i=0;i<m.nrows();++i)
400 for(unsigned j =0;j < m.ncols();++j)
401 in >> m(i,j);
402 return in;
403}
404
406template <typename T, cgv::type::uint32_type N, typename S, cgv::type::uint32_type M>
407fmat<T, N, M> dyad(const fvec<T,N>& v, const fvec<S,M>& w)
408{
409 fmat<T, N, M> m;
410 for (unsigned i = 0; i < N; i++)
411 for (unsigned j = 0; j < M; j++)
412 m(i, j) = v(i)*(T)w(j);
413 return m;
414}
415
417template <typename T>
418T det(const fmat<T, 2, 2>& m) {
419 return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);
420}
421
423template <typename T>
424T det(const fmat<T, 3, 3>& m) {
425 T a = m(0, 0) * m(1, 1) * m(2, 2) + m(0, 1) * m(1, 2) * m(2, 0) + m(0, 2) * m(1, 0) * m(2, 1);
426 T b = -m(2, 0) * m(1, 1) * m(0, 2) - m(2, 1) * m(1, 2) * m(0, 0) - m(2, 2) * m(1, 0) * m(0, 1);
427 return a + b;
428}
429
431template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
432const fmat<T, N, M> lerp(const fmat<T, N, M>& m1, const fmat<T, N, M>& m2, T t)
433{
434 fmat<T, N, M> m;
435 for(unsigned i = 0; i < N; i++)
436 for(unsigned j = 0; j < M; j++)
437 m(i, j) = ((T)1 - t)*m1(i, j) + t * m2(i, j);
438 return m;
439}
440
442template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
443const fmat<T, N, M> lerp(const fmat<T, N, M>& m1, const fmat<T, N, M>& m2, fmat<T, N, M> t)
444{
445 fmat<T, N, M> m;
446 for(unsigned i = 0; i < N; i++)
447 for(unsigned j = 0; j < M; j++)
448 m(i, j) = ((T)1 - t(i, j))*m1(i, j) + t(i, j)*m2(i, j);
449 return m;
450}
451
452} // namespace math
453
456
465
474
476
477}// namespace cgv
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
matrix of fixed size dimensions
Definition fmat.h:23
const fmat< T, N, M > operator-(const fmat< S, N, M > m2) const
matrix subtraction
Definition fmat.h:124
const fmat< T, N, L > operator*(const fmat< S, M, L > &m2) const
multiplication with a ncols x M matrix m2
Definition fmat.h:140
const fvec< T, N > & col(unsigned j) const
read-only reference a column of the matrix as a vector
Definition fmat.h:213
fmat(const fvec< T1, N > &v, const fvec< T2, M > &w)
construct from outer product of vector v and w
Definition fmat.h:63
fmat()
standard constructor
Definition fmat.h:30
const fvec< S, N > mul_dir(const fvec< S, M-1 > &v) const
multiplication with M-1 dimensional direction vector which will be implicitly homogenized
Definition fmat.h:189
fmat(cgv::type::uint32_type n, cgv::type::uint32_type m, const S *a, bool column_major=true)
creates a matrix from an array a of given dimensions but different type - by default in column major ...
Definition fmat.h:53
fmat(std::initializer_list< T > components)
construct from individual components using list-initialization syntax
Definition fmat.h:32
static constexpr unsigned ncols()
number of columns
Definition fmat.h:71
fmat(std::initializer_list< fvec< T, N > > cols)
construct from column vectors using list-initialization syntax
Definition fmat.h:34
fmat(const T &c)
construct a matrix with all elements set to c
Definition fmat.h:36
fvec< T, N > & col(unsigned j)
reference a column of the matrix as a vector
Definition fmat.h:209
fvec< T, N *M > base_type
base type is a vector with sufficent number of elements
Definition fmat.h:26
const fmat< T, N, M > operator/(const T &s) const
division by a scalar
Definition fmat.h:102
const fmat< T, N, M > operator+(const fmat< S, N, M > m2) const
matrix addition
Definition fmat.h:121
void set_col(unsigned j, const fvec< T, N > &v)
set column j of the matrix to vector v
Definition fmat.h:217
fmat< T, N, M > & operator+=(const T &s)
in place addition by a scalar
Definition fmat.h:104
const fmat< T, N, M > operator-() const
negation operator
Definition fmat.h:112
fvec< T, M > row(unsigned i) const
extract a row from the matrix as a vector, this takes time linear in the number of columns
Definition fmat.h:197
static constexpr unsigned nrows()
number of rows
Definition fmat.h:69
T frobenius_norm() const
returns the frobenius norm of matrix m
Definition fmat.h:238
this_type operator*(const T &s) const
scalar multiplication
Definition fmat.h:98
const fmat< T, N, M > operator*=(const fmat< S, N, N > &m2)
in place matrix multiplication with a ncols x ncols matrix m2
Definition fmat.h:127
fmat< T, N, M > this_type
base type is a vector with sufficent number of elements
Definition fmat.h:28
const fmat< T, N, M > operator+(const T &s)
componentwise addition of a scalar
Definition fmat.h:106
const fmat< T, N, N > mul_h(const fmat< S, N-1, N-1 > &m2) const
multiplication with (N-1)x(N-1) matrix, assuming the first operand represents an affine or perspectiv...
Definition fmat.h:153
fmat< T, N, M > & operator=(const fmat< S, N, M > &m)
assignment of a matrix with a different element type
Definition fmat.h:74
void transpose()
transpose matrix
Definition fmat.h:231
fmat(cgv::type::uint32_type n, cgv::type::uint32_type m, const T *a, bool column_major=true)
creates a matrix from an array a of given dimensions - by default in column major format - and fills ...
Definition fmat.h:38
void set_row(unsigned i, const fvec< T, M > &v)
set row i of the matrix to vector v
Definition fmat.h:204
T trace() const
returns the trace
Definition fmat.h:222
const fvec< S, N > mul_pos(const fvec< S, M-1 > &v) const
multiplication with M-1 dimensional position vector which will be implicitly homogenized
Definition fmat.h:181
bool is_square() const
returns true if matrix is a square matrix
Definition fmat.h:84
fmat< T, N, M > & operator-=(const T &s)
in place substraction of a scalar
Definition fmat.h:108
void identity()
set identity matrix
Definition fmat.h:240
fmat(const fmat< S, N, M > &m)
copy constructor for matrix with different element type
Definition fmat.h:60
T & operator()(unsigned i, unsigned j)
access to the element in the ith row in column j
Definition fmat.h:86
fmat< T, N, M > & operator/=(const T &s)
in place division by a scalar
Definition fmat.h:100
A vector with zero based index.
Definition fvec.h:29
fvec< T, N > & operator*=(const T &s)
in place multiplication with s
Definition fvec.h:192
fvec< T, N > & operator-=(const T &s)
in place subtraction by scalar s
Definition fvec.h:190
fvec< T, N > & operator/=(const T &s)
in place division by scalar s
Definition fvec.h:194
iterator begin()
return an iterator to the first component of *this
Definition fvec.h:168
T length() const
length of the vector L2-Norm
Definition fvec.h:257
fvec< T, N > & operator+=(const T &s)
in place addition of a scalar s
Definition fvec.h:188
T & w()
return fourth component
Definition fvec.h:148
static cgv::type::uint32_type size()
return number of components
Definition fvec.h:134
the cgv namespace
Definition print.h:11
cgv::math::fmat< double, 3, 3 > dmat3
declare type of 3x3 matrices
Definition fmat.h:469
cgv::math::fmat< float, 3, 3 > mat3
declare type of 3x3 matrices
Definition fmat.h:460
cgv::math::fmat< double, 4, 4 > dmat4
declare type of 4x4 matrices
Definition fmat.h:471
cgv::math::fmat< float, 2, 2 > mat2
declare type of 2x2 matrices
Definition fmat.h:458
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:659
cgv::math::fmat< double, 2, 2 > dmat2
declare type of 2x2 matrices
Definition fmat.h:467
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
Definition fvec.h:661
cgv::math::fmat< double, 3, 4 > dmat3x4
declare type of 3x4 matrices which are often used to store a pose
Definition fmat.h:473
cgv::math::fmat< float, 4, 4 > mat4
declare type of 4x4 matrices
Definition fmat.h:462
cgv::math::fmat< float, 3, 4 > mat3x4
declare type of 3x4 matrices which are often used to store a pose
Definition fmat.h:464
std::ostream & operator<<(std::ostream &os, const vr_device_info &di)
stream out operator for device infos
Definition vr_info.cxx:10