cgv
Loading...
Searching...
No Matches
mat.h
1#pragma once
2
3#include "vec.h"
4#include <limits>
5#include <cassert>
6
7namespace cgv {
8namespace math {
9
10
11
12template <typename T>
13class mat;
14
15
16
17
18template <typename RandomAccessIterator>
20{
21public:
22 typedef RandomAccessIterator base_type;
23 typedef typename base_type::pointer pointer;
24 typedef typename base_type::reference reference;
25 typedef typename base_type::value_type value_type;
26 typedef typename base_type::difference_type difference_type;
27 typedef typename base_type::iterator_category iterator_category;
28private:
29 RandomAccessIterator internal_iter;
30 int step;
31
32
33 friend class mat<value_type>;
34
35 step_iterator( RandomAccessIterator begin,int step=1):internal_iter(begin),step(step)
36 {}
37
38
39public:
40
41
42 step_iterator():internal_iter(NULL)
43 {
44 step=0;
45 }
46
47 step_iterator(const step_iterator& other)
48 {
49 internal_iter=other.internal_iter;
50 step=other.step;
51 }
52
53 step_iterator& operator=(const step_iterator& other)
54 {
55 if(*this != other)
56 {
57 internal_iter = other.internal_iter;
58 step = other.step;
59 }
60 return *this;
61 }
62
63 bool operator==(const step_iterator& other) const
64 {
65 return internal_iter == other.internal_iter;
66 }
67
68 bool operator!=(const step_iterator& other) const
69 {
70 return !(*this==other);
71 }
72
73 reference operator*()
74 {
75 return *internal_iter;
76 }
77
78 reference operator*() const
79 {
80 return *internal_iter;
81 }
82 pointer operator->()
83 {
84 return &**this;
85 }
86
87 pointer operator->() const
88 {
89 return &**this;
90 }
91
92 step_iterator& operator ++()
93 {
94
95 internal_iter+=step;
96 return *this;
97 }
98
99 step_iterator operator ++(int)
100 {
101 step_iterator tmp=*this;
102 ++*this;
103 return tmp;
104
105 }
106 step_iterator& operator --()
107 {
108 internal_iter-=step;
109 return *this;
110 }
111 step_iterator operator --(int)
112 {
113 step_iterator tmp=*this;
114 --*this;
115 return tmp;
116 }
117
118
119
120 step_iterator& operator +=(difference_type n)
121 {
122 internal_iter+=n*step;
123 return *this;
124
125 }
126
127 step_iterator& operator -=(difference_type n)
128 {
129 internal_iter-=n*step;
130 return *this;
131 }
132
133 step_iterator operator -(difference_type n) const
134 {
135 step_iterator tmp=*this;
136 tmp-=n;
137 return tmp;
138 }
139 difference_type operator-(const step_iterator& right) const
140 {
141 return (internal_iter - right.internal_iter)/step;
142 }
143
144
145 step_iterator operator +(difference_type n)const
146 {
147 step_iterator tmp=*this;
148 tmp+=n;
149 return tmp;
150 }
151
152 reference operator[](difference_type offset) const
153 {
154 return (*(*this + offset));
155 }
156
157 bool operator <(const step_iterator& other) const
158 {
159 if(step > 0)
160 return internal_iter < other.internal_iter;
161 else
162 return internal_iter > other.internal_iter;
163 }
164
165 bool operator >(const step_iterator& other) const
166 {
167 if(step > 0)
168 return internal_iter > other.internal_iter;
169 else
170 return internal_iter < other.internal_iter;
171 }
172
173 bool operator <=(const step_iterator& other) const
174 {
175 if(step > 0)
176 return internal_iter <= other.internal_iter;
177 else
178 return internal_iter >= other.internal_iter;
179 }
180
181 bool operator >=(const step_iterator& other) const
182 {
183 if(step > 0)
184 return internal_iter >= other.internal_iter;
185 else
186 return internal_iter <= other.internal_iter;
187 }
188
189
190};
191
192
193
194
195
196
197
198
199
200
201
206template <typename T>
207class mat
208{
209protected:
213 unsigned _ncols;
215 unsigned _nrows;
216
217
218public:
219 typedef typename vec<T>::value_type value_type;
220 typedef typename vec<T>::reference reference;
221 typedef typename vec<T>::const_reference const_reference;
222 typedef typename vec<T>::pointer pointer;
223 typedef typename vec<T>::const_pointer const_pointer;
224 typedef typename vec<T>::iterator iterator;
225 typedef typename vec<T>::const_iterator const_iterator;
226 typedef typename vec<T>::reverse_iterator reverse_iterator;
227 typedef typename vec<T>::const_reverse_iterator const_reverse_iterator;
228
229 typedef iterator col_iterator;
230 typedef const col_iterator const_col_iterator;
231 typedef std::reverse_iterator<col_iterator> reverse_col_iterator;
232 typedef std::reverse_iterator<const_col_iterator> const_reverse_col_iterator;
233
235 typedef const row_iterator const_row_iterator;
236 typedef std::reverse_iterator<row_iterator> reverse_row_iterator;
237 typedef std::reverse_iterator<const_row_iterator> const_reverse_row_iterator;
238
241 typedef std::reverse_iterator<diag_iterator> reverse_diag_iterator;
242 typedef std::reverse_iterator<const_diag_iterator> const_reverse_diag_iterator;
243
246 typedef std::reverse_iterator<anti_diag_iterator> reverse_anti_diag_iterator;
247 typedef std::reverse_iterator<const_anti_diag_iterator> const_reverse_anti_diag_iterator;
248
249
250
251
252
253 iterator begin(){return _data.begin();}
254 iterator end(){return _data.end();}
255 const_iterator begin() const{return _data.begin();}
256 const_iterator end() const{return _data.end();}
257 reverse_iterator rbegin(){return _data.rbegin();}
258 reverse_iterator rend(){return _data.rend();}
259 const_reverse_iterator rbegin() const{return _data.rbegin();}
260 const_reverse_iterator rend() const {return _data.rend();}
261
262
263
264 col_iterator col_begin(int c)
265 {
266 return col_iterator(_data.begin()+(c*_nrows));
267 }
268 col_iterator col_end(int c)
269 {
270 return col_iterator(_data.begin()+(c+1)*_nrows );
271 }
272 const_col_iterator col_begin(int c) const
273 {
274 return const_col_iterator(_data.begin()+(c*_nrows));
275 }
276 const_col_iterator col_end(int c) const
277 {
278 return const_col_iterator(_data.begin()+(c+1)*_nrows );
279 }
280 reverse_col_iterator col_rbegin(int c)
281 {
282 return (reverse_col_iterator(col_end(c)));
283 }
284 reverse_col_iterator col_rend(int c)
285 {
286 return (reverse_col_iterator(col_begin(c)));
287 }
288 const_reverse_col_iterator col_rbegin(int c) const
289 {
290 return (const_reverse_col_iterator(col_end(c)));
291 }
292 const_reverse_col_iterator col_rend(int c) const
293 {
294 return (const_reverse_col_iterator(col_begin(c)));
295 }
296
297 row_iterator row_begin(int r)
298 {
299 return row_iterator(_data.begin()+r,_nrows);
300 }
301 row_iterator row_end(int r)
302 {
303 return row_iterator(_data.begin()+(r+_ncols*_nrows),_nrows);
304 }
305 const_row_iterator row_begin(int r) const
306 {
307 return const_row_iterator(_data.begin()+r,_nrows);
308 }
309 const_row_iterator row_end(int r) const
310 {
311 return const_row_iterator(_data.begin()+(r+_ncols*_nrows),_nrows);
312 }
313
314 reverse_row_iterator row_rbegin(int r)
315 {
316 return (reverse_row_iterator(row_end(r)));
317 }
318
319 reverse_row_iterator row_rend(int r)
320 {
321 return (reverse_row_iterator(row_begin(r)));
322 }
323
324 const_reverse_row_iterator row_rbegin(int r) const
325 {
326 return (const_reverse_row_iterator(row_end(r)));
327 }
328
329 const_reverse_row_iterator row_rend(int r) const
330 {
331 return (const_reverse_row_iterator(row_begin(r)));
332 }
333
334
335
336
337 diag_iterator diag_begin(int d=0)
338 {
339 if(d <= 0)
340 return diag_iterator(_data.begin()-d ,_nrows+1);
341 else
342 return diag_iterator(_data.begin()+d*_nrows,_nrows+1);
343
344 }
345 diag_iterator diag_end(int d=0)
346 {
347 if(d <= 0)
348 {
349 int n=std::min<int>(_nrows+d,_ncols);
350 return diag_iterator(_data.begin()-d+n*(_nrows+1),_nrows+1);
351 }
352 else
353 {
354 int n = std::min<int>(_ncols-d,_nrows);
355 return diag_iterator(_data.begin()+d*_nrows+n*(_nrows+1),_nrows+1) ;
356 }
357 }
358 const_diag_iterator diag_begin(int d=0) const
359 {
360 if(d <= 0)
361 return const_diag_iterator(begin()-d ,_nrows+1);
362 else
363 return const_diag_iterator(begin()+d*_nrows,_nrows+1);
364
365 }
366 const_diag_iterator diag_end(int d=0) const
367 {
368 if(d <= 0)
369 {
370 int n=std::min<int>(_nrows+d,_ncols);
371 return const_diag_iterator(_data.begin()-d+n*(_nrows+1),_nrows+1);
372 }
373 else
374 {
375 int n = std::min<int>(_ncols-d,_nrows);
376 return const_diag_iterator(_data.begin()+d*_nrows+n*(_nrows+1),_nrows+1) ;
377 }
378 }
379 reverse_diag_iterator diag_rbegin(int d=0)
380 {
381 return (reverse_diag_iterator(diag_end(d)));
382 }
383 reverse_diag_iterator diag_rend(int d=0)
384 {
385 return (reverse_diag_iterator(diag_begin(d)));
386 }
387 const_reverse_diag_iterator diag_rbegin(int d=0) const
388 {
389 return (const_reverse_diag_iterator(diag_end(d)));
390 }
391 const_reverse_diag_iterator diag_rend(int d=0) const
392 {
393 return (const_reverse_diag_iterator(diag_begin(d)));
394 }
395
396 anti_diag_iterator anti_diag_begin(int d=0)
397 {
398 if(d >= 0)
399 return anti_diag_iterator(_data.begin()+(_ncols-1-d)*_nrows ,1-_nrows);
400 else
401 return anti_diag_iterator(_data.begin()+(_ncols-1)*_nrows-d ,1-_nrows);
402 }
403
404 anti_diag_iterator anti_diag_end(int d=0)
405 {
406 if(d >= 0)
407 {
408 int n=std::min(_ncols-d,_nrows);
409 return anti_diag_iterator(_data.begin()+(_ncols-1-d)*_nrows +n*(1-_nrows),1-_nrows);
410 }
411 else
412 {
413 int n=std::min(_nrows+d,_ncols);
414 return anti_diag_iterator(_data.begin()+(_ncols-1)*_nrows-d +n*(1-_nrows),1-_nrows);
415 }
416 }
417
418 const_anti_diag_iterator anti_diag_begin(int d=0) const
419 {
420 if(d >= 0)
421 return const_anti_diag_iterator(_data.begin()+(_ncols-1-d)*_nrows ,1-_nrows);
422 else
423 return const_anti_diag_iterator(_data.begin()+(_ncols-1)*_nrows-d ,1-_nrows);
424 }
425
426 const_anti_diag_iterator anti_diag_end(int d=0) const
427 {
428 if(d >= 0)
429 {
430 int n=std::min(_ncols-d,_nrows);
431 return const_anti_diag_iterator(_data.begin()+(_ncols-1-d)*_nrows +n*(1-_nrows),1-_nrows);
432 }
433 else
434 {
435 int n=std::min(_nrows+d,_ncols);
436 return const_anti_diag_iterator(_data.begin()+(_ncols-1)*_nrows-d +n*(1-_nrows),1-_nrows);
437 }
438 }
439
440 reverse_anti_diag_iterator anti_diag_rbegin(int d=0)
441 {
442 return (reverse_anti_diag_iterator(anti_diag_end(d)));
443 }
444
445 reverse_anti_diag_iterator anti_diag_rend(int d=0)
446 {
447 return (reverse_anti_diag_iterator(anti_diag_begin(d)));
448 }
449
450 const_reverse_anti_diag_iterator anti_diag_rbegin(int d=0) const
451 {
452 return (const_reverse_anti_diag_iterator(anti_diag_end(d)));
453 }
454
455 const_reverse_anti_diag_iterator anti_diag_rend(int d=0) const
456 {
457 return (const_reverse_anti_diag_iterator(anti_diag_begin(d)));
458 }
459
462 {
463 _ncols = 0;
464 _nrows = 0;
465 }
466
467
469 mat(unsigned nrows, unsigned ncols) : _data(nrows*ncols)
470 {
471 _nrows = nrows;
472 _ncols = ncols;
473 }
474
476 mat(unsigned nrows, unsigned ncols, const T& c) :_data(nrows*ncols)
477 {
478 _nrows = nrows;
479 _ncols = ncols;
480 _data.fill(c);
481 }
482
483
486 mat(unsigned nrows, unsigned ncols, const T* marray,bool column_major=true)
488 {
489 _nrows = nrows;
490 _ncols = ncols;
491 if(column_major)
492 memcpy(_data.data(), marray, size()*sizeof(T));
493 else
494 {
495
496 for(unsigned i = 0; i < _nrows; i++)
497 for(unsigned j = 0; j < _ncols;j++)
498 {
499 operator()(i,j) = marray[i*_ncols +j];
500 }
501
502
503 }
504 }
505
506
507
509 template <typename S>
510 mat(const mat<S>& m):_data(m.size())
511 {
512 _nrows = m.nrows();
513 _ncols = m.ncols();
514 for(unsigned i = 0; i < _nrows; i++)
515 for(unsigned j = 0; j < _ncols;j++)
516 {
517 operator()(i,j)=(T)m(i,j);
518 }
519
520 }
521
523 void set_extern_data(unsigned nrows, unsigned ncols, T* data)
524 {
525 _data.set_extern_data(nrows*ncols,data);
526 _nrows = nrows;
527 _ncols = ncols;
528 }
529 void destruct()
530 {
531 _data.destruct();
532 }
534 unsigned size() const
535 {
536 return _data.size();
537 }
538
540 unsigned nrows() const
541 {
542 return _nrows;
543 }
544
546 unsigned ncols() const
547 {
548 return _ncols;
549 }
550
551
552
554 template <typename S>
556 {
557 resize(m.nrows(),m.ncols());
558 for(unsigned i = 0; i < _nrows; i++)
559 for(unsigned j = 0; j < _ncols;j++)
560 {
561 operator()(i,j)=(T)m(i,j);
562 }
563 return *this;
564 }
565
567 mat<T>& operator = (const T& s)
568 {
569 fill (s);
570 return *this;
571 }
572
574 void resize(unsigned rows, unsigned cols)
575 {
576
577 unsigned newsize = rows*cols;
578 _nrows = rows;
579 _ncols = cols;
580 _data.resize(newsize);
581 }
582
584 operator T*()
585 {
586 return (T*)_data;
587 }
588
590 operator const T*() const
591 {
592 return (const T*)_data;
593 }
594
596 bool is_square() const
597 {
598 return _ncols == _nrows;
599 }
600
602 template <typename S>
603 void fill(const S& v)
604 {
605 T val = (T)v;
606 _data.fill(val);
607 }
609 T& operator () (unsigned i, unsigned j) {
610 assert(i < _nrows && j < _ncols);
611 return _data[j*_nrows+i];
612 }
614 const T& operator () (unsigned i, unsigned j) const {
615 assert(_data.data() != NULL && i < _nrows && j < _ncols);
616 return _data[j*_nrows+i];
617 }
619 template <typename S>
620 bool operator == (const mat<S>& m) const
621 {
622 if(_ncols != m.ncols() || _nrows != m.nrows())
623 return false;
624
625 return _data == m._data;
626 }
627
629 template <typename S>
630 bool operator != (const mat<S>& m) const
631 {
632 if(_ncols != m.ncols() || _nrows != m.nrows())
633 return false;
634 return _data != m._data;
635 return false;
636 }
637
638
639 //in place scalar multiplication
640 mat<T>& operator *= (const T& s)
641 {
642 _data *= (T)s;
643 return *this;
644 }
645
647 const mat<T> operator*(const T& s) const
648 {
649 mat<T> r=(*this);
650 r*=(T)s;
651 return r;
652 }
653
655 mat<T>& operator /= (const T& s)
656 {
657 _data /= (T)s;
658 return *this;
659 }
660
662 const mat<T> operator / (const T& s) const
663 {
664 mat<T> r=(*this);
665 r/=s;
666 return r;
667 }
668
669
671 mat<T>& operator += (const T& s)
672 {
673 _data += (T)s;
674 return *this;
675 }
676
678 const mat<T> operator + (const T& s)
679 {
680 mat<T> r=(*this);
681 r+=s;
682 return r;
683 }
684
686 mat<T>& operator -= (const T& s)
687 {
688 _data -= (T)s;
689 return *this;
690 }
691
693 const mat<T> operator - (const T& s)
694 {
695 mat<T> r=(*this);
696 r-=s;
697 return r;
698 }
699
701 const mat<T> operator-() const
702 {
703 mat<T> r=(*this)*((T)-1);
704 return r;
705 }
706
708 template <typename S>
710 {
711 assert(_ncols == m.ncols() && _nrows == m.nrows());
712 _data+=m._data;
713 return *this;
714 }
715
717 template <typename S>
719 {
720 assert(_ncols == m.ncols() && _nrows == m.nrows());
721 _data-=m._data;
722 return *this;
723 }
724
725
726
727
729 template <typename S>
730 const mat<T> operator+(const mat<S> m2)const
731 {
732 mat<T> r=(*this);
733 r += m2;
734 return r;
735 }
736
738 template <typename S>
739 const mat<T> operator-(const mat<S> m2)const
740 {
741 mat<T> r=(*this);
742 r-= m2;
743 return r;
744 }
745
746
748 template <typename S>
749 const mat<T> operator*=(const mat<S>& m2)
750 {
751 assert(ncols() == m2.ncols() && nrows() == m2.nrows() && ncols() == nrows());
752 mat<T> r(_nrows,_ncols,(T)0);
753
754 for(unsigned i = 0; i < _nrows; i++)
755 for(unsigned j = 0; j < _ncols;j++)
756 for(unsigned k = 0; k < _ncols; k++)
757 r(i,j) += operator()(i,k) * (T)(m2(k,j));
758 (*this)=r;
759
760 return *this;
761 }
762
763
764
766 template <typename S>
767 const mat<T> operator*(const mat<S>& m2) const
768 {
769 assert(m2.nrows() == _ncols);
770 unsigned M = m2.ncols();
771 mat<T> r(_nrows,M,(T)0);
772 for(unsigned i = 0; i < _nrows; i++)
773 for(unsigned j = 0; j < M;j++)
774 for(unsigned k = 0; k < _ncols; k++)
775 r(i,j) += operator()(i,k) * (T)(m2(k,j));
776
777 return r;
778 }
779
780
782 template < typename S>
783 const vec<T> operator*(const vec<S>& v) const
784 {
785 assert(_ncols==v.size());
786 vec<T> r;
787 r.zeros(_nrows);
788
789 for(unsigned j = 0; j < _ncols; j++)
790 for(unsigned i = 0; i < _nrows; i++)
791 r(i) += operator()(i,j) * (T)(v(j));
792
793 return r;
794 }
795
797 mat<T> sub_mat(unsigned top, unsigned left, unsigned rows, unsigned cols) const
798 {
799
800 mat<T> mnew(rows,cols);
801
802 for(unsigned i = 0; i < rows;i++)
803 for(unsigned j = 0; j < cols;j++)
804 mnew(i,j)=operator()(i+top,j+left);
805
806 return mnew;
807 }
808
810 const vec<T> row(unsigned i) const
811 {
812
813 vec<T> mnew(_ncols);
814
815
816 for(unsigned j = 0; j < _ncols;j++)
817 mnew(j)=operator()(i,j);
818
819 return mnew;
820 }
821
823 void set_row(unsigned i,const vec<T>& v)
824 {
825
826 for(unsigned j = 0; j < _ncols;j++)
827 operator()(i,j)=v(j);
828
829
830 }
831
833 const vec<T> col(unsigned j) const
834 {
835
836 vec<T> mnew(_nrows);
837
838
839 for(unsigned i = 0; i < _nrows;i++)
840 mnew(i)=operator()(i,j);
841
842 return mnew;
843 }
844
846 void set_col(unsigned j,const vec<T>& v)
847 {
848
849 for(unsigned i = 0; i < _nrows;i++)
850 operator()(i,j)=v(i);
851 }
852
853
854
855
857 void copy(unsigned top, unsigned left, unsigned rows, unsigned cols, mat<T>& submat) const
858 {
859 assert(submat.nrows() == rows && submat.ncols() == cols);
860
861 for(unsigned i = 0; i < rows;i++)
862 for(unsigned j = 0; j < cols;j++)
863 submat(i,j)=operator()(i+top,j+left);
864
865
866 }
867
869 void paste(int top, int left,const mat<T>& m)
870 {
871 for(unsigned i = 0; i < m.nrows(); i++)
872 for(unsigned j = 0; j < m.ncols(); j++)
873 operator()(i+top,j+left)=m(i,j);
874
875 }
876
877
879 void swap_rows(unsigned i, unsigned j)
880 {
881 assert(i < _nrows && j < _nrows);
882 for(unsigned k = 0; k < _ncols;k++)
883 std::swap(operator()(i,k),operator()(j,k));
884 }
885
887 void swap_columns(unsigned i, unsigned j)
888 {
889 assert(i < _ncols && j < _ncols);
890 for(unsigned k = 0; k < _nrows;k++)
891 std::swap(operator()(k,i),operator()(k,j));
892
893 }
894
896 void swap_diagonal_elements(unsigned i, unsigned j)
897 {
898 assert(i < _ncols && j < _ncols);
899 std::swap(operator()(i,i),operator()(j,j));
900 }
901
902
903
904
906 T trace() const
907 {
908 assert(_nrows == _ncols);
909 T t = 0;
910 for(unsigned i = 0; i < _nrows;i++)
911 t+=operator()(i,i);
912 return t;
913 }
914 //return the maximum of all coefficients of the matrix
915 T maxcoeff() const
916 {
917 T t = operator()(0, 0);
918 for (unsigned i = 0; i < _nrows; i++)
919 for (unsigned j = 0; j < _ncols; j++)
920 if (t < operator()(i, j))
921 t = operator()(i, j);
922 return t;
923 }
924 //return the minimum of all coefficients of the matrix
925 T mincoeff() const
926 {
927 T t = operator()(0, 0);
928 for (unsigned i = 0; i < _nrows; i++)
929 for (unsigned j = 0; j < _ncols; j++)
930 if (t > operator()(i, j))
931 t = operator()(i, j);
932 return t;
933 }
934
937 {
939
940 for(unsigned i = 0; i < _nrows;i++)
941 for(unsigned j = 0; j < _ncols;j++)
942 r(j,i) = operator()(i,j);
943
944 *this = r;
945 }
946
947 //flip columns left-right
948 void fliplr()
949 {
951
952 for(unsigned i = 0; i < _nrows;i++)
953 for(unsigned j = 0; j < _ncols;j++)
954 r(i,j) = operator()(i,_ncols-j-1);
955
956 *this = r;
957
958 }
959
960 //flip rows up-down
961 void flipud()
962 {
963 mat<T> r(_nrows,_ncols);
964
965 for(unsigned i = 0; i < _nrows;i++)
966 for(unsigned j = 0; j < _ncols;j++)
967 r(i,j) = operator()(_nrows-i-1,j);
968
969 *this = r;
970
971 }
972
974 void ceil()
975 {
976 for(unsigned i = 0; i < _nrows;i++)
977 for(unsigned j = 0; j < _ncols;j++)
978 operator()(i,j) =::ceil(operator()(i,j));
979 }
980
982 void floor()
983 {
984 for(unsigned i = 0; i < _nrows;i++)
985 for(unsigned j = 0; j < _ncols;j++)
986 operator()(i,j) =::floor(operator()(i,j));
987 }
988
990 void round()
991 {
992 for(unsigned i = 0; i < _nrows;i++)
993 for(unsigned j = 0; j < _ncols;j++)
994 operator()(i,j) =::floor(operator()(i,j)+(T)0.5);
995
996 }
997
998
999
1002 {
1003 T n=0;
1004 for(unsigned i =0; i < _nrows;i++)
1005 for(unsigned j=0;j <_ncols;j++)
1006 n+=operator()(i,j)*operator()(i,j);
1007
1008 return (T)sqrt((double)n);
1009 }
1010
1011
1014 {
1015 assert(_ncols == _nrows);
1016 zeros();
1017 for(unsigned i = 0; i < _ncols;++i)
1018 operator()(i,i)=1;
1019 }
1020
1022 void identity(unsigned dim)
1023 {
1024 zeros(dim,dim);
1025 for(unsigned i = 0; i < _ncols;++i)
1026 operator()(i,i)=1;
1027 }
1028
1030 void zeros()
1031 {
1032 fill(0);
1033 }
1034
1036 void zeros(unsigned rows, unsigned cols)
1037 {
1038 resize(rows,cols);
1039 fill((T)0);
1040 }
1041
1043 void ones(unsigned rows, unsigned cols)
1044 {
1045 resize(rows,cols);
1046 fill((T)1);
1047 }
1048
1049
1050
1051
1052};
1053
1055#define CGV_MATH_MAT_DECLARED
1056
1057template <typename T>
1058mat<T> zeros(unsigned rows, unsigned cols)
1059{
1060 mat<T> m;
1061 m.zeros(rows,cols);
1062 return m;
1063}
1064
1065template <typename T>
1066mat<T> ones(unsigned rows, unsigned cols)
1067{
1068 mat<T> m(rows,cols);
1069 m.fill((T)1);
1070 return m;
1071}
1072
1073template<typename T>
1074mat<T> identity(unsigned dim)
1075{
1076 mat<T> m;
1077 m.identity(dim);
1078 return m;
1079}
1080
1081//return frobenius norm
1082template<typename T>
1083T frobenius_norm(const mat<T>& m)
1084{
1085 return m.frobenius_norm();
1086}
1087
1088//return trace of matrix
1089template<typename T>
1090T trace(const mat<T>& m)
1091{
1092 return m.trace();
1093}
1094
1095
1096//concatenate two matrices horizontally
1097template<typename T, typename S>
1098const mat<T> horzcat(const mat<T>& m1, const mat<S>& m2)
1099{
1100
1101 assert(m1.nrows() == m2.nrows());
1102 mat<T> r(m1.nrows(),m1.ncols()+m2.ncols());
1103 for(unsigned i = 0; i < m1.nrows();i++)
1104 {
1105 for(unsigned j = 0; j < m1.ncols(); j++)
1106 r(i,j) = m1(i,j);
1107 for(unsigned j = 0; j < m2.ncols(); j++)
1108 r(i,j+m1.ncols())=(T)m2(i,j);
1109 }
1110 return r;
1111}
1112
1113//concatenates a matrix and a column vector horizontally
1114template<typename T, typename S>
1115const mat<T> horzcat(const mat<T>& m1, const vec<S>& v)
1116{
1117
1118 assert(m1.nrows() == v.size());
1119 mat<T> r(m1.nrows(),m1.ncols()+1);
1120 for(unsigned i = 0; i < m1.nrows();i++)
1121 {
1122 for(unsigned j = 0; j < m1.ncols(); j++)
1123 r(i,j) = m1(i,j);
1124
1125 r(i,m1.ncols())=(T)v(i);
1126 }
1127 return r;
1128}
1129
1130//concatenates two vectors horizontally
1131template<typename T, typename S>
1132const mat<T> horzcat(const vec<T>& v1, const vec<S>& v2)
1133{
1134
1135 assert(v1.size() == v2.size());
1136 mat<T> r(v1.size(),2);
1137 for(unsigned i = 0; i < v1.size();i++)
1138 {
1139 r(i,0) = v1(i);
1140 r(i,1) = v2(i);
1141 }
1142 return r;
1143}
1144
1145//concatenates two column vectors vertically
1146template<typename T, typename S>
1147const vec<T> vertcat(const vec<T>& v1, const vec<S>& v2)
1148{
1149
1150 vec<T> r(v1.size()+v2.size());
1151 unsigned off = v1.size();
1152 for(unsigned i = 0; i < v1.size();i++)
1153 r(i) = v1(i);
1154 for(unsigned i = 0; i < v2.size();i++)
1155 r(i+off) = v2(i);
1156
1157 return r;
1158}
1159
1160
1161//concatenates two matrices vertically
1162template<typename T, typename S>
1163const mat<T> vertcat(const mat<T>& m1, const mat<S>& m2)
1164{
1165
1166 assert(m1.ncols() == m2.ncols());
1167 mat<T> r(m1.nrows()+m2.nrows(),m1.ncols());
1168 for(unsigned i = 0; i < m1.nrows();i++)
1169 {
1170 for(unsigned j = 0; j < m1.ncols(); j++)
1171 r(i,j) = m1(i,j);
1172 }
1173
1174 for(unsigned i = 0; i < m2.nrows();i++)
1175 {
1176 for(unsigned j = 0; j < m1.ncols(); j++)
1177 r(i+m1.nrows(),j) = m2(i,j);
1178 }
1179
1180 return r;
1181}
1182
1183
1184
1185
1186//transpose of a matrix m
1187template <typename T>
1188const mat<T> transpose(const mat<T> &m)
1189{
1190 mat<T> r = m;
1191 r.transpose();
1192 return r;
1193}
1194//transpose of a column vector
1195template <typename T>
1196const mat<T> transpose(const vec<T> &v)
1197{
1198 mat<T> r(1, v.size());
1199 for(unsigned i = 0; i < v.size(); i++)
1200 r(0,i)= v(i);
1201
1202 return r;
1203}
1204
1206template <typename T>
1207const mat<T> ceil(const mat<T> &m)
1208{
1209 mat<T> r = m;
1210 r.ceil();
1211 return r;
1212}
1213
1215template <typename T>
1216const mat<T> floor(const mat<T> &m)
1217{
1218 mat<T> r = m;
1219 r.floor();
1220 return r;
1221}
1222
1224template <typename T>
1225const mat<T> round(const mat<T> &m)
1226{
1227 mat<T> r = m;
1228 r.round();
1229 return r;
1230}
1231
1232
1233
1234
1236template <typename T>
1237mat<T> operator * (const T& s, const mat<T>& m)
1238{
1239 return m*(T)s;
1240}
1241
1242
1243
1245template <typename T>
1246std::ostream& operator<<(std::ostream& out, const mat<T>& m)
1247{
1248
1249 for (unsigned i=0;i<m.nrows();++i)
1250 {
1251 for(unsigned j =0;j < m.ncols()-1;++j)
1252 out << m(i,j)<<" ";
1253 out << m(i,m.ncols()-1);
1254 if(i != m.nrows()-1)
1255 out <<"\n";
1256 }
1257
1258 return out;
1259
1260}
1261
1262
1264template <typename T>
1265std::istream& operator>>(std::istream& in, mat<T>& m)
1266{
1267 assert(m.size() > 0);
1268 for (unsigned i=0;i<m.nrows();++i)
1269 for(unsigned j =0;j < m.ncols();++j)
1270 in >> m(i,j);
1271
1272
1273 return in;
1274
1275}
1276
1277
1278
1279
1280
1281
1282//compute transpose(A)*A
1283template <typename T>
1284void AtA(const mat<T>& a, mat<T>& ata)
1285{
1286 ata.resize(a.ncols(),a.ncols());
1287 ata.zeros();
1288 for(unsigned r = 0; r < a.nrows();r++)
1289 {
1290 for(unsigned i = 0; i < a.ncols();i++)
1291 {
1292 for(unsigned j = 0; j < a.ncols();j++)
1293 {
1294 ata(i,j)+=a(r,i)*a(r,j);
1295 }
1296 }
1297 }
1298}
1299//compute A*transpose(A)
1300template <typename T>
1301void AAt(const mat<T>& a, mat<T>& aat)
1302{
1303 aat.resize(a.nrows(),a.nrows());
1304 aat.zeros();
1305 for(unsigned c = 0; c < a.ncols();c++)
1306 {
1307 for(unsigned i = 0; i < a.nrows();i++)
1308 {
1309 for(unsigned j = 0; j < a.nrows();j++)
1310 {
1311 aat(i,j)+=a(i,c)*a(j,c);
1312 }
1313 }
1314 }
1315
1316}
1317
1318template <typename T>
1319mat<T> reshape(const vec<T>& v,unsigned r,unsigned c)
1320{
1321 assert(v.size() == r*c);
1322 return mat<T>(r,c,(const T*)v);
1323}
1324
1325template <typename T>
1326mat<T> reshape(const mat<T>& m,unsigned r,unsigned c)
1327{
1328 assert(m.size() == r*c);
1329 return mat<T>(r,c,(const T*)m);
1330}
1331
1332
1333template <typename T>
1334void AtB(const mat<T>& a,const mat<T>& b, mat<T>& atb)
1335{
1336 atb.resize(a.ncols(),b.ncols());
1337 atb.zeros();
1338
1339 for(unsigned i = 0; i < a.ncols(); i++)
1340 for(unsigned j = 0; j < b.ncols();j++)
1341 for(unsigned k = 0; k < a.nrows(); k++)
1342 atb(i,j) += a(k,i)*b(k,j);
1343
1344}
1345
1348template <typename T>
1349void Atx(const mat<T>& a,const vec<T>& x, vec<T>& atx)
1350{
1351 atx.resize(a.ncols());
1352 atx.zeros();
1353
1354 for(unsigned i = 0; i < a.ncols(); i++)
1355 for(unsigned j = 0; j < a.nrows(); j++)
1356 atx(i) += a(j,i) * (T)(x(j));
1357
1358
1359}
1360
1361
1363template < typename T, typename S>
1364mat<T> dyad(const vec<T>& v, const vec<S>& w)
1365{
1366 mat<T> m(v.size(),w.size());
1367
1368 for(unsigned i = 0; i < v.size();i++)
1369 for(unsigned j = 0; j < w.size();j++)
1370 m(i,j) =v(i)*(T)w(j);
1371
1372 return m;
1373}
1374
1375} // namespace math
1376
1379
1384
1386
1387} // namespace cgv
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
Definition mat.h:208
void copy(unsigned top, unsigned left, unsigned rows, unsigned cols, mat< T > &submat) const
copy submatrix m(top,left)...m(top+rows,left+cols) into submat
Definition mat.h:857
const mat< T > operator-() const
negation operator
Definition mat.h:701
T trace() const
returns the trace
Definition mat.h:906
unsigned ncols() const
number of columns
Definition mat.h:546
mat< T > sub_mat(unsigned top, unsigned left, unsigned rows, unsigned cols) const
create submatrix m(top,left)...m(top+rows,left+cols)
Definition mat.h:797
mat(unsigned nrows, unsigned ncols, const T *marray, bool column_major=true)
creates a matrix from an array if the matrix data is stored in a row major fashion set column_major t...
Definition mat.h:486
mat< T > & operator/=(const T &s)
in place division by a scalar
Definition mat.h:655
void set_col(unsigned j, const vec< T > &v)
set column j of the matrix to vector v
Definition mat.h:846
void identity(unsigned dim)
set dim x dim identity matrix
Definition mat.h:1022
const mat< T > operator/(const T &s) const
division by a scalar
Definition mat.h:662
const mat< T > operator*(const mat< S > &m2) const
multiplication with a ncols x M matrix m2
Definition mat.h:767
void floor()
floor all components of the matrix
Definition mat.h:982
mat()
standard constructor
Definition mat.h:461
unsigned _ncols
number of columns
Definition mat.h:213
const mat< T > operator*=(const mat< S > &m2)
in place matrix multiplication with a ncols x ncols matrix m2
Definition mat.h:749
T & operator()(unsigned i, unsigned j)
access to the element in the ith row in column j
Definition mat.h:609
bool operator!=(const mat< S > &m) const
test for inequality
Definition mat.h:630
void paste(int top, int left, const mat< T > &m)
paste matrix m at position: top, left
Definition mat.h:869
void swap_columns(unsigned i, unsigned j)
exchange column i with column j
Definition mat.h:887
mat< T > & operator+=(const T &s)
in place addition by a scalar
Definition mat.h:671
void ceil()
ceil all components of the matrix
Definition mat.h:974
mat(unsigned nrows, unsigned ncols)
constructor creates a nrows x ncols full matrix
Definition mat.h:469
void zeros(unsigned rows, unsigned cols)
resize and fill matrix with zeros
Definition mat.h:1036
vec< T > _data
pointer to data storage
Definition mat.h:211
const mat< T > operator-(const mat< S > m2) const
matrix subtraction
Definition mat.h:739
void resize(unsigned rows, unsigned cols)
resize the matrix, the content of the matrix will be destroyed
Definition mat.h:574
void identity()
set identity matrix
Definition mat.h:1013
void swap_rows(unsigned i, unsigned j)
exchange row i with row j
Definition mat.h:879
mat(unsigned nrows, unsigned ncols, const T &c)
construct a matrix with all elements set to c
Definition mat.h:476
const mat< T > operator+(const T &s)
componentwise addition of a scalar
Definition mat.h:678
void set_row(unsigned i, const vec< T > &v)
set row i of the matrix to vector v
Definition mat.h:823
void fill(const S &v)
fills all elements of the matrix with v
Definition mat.h:603
unsigned size() const
number of stored elements
Definition mat.h:534
mat< T > & operator-=(const T &s)
in place substraction of a scalar
Definition mat.h:686
const vec< T > col(unsigned j) const
extract a column of the matrix as a vector
Definition mat.h:833
void round()
round to integer
Definition mat.h:990
void ones(unsigned rows, unsigned cols)
resize and fill matrix with ones
Definition mat.h:1043
void zeros()
set zero matrix
Definition mat.h:1030
void set_extern_data(unsigned nrows, unsigned ncols, T *data)
set data pointer to an external data array
Definition mat.h:523
void swap_diagonal_elements(unsigned i, unsigned j)
exchange diagonal elements (i,i) (j,j)
Definition mat.h:896
mat< T > & operator=(const mat< S > &m)
assignment of a matrix with a different element type
Definition mat.h:555
T frobenius_norm() const
returns the frobenius norm of matrix m
Definition mat.h:1001
bool operator==(const mat< S > &m) const
test for equality
Definition mat.h:620
unsigned _nrows
number of rows
Definition mat.h:215
const mat< T > operator*(const T &s) const
scalar multiplication
Definition mat.h:647
mat(const mat< S > &m)
copy constructor for matrix with different element type
Definition mat.h:510
bool is_square() const
returns true if matrix is a square matrix
Definition mat.h:596
const mat< T > operator+(const mat< S > m2) const
matrix addition
Definition mat.h:730
void transpose()
transpose matrix
Definition mat.h:936
const vec< T > operator*(const vec< S > &v) const
matrix vector multiplication
Definition mat.h:783
unsigned nrows() const
number of rows
Definition mat.h:540
const vec< T > row(unsigned i) const
extract a row from the matrix as a vector
Definition mat.h:810
A column vector class.
Definition vec.h:28
unsigned size() const
number of elements
Definition vec.h:59
void zeros()
fill the vector with zeros
Definition vec.h:470
the cgv namespace
Definition print.h:11
cgv::math::mat< double > dmatn
declare type of matrices of varying dimensions
Definition mat.h:1383
cgv::math::mat< float > matn
declare type of matrices of varying dimensions
Definition mat.h:1381
std::ostream & operator<<(std::ostream &os, const vr_device_info &di)
stream out operator for device infos
Definition vr_info.cxx:10