GSLAM  3.0.0
Matrix.h
1 // GSLAM - A general SLAM framework and benchmark
2 // Copyright 2018 PILAB Inc. All rights reserved.
3 // https://github.com/zdzhaoyong/GSLAM
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors may be
14 // used to endorse or promote products derived from this software without
15 // specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Author: zd5945@126.com (Yong Zhao)
30 //
31 // Matrix provide basic matrix computation like Eigen
32 
33 #ifndef GSLAM_MATRIX_H
34 #define GSLAM_MATRIX_H
35 
36 #include <iostream>
37 #include <iomanip>
38 #include <string.h>
39 #include <math.h>
40 #include <array>
41 #include <limits>
42 
43 namespace GSLAM{
44 
45 template<typename Scalar, size_t Rows, size_t Cols>
46 class Matrix
47 {
48 public:
49  Scalar _data[Rows][Cols] {};
50 
51  Matrix() = default;
52 
53  Matrix(const std::array<Scalar,Rows*Cols>& c){
54  memcpy(_data, c.data(), sizeof(_data));
55  }
56 
57  Matrix(const Scalar data_[Rows*Cols])
58  {
59  memcpy(_data, data_, sizeof(_data));
60  }
61 
62  Matrix(const Scalar data_[Rows][Cols])
63  {
64  memcpy(_data, data_, sizeof(_data));
65  }
66 
67  Matrix(const Matrix &other)
68  {
69  memcpy(_data, other._data, sizeof(_data));
70  }
71 
72  static Matrix<Scalar, Rows, Cols> zeros() {
74  m.setZero();
75  return m;
76  }
77 
78  static Matrix<Scalar, Rows, Cols> ones() {
80  m.setOne();
81  return m;
82  }
83 
84  Scalar *data()
85  {
86  return _data[0];
87  }
88 
89  const Scalar *data() const
90  {
91  return _data[0];
92  }
93 
94  inline Scalar operator()(size_t i, size_t j) const
95  {
96  return _data[i][j];
97  }
98 
99  inline Scalar &operator()(size_t i, size_t j)
100  {
101  return _data[i][j];
102  }
103 
105  {
106  if (this != &other) {
107  memcpy(_data, other._data, sizeof(_data));
108  }
109  return (*this);
110  }
111 
112  void copyTo(Scalar (&dst)[Rows*Cols]) const
113  {
114  memcpy(dst, _data, sizeof(dst));
115  }
116 
117  void copyToRaw(Scalar *dst) const
118  {
119  memcpy(dst, _data, sizeof(_data));
120  }
121 
122  void copyToColumnMajor(Scalar (&dst)[Rows*Cols]) const
123  {
124  const Matrix<Scalar, Rows, Cols> &self = *this;
125 
126  for (size_t i = 0; i < Rows; i++) {
127  for (size_t j = 0; j < Cols; j++) {
128  dst[i+(j*Rows)] = self(i, j);
129  }
130  }
131  }
132 
133  template<size_t P>
134  Matrix<Scalar, Rows, P> operator*(const Matrix<Scalar, Cols, P> &other) const
135  {
136  const Matrix<Scalar, Rows, Cols> &self = *this;
138  res.setZero();
139 
140  for (size_t i = 0; i < Rows; i++) {
141  for (size_t k = 0; k < P; k++) {
142  for (size_t j = 0; j < Cols; j++) {
143  res(i, k) += self(i, j) * other(j, k);
144  }
145  }
146  }
147 
148  return res;
149  }
150 
152  {
154  const Matrix<Scalar, Rows, Cols> &self = *this;
155 
156  for (size_t i = 0; i < Rows; i++) {
157  for (size_t j = 0; j < Cols; j++) {
158  res(i, j) = self(i, j)*other(i, j);
159  }
160  }
161 
162  return res;
163  }
164 
165  Matrix<Scalar, Rows, Cols> edivide(const Matrix<Scalar, Rows, Cols> &other) const
166  {
168  const Matrix<Scalar, Rows, Cols> &self = *this;
169 
170  for (size_t i = 0; i < Rows; i++) {
171  for (size_t j = 0; j < Cols; j++) {
172  res(i, j) = self(i, j)/other(i, j);
173  }
174  }
175 
176  return res;
177  }
178 
179  Matrix<Scalar, Rows, Cols> operator+(const Matrix<Scalar, Rows, Cols> &other) const
180  {
182  const Matrix<Scalar, Rows, Cols> &self = *this;
183 
184  for (size_t i = 0; i < Rows; i++) {
185  for (size_t j = 0; j < Cols; j++) {
186  res(i, j) = self(i, j) + other(i, j);
187  }
188  }
189 
190  return res;
191  }
192 
193  Matrix<Scalar, Rows, Cols> operator-(const Matrix<Scalar, Rows, Cols> &other) const
194  {
196  const Matrix<Scalar, Rows, Cols> &self = *this;
197 
198  for (size_t i = 0; i < Rows; i++) {
199  for (size_t j = 0; j < Cols; j++) {
200  res(i, j) = self(i, j) - other(i, j);
201  }
202  }
203 
204  return res;
205  }
206 
207  Matrix<Scalar, Rows, Cols> operator-() const
208  {
210  const Matrix<Scalar, Rows, Cols> &self = *this;
211 
212  for (size_t i = 0; i < Rows; i++) {
213  for (size_t j = 0; j < Cols; j++) {
214  res(i, j) = -self(i, j);
215  }
216  }
217 
218  return res;
219  }
220 
221  void operator+=(const Matrix<Scalar, Rows, Cols> &other)
222  {
223  Matrix<Scalar, Rows, Cols> &self = *this;
224  self = self + other;
225  }
226 
227  void operator-=(const Matrix<Scalar, Rows, Cols> &other)
228  {
229  Matrix<Scalar, Rows, Cols> &self = *this;
230  self = self - other;
231  }
232 
233  template<size_t P>
234  void operator*=(const Matrix<Scalar, Cols, P> &other)
235  {
236  Matrix<Scalar, Rows, Cols> &self = *this;
237  self = self * other;
238  }
239 
240  Matrix<Scalar, Rows, Cols> operator*(Scalar scalar) const
241  {
243  const Matrix<Scalar, Rows, Cols> &self = *this;
244 
245  for (size_t i = 0; i < Rows; i++) {
246  for (size_t j = 0; j < Cols; j++) {
247  res(i, j) = self(i, j) * scalar;
248  }
249  }
250 
251  return res;
252  }
253 
254  inline Matrix<Scalar, Rows, Cols> operator/(Scalar scalar) const
255  {
256  return (*this)*(1/scalar);
257  }
258 
259  Matrix<Scalar, Rows, Cols> operator+(Scalar scalar) const
260  {
262  const Matrix<Scalar, Rows, Cols> &self = *this;
263 
264  for (size_t i = 0; i < Rows; i++) {
265  for (size_t j = 0; j < Cols; j++) {
266  res(i, j) = self(i, j) + scalar;
267  }
268  }
269 
270  return res;
271  }
272 
273  inline Matrix<Scalar, Rows, Cols> operator-(Scalar scalar) const
274  {
275  return (*this) + (-1*scalar);
276  }
277 
278  void operator*=(Scalar scalar)
279  {
280  Matrix<Scalar, Rows, Cols> &self = *this;
281 
282  for (size_t i = 0; i < Rows; i++) {
283  for (size_t j = 0; j < Cols; j++) {
284  self(i, j) = self(i, j) * scalar;
285  }
286  }
287  }
288 
289  void operator/=(Scalar scalar)
290  {
291  Matrix<Scalar, Rows, Cols> &self = *this;
292  self = self * (1.0f / scalar);
293  }
294 
295  inline void operator+=(Scalar scalar)
296  {
297  *this = (*this) + scalar;
298  }
299 
300  inline void operator-=(Scalar scalar)
301  {
302  *this = (*this) - scalar;
303  }
304 
305  bool operator==(const Matrix<Scalar, Rows, Cols> &other) const
306  {
307  const Matrix<Scalar, Rows, Cols> &self = *this;
308 
309  // TODO: set this based on Type
310  static constexpr Scalar eps = std::numeric_limits<Scalar>::epsilon();
311 
312  for (size_t i = 0; i < Rows; i++) {
313  for (size_t j = 0; j < Cols; j++) {
314  if (fabs(self(i, j) - other(i, j)) > eps) {
315  return false;
316  }
317  }
318  }
319 
320  return true;
321  }
322 
323  bool operator!=(const Matrix<Scalar, Rows, Cols> &other) const
324  {
325  const Matrix<Scalar, Rows, Cols> &self = *this;
326  return !(self == other);
327  }
328 
329  bool equal(const Matrix<Scalar, Rows, Cols> &y, const Scalar eps=1e-4f) {
330  for (size_t i = 0; i < Rows; i++) {
331  for (size_t j = 0; j < Cols; j++) {
332  if (fabs((*this)(i, j) - y(i, j)) > eps) {
333  return false;
334  }
335  }
336  }
337  return true;
338  }
339 
340  Matrix<Scalar, Cols, Rows> transpose() const
341  {
343  const Matrix<Scalar, Rows, Cols> &self = *this;
344 
345  for (size_t i = 0; i < Rows; i++) {
346  for (size_t j = 0; j < Cols; j++) {
347  res(j, i) = self(i, j);
348  }
349  }
350 
351  return res;
352  }
353 
354  // tranpose alias
355  inline Matrix<Scalar, Cols, Rows> T() const
356  {
357  return transpose();
358  }
359 
360  template<size_t P, size_t Q>
361  Matrix<Scalar, P, Q> slice(size_t x0, size_t y0) const
362  {
363  Matrix<Scalar, P, Q> res(&(_data[x0][y0]));
364  return res;
365  }
366 
367  template<size_t P, size_t Q>
368  void set(const Matrix<Scalar, P, Q> &m, size_t x0, size_t y0)
369  {
370  Matrix<Scalar, Rows, Cols> &self = *this;
371  for (size_t i = 0; i < P; i++) {
372  for (size_t j = 0; j < Q; j++) {
373  self(i + x0, j + y0) = m(i, j);
374  }
375  }
376  }
377 
378  void setRow(size_t i, const Matrix<Scalar, Cols, 1> &row)
379  {
380  Matrix<Scalar, Rows, Cols> &self = *this;
381  for (size_t j = 0; j < Cols; j++) {
382  self(i, j) = row(j, 0);
383  }
384  }
385 
386  void setCol(size_t j, const Matrix<Scalar, Rows, 1> &col)
387  {
388  Matrix<Scalar, Rows, Cols> &self = *this;
389  for (size_t i = 0; i < Rows; i++) {
390  self(i, j) = col(i, 0);
391  }
392  }
393 
394  void setZero()
395  {
396  memset(_data, 0, sizeof(_data));
397  }
398 
399  inline void zero()
400  {
401  setZero();
402  }
403 
404  void setAll(Scalar val)
405  {
406  Matrix<Scalar, Rows, Cols> &self = *this;
407 
408  for (size_t i = 0; i < Rows; i++) {
409  for (size_t j = 0; j < Cols; j++) {
410  self(i, j) = val;
411  }
412  }
413  }
414 
415  inline void setOne()
416  {
417  setAll(1);
418  }
419 
420  void setIdentity()
421  {
422  setZero();
423  Matrix<Scalar, Rows, Cols> &self = *this;
424 
425  for (size_t i = 0; i < Rows && i < Cols; i++) {
426  self(i, i) = 1;
427  }
428  }
429 
430  inline void identity()
431  {
432  setIdentity();
433  }
434 
435  inline void swapRows(size_t a, size_t b)
436  {
437  if (a == b) {
438  return;
439  }
440 
441  Matrix<Scalar, Rows, Cols> &self = *this;
442 
443  for (size_t j = 0; j < Cols; j++) {
444  Scalar tmp = self(a, j);
445  self(a, j) = self(b, j);
446  self(b, j) = tmp;
447  }
448  }
449 
450  inline void swapCols(size_t a, size_t b)
451  {
452  if (a == b) {
453  return;
454  }
455 
456  Matrix<Scalar, Rows, Cols> &self = *this;
457 
458  for (size_t i = 0; i < Rows; i++) {
459  Scalar tmp = self(i, a);
460  self(i, a) = self(i, b);
461  self(i, b) = tmp;
462  }
463  }
464 
465  Matrix<Scalar, Rows, Cols> abs() const
466  {
468  for (size_t i=0; i<Rows; i++) {
469  for (size_t j=0; j<Cols; j++) {
470  r(i,j) = Scalar(fabs((*this)(i,j)));
471  }
472  }
473  return r;
474  }
475 
476  Scalar max() const
477  {
478  Scalar max_val = (*this)(0,0);
479  for (size_t i=0; i<Rows; i++) {
480  for (size_t j=0; j<Cols; j++) {
481  Scalar val = (*this)(i,j);
482  if (val > max_val) {
483  max_val = val;
484  }
485  }
486  }
487  return max_val;
488  }
489 
490  Scalar min() const
491  {
492  Scalar min_val = (*this)(0,0);
493  for (size_t i=0; i<Rows; i++) {
494  for (size_t j=0; j<Cols; j++) {
495  Scalar val = (*this)(i,j);
496  if (val < min_val) {
497  min_val = val;
498  }
499  }
500  }
501  return min_val;
502  }
503 
504  int rows() const {return Rows;}
505 
506  int cols() const {return Cols;}
507 
508 #ifdef EIGEN_MATRIX_H
509  operator Eigen::Matrix<Scalar,Rows,Cols,Eigen::ColMajor>()
510  {
511  return Eigen::Map<Eigen::Matrix<Scalar,Rows,Cols,Eigen::RowMajor> >(_data[0]);
512  }
513 
514  Matrix(const Eigen::Matrix<Scalar,Rows,Cols,Eigen::ColMajor>& eigen)
515  {
516  Eigen::Matrix<Scalar,Rows,Cols,Eigen::RowMajor> rowM=eigen;
517  memcpy(_data,rowM.data(),sizeof(_data));
518  }
519 
520  Matrix(const Eigen::Matrix<Scalar,Rows,Cols,Eigen::RowMajor>& eigen)
521  {
522  memcpy(_data,eigen.data(),sizeof(_data));
523  }
524 #endif
525 
526 };
527 template<typename Scalar,size_t Rows,size_t Cols>
528 std::ostream& operator<<(std::ostream& os,const Matrix<Scalar, Rows, Cols>& matrix)
529 {
530  os.precision(6);
531  for (size_t i = 0; i < Rows; ++i) {
532  for (size_t j = 0; j < Cols; ++j) {
533  os << std::setw(9)
534  << matrix(i, j)
535  << ((j<Cols-1)?" ":"\n");
536  }
537  }
538  return os;
539 }
540 
541 template<typename Scalar, size_t Rows, size_t Cols>
542 Matrix<Scalar, Rows, Cols> operator*(Scalar scalar, const Matrix<Scalar, Rows, Cols> &other)
543 {
544  return other * scalar;
545 }
546 
547 template<typename Scalar, size_t Rows>
548 class Vector : public Matrix<Scalar, Rows, 1>
549 {
550 public:
552 
553  Vector() = default;
554 
555  Vector(const MatrixM1 & other) :
556  MatrixM1(other)
557  {
558  }
559 
560  Vector(const Scalar data_[Rows]) :
561  MatrixM1(data_)
562  {
563  }
564 
565  inline Scalar operator()(size_t i) const
566  {
567  const MatrixM1 &v = *this;
568  return v(i, 0);
569  }
570 
571  inline Scalar &operator()(size_t i)
572  {
573  MatrixM1 &v = *this;
574  return v(i, 0);
575  }
576 
577  inline Scalar operator[](size_t i) const
578  {
579  const MatrixM1 &v = *this;
580  return v(i, 0);
581  }
582 
583  inline Scalar &operator[](size_t i)
584  {
585  MatrixM1 &v = *this;
586  return v(i, 0);
587  }
588 
589  Scalar dot(const MatrixM1 & b) const {
590  const Vector &a(*this);
591  Scalar r = 0;
592  for (size_t i = 0; i<Rows; i++) {
593  r += a(i)*b(i,0);
594  }
595  return r;
596  }
597 
598  inline Scalar operator*(const MatrixM1 & b) const {
599  const Vector &a(*this);
600  return a.dot(b);
601  }
602 
603  inline Vector operator*(Scalar b) const {
604  return Vector(MatrixM1::operator*(b));
605  }
606 
607  Scalar norm() const {
608  const Vector &a(*this);
609  return Scalar(sqrt(a.dot(a)));
610  }
611 
612  Scalar norm_squared() const {
613  const Vector &a(*this);
614  return a.dot(a);
615  }
616 
617  inline Scalar length() const {
618  return norm();
619  }
620 
621  inline void normalize() {
622  (*this) /= norm();
623  }
624 
625  Vector unit() const {
626  return (*this) / norm();
627  }
628 
629  Vector unit_or_zero(const Scalar eps = Scalar(1e-5)) {
630  const Scalar n = norm();
631  if (n > eps) {
632  return (*this) / n;
633  }
634  return Vector();
635  }
636 
637  inline Vector normalized() const {
638  return unit();
639  }
640 
641  Vector pow(Scalar v) const {
642  const Vector &a(*this);
643  Vector r;
644  for (size_t i = 0; i<Rows; i++) {
645  r(i) = Scalar(::pow(a(i), v));
646  }
647  return r;
648  }
649 };
650 
651 template<typename Scalar>
652 class Vector2 : public Vector<Scalar, 2>
653 {
654 public:
655 
657  typedef Vector<Scalar, 3> Vector3;
658 
659  Vector2() = default;
660 
661  Vector2(const Matrix21 & other) :
662  Vector<Scalar, 2>(other)
663  {
664  }
665 
666  Vector2(const Scalar data_[2]) :
667  Vector<Scalar, 2>(data_)
668  {
669  }
670 
671  Vector2(Scalar x, Scalar y)
672  {
673  Vector2 &v(*this);
674  v(0) = x;
675  v(1) = y;
676  }
677 
678  explicit Vector2(const Vector3 & other)
679  {
680  Vector2 &v(*this);
681  v(0) = other(0);
682  v(1) = other(1);
683  }
684 
685  Scalar cross(const Matrix21 & b) const {
686  const Vector2 &a(*this);
687  return a(0)*b(1, 0) - a(1)*b(0, 0);
688  }
689 
690  Scalar operator^(const Matrix21 & b) const {
691  return (*this).cross(b);
692  }
693 
694 };
695 
696 template<typename Scalar>
697 class Vector3 : public Vector<Scalar, 3>
698 {
699 public:
700 
702 
703  Vector3() = default;
704 
705  Vector3(const Matrix31 & other) :
706  Vector<Scalar, 3>(other)
707  {
708  }
709 
710  Vector3(const Scalar data_[3]) :
711  Vector<Scalar, 3>(data_)
712  {
713  }
714 
715  Vector3(Scalar x, Scalar y, Scalar z) {
716  Vector3 &v(*this);
717  v(0) = x;
718  v(1) = y;
719  v(2) = z;
720  }
721 
722  Vector3 cross(const Matrix31 & b) const {
723  const Vector3 &a(*this);
724  Vector3 c;
725  c(0) = a(1)*b(2,0) - a(2)*b(1,0);
726  c(1) = -a(0)*b(2,0) + a(2)*b(0,0);
727  c(2) = a(0)*b(1,0) - a(1)*b(0,0);
728  return c;
729  }
730 
731  inline Vector3 operator+(Vector3 other) const
732  {
733  return Matrix31::operator+(other);
734  }
735 
736  inline Vector3 operator-(Vector3 other) const
737  {
738  return Matrix31::operator-(other);
739  }
740 
741  inline Vector3 operator-() const
742  {
743  return Matrix31::operator-();
744  }
745 
746  inline Vector3 operator*(Scalar scalar) const
747  {
748  return Matrix31::operator*(scalar);
749  }
750 
751  inline Scalar operator*(Vector3 b) const
752  {
754  }
755 
756  inline Vector3 operator^(const Matrix31 & b) const {
757  return (*this).cross(b);
758  }
759 
760  /**
761  * Override vector ops so Vector3 type is returned
762  */
763  inline Vector3 unit() const {
765  }
766 
767  inline Vector3 normalized() const {
768  return unit();
769  }
770 
771 
772  Matrix<Scalar,3,3> hat() const {
773  const Vector3 &v(*this);
775  A(0,0) = 0;
776  A(0,1) = -v(2);
777  A(0,2) = v(1);
778  A(1,0) = v(2);
779  A(1,1) = 0;
780  A(1,2) = -v(0);
781  A(2,0) = -v(1);
782  A(2,1) = v(0);
783  A(2,2) = 0;
784  return A;
785  }
786 
787 };
788 
789 typedef Vector2<float> Vector2f;
790 typedef Vector2<float> Vector3f;
791 typedef Vector<float,4> Vector4f;
792 typedef Vector<float,5> Vector5f;
793 typedef Vector<float,6> Vector6f;
794 typedef Vector2<double> Vector2d;
795 typedef Vector3<double> Vector3d;
796 typedef Vector<double,4> Vector4d;
797 typedef Vector<double,5> Vector5d;
798 typedef Vector<double,6> Vector6d;
799 
806 
807 }
808 
809 #endif
Definition: Matrix.h:697
Definition: Matrix.h:652
Definition: Camera.h:45
Definition: Matrix.h:46
Definition: Matrix.h:548
Vector3 unit() const
Override vector ops so Vector3 type is returned.
Definition: Matrix.h:763