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>
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 {
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
252template <typename T, cgv::type::uint32_type N>
253fmat<T,N,N> transpose(const fmat<T,N,N>& m)
254{
255 fmat<T,N,N> m_t(m);
256 m_t.transpose();
257 return m_t;
258}
259
261template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
262fmat<T,N,M> operator * (const T& s, const fmat<T,N,M>& m)
263{
264 return m*s;
265}
266
268template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
269fvec<T, M> operator * (const fvec<T, N>& v_row, const fmat<T, N, M>& m)
270{
271 fvec<T, M> r_row;
272 for (unsigned i = 0; i < M; i++)
273 r_row(i) = dot(m.col(i), v_row);
274 return r_row;
275}
276
278template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
279std::ostream& operator<<(std::ostream& out, const fmat<T,N,M>& m)
280{
281 for (unsigned i=0;i<N;++i) {
282 for(unsigned j =0;j < M-1;++j)
283 out << m(i,j) << " ";
284 out << m(i,M-1);
285 if(i != N-1)
286 out <<"\n";
287 }
288 return out;
289}
290
292template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
293std::istream& operator>>(std::istream& in, fmat<T,N,M>& m)
294{
295 for (unsigned i=0;i<m.nrows();++i)
296 for(unsigned j =0;j < m.ncols();++j)
297 in >> m(i,j);
298 return in;
299}
300
302template <typename T, cgv::type::uint32_type N, typename S, cgv::type::uint32_type M>
303fmat<T, N, M> dyad(const fvec<T,N>& v, const fvec<S,M>& w)
304{
305 fmat<T, N, M> m;
306 for (unsigned i = 0; i < N; i++)
307 for (unsigned j = 0; j < M; j++)
308 m(i, j) = v(i)*(T)w(j);
309 return m;
310}
311
313template <typename T>
314T det(const fmat<T, 2, 2>& m) {
315 return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);
316}
317
319template <typename T>
320T det(const fmat<T, 3, 3>& m) {
321 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);
322 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);
323 return a + b;
324}
325
327template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
328const fmat<T, N, M> lerp(const fmat<T, N, M>& m1, const fmat<T, N, M>& m2, T t)
329{
330 fmat<T, N, M> m;
331 for(unsigned i = 0; i < N; i++)
332 for(unsigned j = 0; j < M; j++)
333 m(i, j) = ((T)1 - t)*m1(i, j) + t * m2(i, j);
334 return m;
335}
336
338template <typename T, cgv::type::uint32_type N, cgv::type::uint32_type M>
339const fmat<T, N, M> lerp(const fmat<T, N, M>& m1, const fmat<T, N, M>& m2, fmat<T, N, M> t)
340{
341 fmat<T, N, M> m;
342 for(unsigned i = 0; i < N; i++)
343 for(unsigned j = 0; j < M; j++)
344 m(i, j) = ((T)1 - t(i, j))*m1(i, j) + t(i, j)*m2(i, j);
345 return m;
346}
347
348} // namespace math
349
352
363
372
374
375}// 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:26
fvec< T, N > & operator*=(const T &s)
in place multiplication with s
Definition fvec.h:193
fvec< T, N > & operator-=(const T &s)
in place subtraction by scalar s
Definition fvec.h:191
fvec< T, N > & operator/=(const T &s)
in place division by scalar s
Definition fvec.h:195
T length() const
length of the vector L2-Norm
Definition fvec.h:249
fvec< T, N > & operator+=(const T &s)
in place addition of a scalar s
Definition fvec.h:189
fvec & operator=(const fvec< T, N > &rhs)
assign vector rhs, if vector and rhs have different sizes, vector has been resized to match the size ...
Definition fvec.h:119
T & w()
fourth element
Definition fvec.h:167
void zeros()
fill the vector with zeros
Definition fvec.h:133
void fill(const T &a)
fill elements of vector with scalar v
Definition fvec.h:131
static cgv::type::uint32_type size()
return number of elements
Definition fvec.h:179
the cgv namespace
Definition print.h:11
cgv::math::fmat< float, 2, 3 > mat23
declare type of 2x3 matrices used to store camera matrix
Definition fmat.h:356
cgv::math::fmat< double, 3, 3 > dmat3
declare type of 3x3 matrices
Definition fmat.h:367
cgv::math::fmat< float, 3, 3 > mat3
declare type of 3x3 matrices
Definition fmat.h:358
cgv::math::fmat< double, 4, 4 > dmat4
declare type of 4x4 matrices
Definition fmat.h:369
cgv::math::fmat< float, 2, 2 > mat2
declare type of 2x2 matrices
Definition fmat.h:354
cgv::math::fmat< double, 2, 2 > dmat2
declare type of 2x2 matrices
Definition fmat.h:365
cgv::math::fmat< double, 3, 4 > dmat3x4
declare type of 3x4 matrices which are often used to store a pose
Definition fmat.h:371
cgv::math::fmat< float, 4, 4 > mat4
declare type of 4x4 matrices
Definition fmat.h:360
cgv::math::fmat< float, 3, 4 > mat3x4
declare type of 3x4 matrices which are often used to store a pose
Definition fmat.h:362
std::ostream & operator<<(std::ostream &os, const vr_device_info &di)
stream out operator for device infos
Definition vr_info.cxx:10