Matrix.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2015 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2015 Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef MIRTK_Matrix_H
22 #define MIRTK_Matrix_H
23 
24 #include "mirtk/Object.h"
25 
26 #include "mirtk/Math.h"
27 #include "mirtk/Array.h"
28 #include "mirtk/Pair.h"
29 #include "mirtk/Indent.h"
30 #include "mirtk/Cfstream.h"
31 #include "mirtk/Matrix3x3.h"
32 
33 
34 namespace mirtk {
35 
36 
37 // Forward declarations to reduce cyclic header dependencies
38 class PointSet;
39 class Vector;
40 
41 
42 /**
43  * Dense matrix
44  *
45  * \sa SparseMatrix
46  */
47 
48 class Matrix : public Object
49 {
50  mirtkObjectMacro(Matrix);
51 
52  // ---------------------------------------------------------------------------
53  // Types
54 public:
55 
56  typedef double ElementType;
57 
58  // ---------------------------------------------------------------------------
59  // Attributes
60 protected:
61 
62  /// Number of rows
63  int _rows;
64 
65  /// Number of colums
66  int _cols;
67 
68  /// Matrix values
69  double **_matrix;
70 
71  /// Whether this instance owns the memory of the matrix elements
72  bool _owner;
73 
74  // ---------------------------------------------------------------------------
75  // Construction/destruction
76 public:
77 
78  /// Default constructor
79  Matrix();
80 
81  /// Constructor for given number of rows and columns
82  Matrix(int, int = -1, double * = NULL);
83 
84  /// Convert column vector to matrix
85  Matrix(const Vector &);
86 
87  /// Convert point set to (n x 3) or (n x 2) matrix
88  ///
89  /// \param[in] twoD Discard z coordinate.
90  Matrix(const PointSet &, bool twoD = false);
91 
92  /// Copy constructor
93  Matrix(const Matrix &);
94 
95  /// Construct from 3x3 matrix
96  explicit Matrix(const Matrix3x3 &);
97 
98  /// Destructor
99  ~Matrix();
100 
101  /// Assign scalar value to all elements
102  Matrix& operator =(double);
103 
104  /// Assignment operator
105  Matrix& operator =(const Matrix &);
106 
107  /// Assignment operator
108  Matrix& operator =(const Matrix3x3 &);
109 
110  /// Initialize matrix with number of rows and columns
111  void Initialize(int, int = -1, double * = NULL);
112 
113  /// Resize matrix preserving existing entries
114  void Resize(int, int = -1);
115 
116  /// Free memory
117  void Clear();
118 
119  /// Set elements to zero
120  void Zero();
121 
122  // ---------------------------------------------------------------------------
123  // Indexing
124 
125  /// Get number of elements
126  int NumberOfElements() const;
127 
128  /// Get matrix size in each dimension
129  Pair<int, int> Size() const;
130 
131  /// Get number of rows
132  int Rows() const;
133 
134  /// Get number of columns
135  int Cols() const;
136 
137  /// Get linear index of element given its row and column indices
138  int Index(int, int) const;
139 
140  /// Get row index of element given its linear index
141  int RowIndex(int) const;
142 
143  /// Get column index of element given its linear index
144  int ColIndex(int) const;
145 
146  /// Get row and column index of element given its linear index
147  void SubIndex(int, int &, int &) const;
148 
149  /// Get row and column index of element given its linear index
150  Pair<int, int> SubIndex(int) const;
151 
152  // ---------------------------------------------------------------------------
153  // Element access
154 
155  /// Get pointer to linear memory which stores matrix elements in column-major order
156  double *RawPointer(int r = 0, int c = 0);
157 
158  /// Get pointer to linear memory which stores matrix elements in column-major order
159  const double *RawPointer(int r = 0, int c = 0) const;
160 
161  /// Get pointer to linear memory which stores matrix elements in column-major order
162  /// \deprecated Use RawPointer instead.
163  double *GetPointerToElements(int r = 0, int c = 0);
164 
165  /// Get pointer to linear memory which stores matrix elements in column-major order
166  /// \deprecated Use RawPointer instead.
167  const double *GetPointerToElements(int r = 0, int c = 0) const;
168 
169  /// Get pointer to matrix entries in specified column
170  double *Col(int c);
171 
172  /// Get pointer to matrix entries in specified column
173  const double *Col(int c) const;
174 
175  /// Get reference to element with specified linear index
176  double &operator ()(int);
177 
178  /// Get const reference to element with specified linear index
179  const double &operator ()(int) const;
180 
181  /// Get reference to element in specified row and column
182  double &operator ()(int, int);
183 
184  /// Get const reference to element in specified row and column
185  const double &operator ()(int, int) const;
186 
187  /// Set value of element with specified linear index
188  void Put(int, double);
189 
190  /// Get value of element with specified linear index
191  double Get(int) const;
192 
193  /// Set value of element in specified row and column
194  void Put(int, int, double);
195 
196  /// Get value of element in specified row and column
197  double Get(int, int) const;
198 
199  /// Get submatrix
200  Matrix operator ()(int, int, int, int) const;
201 
202  /// Set submatrix
203  void operator ()(Matrix &, int, int);
204 
205  // ---------------------------------------------------------------------------
206  // Scalar matrix operations
207 
208  /// Add scalar to values in specified row
209  Matrix &AddToRow(int, double);
210 
211  /// Add scalar to values in specified column
212  Matrix &AddToCol(int, double);
213 
214  /// Scale row by a scalar
215  Matrix &ScaleRow(int, double);
216 
217  /// Scale column by a scalar
218  Matrix &ScaleCol(int, double);
219 
220  /// Subtraction of a double
221  Matrix &operator -=(double);
222 
223  /// Addition of a double
224  Matrix &operator +=(double);
225 
226  /// Multiplication with a double
227  Matrix &operator *=(double);
228 
229  /// Division by a double
230  Matrix &operator /=(double);
231 
232  /// Return result of subtraction of a double
233  Matrix operator -(double) const;
234 
235  /// Return result of addition of a double
236  Matrix operator +(double) const;
237 
238  /// Return result of multiplication with a double
239  Matrix operator *(double) const;
240 
241  /// Return result of division by a double
242  Matrix operator /(double) const;
243 
244  // ---------------------------------------------------------------------------
245  // Matrix-vector operations
246 
247  /// Right-multiply matrix with vector
248  Vector operator* (const Vector&) const;
249 
250  // ---------------------------------------------------------------------------
251  // Matrix-matrix operations
252 
253  /// Matrix subtraction operator
254  Matrix& operator -=(const Matrix&);
255 
256  /// Matrix addition operator
257  Matrix& operator +=(const Matrix&);
258 
259  /// Matrix multiplication operator
260  Matrix& operator *=(const Matrix&);
261 
262  /// Return result of matrix subtraction
263  Matrix operator -(const Matrix&) const;
264 
265  /// Return result of matrix addition
266  Matrix operator +(const Matrix&) const;
267 
268  /// Return result of matrix multiplication
269  Matrix operator *(const Matrix&) const;
270 
271  // ---------------------------------------------------------------------------
272  // Comparison operations
273 
274  /// Matrix equality
275  bool operator ==(const Matrix &) const;
276 
277  /// Matrix inequality
278  bool operator !=(const Matrix &) const;
279 
280  /// Find elements with specific value
281  /// \returns Sorted linear indices of found elements
282  Array<int> operator ==(double) const;
283 
284  /// Find elements with value not equal to specified value
285  /// \returns Sorted linear indices of found elements
286  Array<int> operator !=(double) const;
287 
288  /// Find elements with value less than specified value
289  /// \returns Sorted linear indices of found elements
290  Array<int> operator <(double) const;
291 
292  /// Find elements with value less or equal than specified value
293  /// \returns Sorted linear indices of found elements
294  Array<int> operator <=(double) const;
295 
296  /// Find elements with value greater than specified value
297  /// \returns Sorted linear indices of found elements
298  Array<int> operator >(double) const;
299 
300  /// Find elements with value greater or equal than specified value
301  /// \returns Sorted linear indices of found elements
302  Array<int> operator >=(double) const;
303 
304  // ---------------------------------------------------------------------------
305  // Matrix functions
306 
307  /// Minimum value in specified row
308  double RowMin(int) const;
309 
310  /// Maximum value in specified row
311  double RowMax(int) const;
312 
313  /// Minimum and maximum value in specified row
314  void RowRange(int, double &, double &) const;
315 
316  /// Sum of column values in specified row
317  double RowSum(int) const;
318 
319  /// Mean of column values in specified row
320  double RowMean(int) const;
321 
322  /// Variance of column values in specified row
323  double RowVar(int) const;
324 
325  /// Standard deviation of column values in specified row
326  double RowStd(int) const;
327 
328  /// Minimum value in specified column
329  double ColMin(int) const;
330 
331  /// Maximum value in specified column
332  double ColMax(int) const;
333 
334  /// Minimum and maximum value in specified column
335  void ColRange(int, double &, double &) const;
336 
337  /// Sum of row values in specified column
338  double ColSum(int) const;
339 
340  /// Mean of row values in specified column
341  double ColMean(int) const;
342 
343  /// Variance of row values in specified column
344  double ColVar(int) const;
345 
346  /// Standard deviation of row values in specified column
347  double ColStd(int) const;
348 
349  /// Matrix exponential via Pade approximation
350  /// (cf. Golub and Van Loan, Matrix Computations, Algorithm 11.3-1)
351  Matrix Exp() const;
352 
353  /// Matrix logarithm
354  Matrix Log() const;
355 
356  /// Matrix square root
357  Matrix Sqrt() const;
358 
359  /// Calculate norm of matrix
360  double Norm() const;
361 
362  /// Calculate trace of matrix
363  double Trace() const;
364 
365  // The infinity norm is the maximum of the absolute value row sums.
366  double InfinityNorm() const;
367 
368  /// Calculate determinant of matrix
369  double Det() const;
370 
371  /// Calculate determinant of a 3x3 matrix
372  double Det3x3() const;
373 
374  /// Get upper left 3x3 sub-matrix
375  Matrix3x3 To3x3() const;
376 
377  /// Set to identity matrix
378  Matrix &Ident();
379 
380  /// Returns true if the matrix is an identity matrix.
381  bool IsIdentity() const;
382 
383  /// Whether matrix is square
384  bool IsSquare() const;
385 
386  /// Whether matrix is symmetric
387  bool IsSymmetric() const;
388 
389  /// Whether matrix is diagonalizable
390  bool IsDiagonalizable() const;
391 
392  /// Make square matrix symmetric by adding its transpose and divide by 2
393  void MakeSymmetric();
394 
395  /// Invert matrix
396  Matrix &Invert(bool use_svd_if_singular = true);
397 
398  /// Get inverse matrix
399  Matrix Inverse(bool use_svd_if_singular = true) const;
400 
401  /// Invert (singular) matrix using SVD
402  Matrix &SVDInvert();
403 
404  /// Get inverse of (singular) matrix using SVD
405  Matrix SVDInverse() const;
406 
407  /// Invert matrix using pseudo inverse
408  Matrix &PseudoInvert();
409 
410  /// Get pseudo inverse of matrix
411  Matrix PseudoInverse() const;
412 
413  /// Matrix inversion operator
414  Matrix operator !();
415 
416  /// Adjugate matrix and return determinant
417  Matrix &Adjugate(double &);
418 
419  /// Transpose matrix
420  Matrix &Transpose();
421 
422  /// Get transposed matrix
423  Matrix Transposed() const;
424 
425  /// Matrix transpose operator
426  Matrix operator ~();
427 
428  /// Permute rows
429  Matrix &PermuteRows(Array<int>);
430 
431  /// Permute columns
432  Matrix &PermuteCols(Array<int>);
433 
434  /// Calculate LU decomposition of square matrix
435  void LU(Matrix &, Matrix &, double &) const;
436 
437  /// Calculate singular value decomposition
438  void SVD(Matrix &, Vector &, Matrix &) const;
439 
440  /// Calculate eigenvalues and eigenvectors of matrix
441  ///
442  /// This function chooses the appropriate algorithm
443  /// according to matrix properties.
444  ///
445  /// \returns Whether eigenvalue decomposition exists.
446  /// If \c false, squared singular values are returned.
447  bool Eigenvalues(Matrix &, Vector &, Matrix &) const;
448 
449  /// Calculate eigendecomposition of symmetric matrix
450  void SymmetricEigen(Matrix &, Vector &) const;
451 
452  /// Calculate least square fit via SVD
453  void LeastSquaresFit(const Vector &, Vector &) const;
454 
455  // ---------------------------------------------------------------------------
456  // I/O
457 
458  /// Interface to output stream
459  friend ostream& operator<< (ostream&, const Matrix&);
460 
461  /// Interface to input stream
462  friend istream& operator>> (istream&, Matrix&);
463 
464  /// Interface to output stream
465  friend Cofstream& operator<< (Cofstream&, const Matrix&);
466 
467  /// Interface to input stream
469 
470  /// Print matrix
471  void Print(Indent = 0) const;
472 
473  /// Print matrix
474  void Print(ostream &, Indent = 0) const;
475 
476  /// Read matrix from file
477  void Read(const char *);
478 
479  /// Write matrix to file
480  void Write(const char *) const;
481 
482  /// Import matrix from text file (requires no. of expected rows and cols)
483  void Import(const char *, int, int);
484 
485  /// Write dense matrix to MAT-file
486  ///
487  /// \note Use only when MIRTK_Numerics_WITH_MATLAB is 1.
488  bool WriteMAT(const char *, const char * = "A") const;
489 
490 };
491 
492 
493 } // namespace mirtk
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 // Inline definitions
497 ////////////////////////////////////////////////////////////////////////////////
498 
499 #include "mirtk/Point.h"
500 
501 
502 namespace mirtk {
503 
504 // =============================================================================
505 // Construction
506 // =============================================================================
507 
508 // -----------------------------------------------------------------------------
509 inline Matrix::Matrix(const Matrix3x3 &m)
510 :
511  _rows(3),
512  _cols(3),
513  _owner(true)
514 {
515  Allocate(_matrix, 3, 3);
516  for (int c = 0; c < 3; ++c)
517  for (int r = 0; r < 3; ++r) {
518  _matrix[c][r] = m[r][c];
519  }
520 }
521 
522 // -----------------------------------------------------------------------------
523 inline Matrix &Matrix::operator =(const Matrix3x3 &m)
524 {
525  if (_rows != 3 || _cols != 3) {
526  Clear();
527  Allocate(_matrix, 3, 3);
528  _rows = _cols = 3;
529  _owner = true;
530  }
531  for (int c = 0; c < 3; ++c)
532  for (int r = 0; r < 3; ++r) {
533  _matrix[c][r] = m[r][c];
534  }
535  return *this;
536 }
537 
538 // =============================================================================
539 // Indexing
540 // =============================================================================
541 
542 // -----------------------------------------------------------------------------
543 inline int Matrix::NumberOfElements() const
544 {
545  return _rows * _cols;
546 }
547 
548 // -----------------------------------------------------------------------------
549 inline Pair<int, int> Matrix::Size() const
550 {
551  return MakePair(_rows, _cols);
552 }
553 
554 // -----------------------------------------------------------------------------
555 inline int Matrix::Rows() const
556 {
557  return _rows;
558 }
559 
560 // -----------------------------------------------------------------------------
561 inline int Matrix::Cols() const
562 {
563  return _cols;
564 }
565 
566 // -----------------------------------------------------------------------------
567 inline int Matrix::Index(int r, int c) const
568 {
569  return c * _cols + r;
570 }
571 
572 // -----------------------------------------------------------------------------
573 inline int Matrix::RowIndex(int i) const
574 {
575  return i % _cols;
576 }
577 
578 // -----------------------------------------------------------------------------
579 inline int Matrix::ColIndex(int i) const
580 {
581  return i / _cols;
582 }
583 
584 // -----------------------------------------------------------------------------
585 inline void Matrix::SubIndex(int i, int &r, int &c) const
586 {
587  r = RowIndex(i);
588  c = ColIndex(i);
589 }
590 
591 // -----------------------------------------------------------------------------
592 inline Pair<int, int> Matrix::SubIndex(int i) const
593 {
594  return MakePair(RowIndex(i), ColIndex(i));
595 }
596 
597 // =============================================================================
598 // Element access
599 // =============================================================================
600 
601 // -----------------------------------------------------------------------------
602 inline double *Matrix::RawPointer(int r, int c)
603 {
604  return &_matrix[c][r];
605 }
606 
607 // -----------------------------------------------------------------------------
608 inline const double *Matrix::RawPointer(int r, int c) const
609 {
610  return &_matrix[c][r];
611 }
612 
613 // -----------------------------------------------------------------------------
614 inline double *Matrix::GetPointerToElements(int r, int c)
615 {
616  return &_matrix[c][r];
617 }
618 
619 // -----------------------------------------------------------------------------
620 inline const double *Matrix::GetPointerToElements(int r, int c) const
621 {
622  return &_matrix[c][r];
623 }
624 
625 // -----------------------------------------------------------------------------
626 inline double *Matrix::Col(int c)
627 {
628  return _matrix[c];
629 }
630 
631 // -----------------------------------------------------------------------------
632 inline const double *Matrix::Col(int c) const
633 {
634  return _matrix[c];
635 }
636 
637 // -----------------------------------------------------------------------------
638 inline double &Matrix::operator()(int i)
639 {
640  return _matrix[0][i];
641 }
642 
643 // -----------------------------------------------------------------------------
644 inline const double &Matrix::operator()(int i) const
645 {
646  return const_cast<const double &>(const_cast<Matrix *>(this)->operator()(i));
647 }
648 
649 // -----------------------------------------------------------------------------
650 inline double &Matrix::operator()(int r, int c)
651 {
652  return _matrix[c][r];
653 }
654 
655 // -----------------------------------------------------------------------------
656 inline const double &Matrix::operator()(int r, int c) const
657 {
658  return const_cast<const double &>(const_cast<Matrix *>(this)->operator()(r, c));
659 }
660 
661 // -----------------------------------------------------------------------------
662 inline void Matrix::Put(int i, double v)
663 {
664  this->operator()(i) = v;
665 }
666 
667 // -----------------------------------------------------------------------------
668 inline double Matrix::Get(int i) const
669 {
670  return this->operator()(i);
671 }
672 
673 // -----------------------------------------------------------------------------
674 inline void Matrix::Put(int r, int c, double v)
675 {
676  this->operator()(r, c) = v;
677 }
678 
679 // -----------------------------------------------------------------------------
680 inline double Matrix::Get(int r, int c) const
681 {
682  return this->operator()(r, c);
683 }
684 
685 // -----------------------------------------------------------------------------
686 inline Matrix3x3 Matrix::To3x3() const
687 {
688  Matrix3x3 m;
689  for (int r = 0; r < 3; ++r) {
690  if (r < _rows) {
691  for (int c = 0; c < 3; ++c) {
692  if (c < _cols) {
693  m[r][c] = _matrix[c][r];
694  } else {
695  m[r][c] = 0.;
696  }
697  }
698  } else {
699  memset(m[r], 0, 3 * sizeof(double));
700  }
701  }
702  return m;
703 }
704 
705 // =============================================================================
706 // Scalar matrix operations
707 // =============================================================================
708 
709 // -----------------------------------------------------------------------------
710 inline Matrix &Matrix::AddToRow(int r, double s)
711 {
712  for (int c = 0; c < _cols; ++c) _matrix[c][r] += s;
713  return *this;
714 }
715 
716 // -----------------------------------------------------------------------------
717 inline Matrix &Matrix::AddToCol(int c, double s)
718 {
719  for (int r = 0; r < _rows; ++r) _matrix[c][r] += s;
720  return *this;
721 }
722 
723 // -----------------------------------------------------------------------------
724 inline Matrix &Matrix::ScaleRow(int r, double s)
725 {
726  for (int c = 0; c < _cols; ++c) _matrix[c][r] *= s;
727  return *this;
728 }
729 
730 // -----------------------------------------------------------------------------
731 inline Matrix &Matrix::ScaleCol(int c, double s)
732 {
733  for (int r = 0; r < _rows; ++r) _matrix[c][r] *= s;
734  return *this;
735 }
736 
737 // -----------------------------------------------------------------------------
738 inline Matrix &Matrix::operator =(double s)
739 {
740  const int n = this->NumberOfElements();
741  double *p = this->RawPointer();
742  for (int i = 0; i < n; ++i, ++p) (*p) = s;
743  return *this;
744 }
745 
746 // -----------------------------------------------------------------------------
747 inline Matrix &Matrix::operator -=(double x)
748 {
749  const int n = this->NumberOfElements();
750  double *p = this->RawPointer();
751  for (int i = 0; i < n; ++i, ++p) (*p) -= x;
752  return *this;
753 }
754 
755 // -----------------------------------------------------------------------------
756 inline Matrix &Matrix::operator +=(double x)
757 {
758  const int n = this->NumberOfElements();
759  double *p = this->RawPointer();
760  for (int i = 0; i < n; ++i, ++p) (*p) += x;
761  return *this;
762 }
763 
764 // -----------------------------------------------------------------------------
765 inline Matrix &Matrix::operator *=(double x)
766 {
767  const int n = this->NumberOfElements();
768  double *p = this->RawPointer();
769  for (int i = 0; i < n; ++i, ++p) (*p) *= x;
770  return *this;
771 }
772 
773 // -----------------------------------------------------------------------------
774 inline Matrix &Matrix::operator /=(double x)
775 {
776  const int n = this->NumberOfElements();
777  double *p = this->RawPointer();
778  for (int i = 0; i < n; ++i, ++p) (*p) /= x;
779  return *this;
780 }
781 
782 // -----------------------------------------------------------------------------
783 inline Matrix Matrix::operator -(double x) const
784 {
785  return Matrix(*this) -= x;
786 }
787 
788 // -----------------------------------------------------------------------------
789 inline Matrix Matrix::operator +(double x) const
790 {
791  return Matrix(*this) += x;
792 }
793 
794 // -----------------------------------------------------------------------------
795 inline Matrix Matrix::operator *(double x) const
796 {
797  return Matrix(*this) *= x;
798 }
799 
800 // -----------------------------------------------------------------------------
801 inline Matrix Matrix::operator /(double x) const
802 {
803  return Matrix(*this) /= x;
804 }
805 
806 // =============================================================================
807 // Comparison operations
808 // =============================================================================
809 
810 // -----------------------------------------------------------------------------
811 inline bool Matrix::operator ==(const Matrix &m) const
812 {
813  if ((m._rows != _rows) || (m._cols != _cols)) return false;
814  const int n = this->NumberOfElements();
815  const double *ptr1 = m . RawPointer();
816  const double *ptr2 = this->RawPointer();
817  for (int i = 0; i < n; ++i, ++ptr1, ++ptr2) {
818  if (!fequal(*ptr2, *ptr1)) return false;
819  }
820  return true;
821 }
822 
823 // -----------------------------------------------------------------------------
824 inline bool Matrix::operator !=(const Matrix &m) const
825 {
826  return !(*this == m);
827 }
828 
829 // -----------------------------------------------------------------------------
830 inline Array<int> Matrix::operator ==(double x) const
831 {
832  Array<int> idx;
833  const int n = this->NumberOfElements();
834  const double *p = this->RawPointer();
835  for (int i = 0; i < n; ++i, ++p) {
836  if (*p == x) idx.push_back(i);
837  }
838  return idx;
839 }
840 
841 // -----------------------------------------------------------------------------
842 inline Array<int> Matrix::operator !=(double x) const
843 {
844  Array<int> idx;
845  const int n = this->NumberOfElements();
846  const double *p = this->RawPointer();
847  for (int i = 0; i < n; ++i, ++p) {
848  if (*p != x) idx.push_back(i);
849  }
850  return idx;
851 }
852 
853 // -----------------------------------------------------------------------------
854 inline Array<int> Matrix::operator <(double x) const
855 {
856  Array<int> idx;
857  const int n = this->NumberOfElements();
858  const double *p = this->RawPointer();
859  for (int i = 0; i < n; ++i, ++p) {
860  if (*p < x) idx.push_back(i);
861  }
862  return idx;
863 }
864 
865 // -----------------------------------------------------------------------------
866 inline Array<int> Matrix::operator <=(double x) const
867 {
868  Array<int> idx;
869  const int n = this->NumberOfElements();
870  const double *p = this->RawPointer();
871  for (int i = 0; i < n; ++i, ++p) {
872  if (*p <= x) idx.push_back(i);
873  }
874  return idx;
875 }
876 
877 // -----------------------------------------------------------------------------
878 inline Array<int> Matrix::operator >(double x) const
879 {
880  Array<int> idx;
881  const int n = this->NumberOfElements();
882  const double *p = this->RawPointer();
883  for (int i = 0; i < n; ++i, ++p) {
884  if (*p > x) idx.push_back(i);
885  }
886  return idx;
887 }
888 
889 // -----------------------------------------------------------------------------
890 inline Array<int> Matrix::operator >=(double x) const
891 {
892  Array<int> idx;
893  const int n = this->NumberOfElements();
894  const double *p = this->RawPointer();
895  for (int i = 0; i < n; ++i, ++p) {
896  if (*p >= x) idx.push_back(i);
897  }
898  return idx;
899 }
900 
901 // =============================================================================
902 // Matrix functions
903 // =============================================================================
904 
905 // -----------------------------------------------------------------------------
906 inline double Matrix::RowMin(int r) const
907 {
908  if (_rows == 0) return .0;
909  double v = _matrix[0][r];
910  for (int c = 1; c < _cols; ++c) v = min(v, _matrix[c][r]);
911  return v;
912 }
913 
914 // -----------------------------------------------------------------------------
915 inline double Matrix::RowMax(int r) const
916 {
917  if (_rows == 0) return .0;
918  double v = _matrix[0][r];
919  for (int c = 1; c < _cols; ++c) v = max(v, _matrix[c][r]);
920  return v;
921 }
922 
923 // -----------------------------------------------------------------------------
924 inline void Matrix::RowRange(int r, double &v1, double &v2) const
925 {
926  if (_rows > 0) {
927  v1 = v2 = _matrix[0][r];
928  for (int c = 1; c < _cols; ++c) {
929  const double &v = _matrix[c][r];
930  v1 = min(v1, v), v2 = max(v2, v);
931  }
932  } else {
933  v1 = v2 = .0;
934  }
935 }
936 
937 // -----------------------------------------------------------------------------
938 inline double Matrix::ColMin(int c) const
939 {
940  if (_cols == 0) return .0;
941  double v = _matrix[c][0];
942  for (int r = 1; r < _rows; ++r) v = min(v, _matrix[c][r]);
943  return v;
944 }
945 
946 // -----------------------------------------------------------------------------
947 inline double Matrix::ColMax(int c) const
948 {
949  if (_cols == 0) return .0;
950  double v = _matrix[c][0];
951  for (int r = 1; r < _rows; ++r) v = min(v, _matrix[c][r]);
952  return v;
953 }
954 
955 // -----------------------------------------------------------------------------
956 inline void Matrix::ColRange(int c, double &v1, double &v2) const
957 {
958  if (_cols > 0) {
959  v1 = v2 = _matrix[c][0];
960  for (int r = 1; r < _rows; ++r) {
961  const double &v = _matrix[c][r];
962  v1 = min(v1, v), v2 = max(v2, v);
963  }
964  } else {
965  v1 = v2 = .0;
966  }
967 }
968 
969 // -----------------------------------------------------------------------------
970 inline double Matrix::Trace() const
971 {
972  if (_rows == _cols) {
973  double trace = 0;
974  for (int j = 0; j < _cols; ++j)
975  for (int i = 0; i < _rows; ++i) {
976  trace += _matrix[j][i];
977  }
978  return trace;
979  } else {
980  cerr << "Matrix::Trace() matrix number of col != row" << endl;
981  return 0;
982  }
983 }
984 
985 // -----------------------------------------------------------------------------
986 inline double Matrix::Norm() const
987 {
988  int i, j;
989  double norm = 0;
990 
991  // The norm of a matrix M is defined as trace(M * M~)
992  for (j = 0; j < _cols; j++) {
993  for (i = 0; i < _rows; i++) {
994  norm += _matrix[j][i]*_matrix[j][i];
995  }
996  }
997  return sqrt(norm);
998 }
999 
1000 // -----------------------------------------------------------------------------
1001 inline double Matrix::InfinityNorm() const
1002 {
1003  int i, j;
1004  double normInf = -1.0 * DBL_MAX;
1005  double sum;
1006 
1007  for (i = 0; i < _rows; ++i) {
1008  sum = 0;
1009  for (j = 0; j < _cols; ++j) {
1010  sum += abs(_matrix[j][i]);
1011  }
1012  if (sum > normInf)
1013  normInf = sum;
1014  }
1015  return normInf;
1016 }
1017 
1018 // -----------------------------------------------------------------------------
1019 inline double Matrix::Det3x3() const
1020 {
1021  return _matrix[0][0] * (_matrix[1][1] * _matrix[2][2] - _matrix[1][2] * _matrix[2][1])
1022  - _matrix[0][1] * (_matrix[1][0] * _matrix[2][2] - _matrix[1][2] * _matrix[2][0])
1023  + _matrix[0][2] * (_matrix[1][0] * _matrix[2][1] - _matrix[1][1] * _matrix[2][0]);
1024 }
1025 
1026 // -----------------------------------------------------------------------------
1027 inline Matrix Matrix::Inverse(bool use_svd_if_singular) const
1028 {
1029  return Matrix(*this).Invert(use_svd_if_singular);
1030 }
1031 
1032 // -----------------------------------------------------------------------------
1034 {
1035  return Matrix(*this).SVDInvert();
1036 }
1037 
1038 // -----------------------------------------------------------------------------
1040 {
1041  return Matrix(*this).PseudoInvert();
1042 }
1043 
1044 // -----------------------------------------------------------------------------
1046 {
1047  return Inverse();
1048 }
1049 
1050 // -----------------------------------------------------------------------------
1052 {
1053  return Matrix(*this).Transpose();
1054 }
1055 
1056 // -----------------------------------------------------------------------------
1058 {
1059  return Matrix(*this).Transpose();
1060 }
1061 
1062 // =============================================================================
1063 // Backwards compatibility
1064 // =============================================================================
1065 
1066 // -----------------------------------------------------------------------------
1067 inline Matrix expm(const Matrix &m)
1068 {
1069  return m.Exp();
1070 }
1071 
1072 // -----------------------------------------------------------------------------
1073 inline Matrix logm(const Matrix &m)
1074 {
1075  return m.Log();
1076 }
1077 
1078 // -----------------------------------------------------------------------------
1079 inline Matrix sqrtm(const Matrix &m)
1080 {
1081  return m.Sqrt();
1082 }
1083 
1084 ////////////////////////////////////////////////////////////////////////////////
1085 // Conversion to CUDA vector types
1086 ////////////////////////////////////////////////////////////////////////////////
1087 
1088 // -----------------------------------------------------------------------------
1089 // Construct float3x3 matrix from upper left 3x3 sub-matrix of Matrix
1090 MIRTKCU_HOST_API inline float3x3 make_float3x3(const Matrix &m)
1091 {
1092  float3x3 f;
1093  f.a = make_float3(m(0, 0), m(0, 1), m(0, 2));
1094  f.b = make_float3(m(1, 0), m(1, 1), m(1, 2));
1095  f.c = make_float3(m(2, 0), m(2, 1), m(2, 2));
1096  return f;
1097 }
1098 
1099 // -----------------------------------------------------------------------------
1100 // Construct float3x4 matrix from upper left 3x4 sub-matrix of Matrix
1101 MIRTKCU_HOST_API inline float3x4 make_float3x4(const Matrix &m)
1102 {
1103  float3x4 f;
1104  f.a = make_float4(m(0, 0), m(0, 1), m(0, 2), m(0, 3));
1105  f.b = make_float4(m(1, 0), m(1, 1), m(1, 2), m(1, 3));
1106  f.c = make_float4(m(2, 0), m(2, 1), m(2, 2), m(2, 3));
1107  return f;
1108 }
1109 
1110 // -----------------------------------------------------------------------------
1111 // Construct float4x4 matrix from upper left 4x4 sub-matrix of Matrix
1112 MIRTKCU_HOST_API inline float4x4 make_float4x4(const Matrix &m)
1113 {
1114  float4x4 d;
1115  d.a = make_float4(m(0, 0), m(0, 1), m(0, 2), m(0, 3));
1116  d.b = make_float4(m(1, 0), m(1, 1), m(1, 2), m(1, 3));
1117  d.c = make_float4(m(2, 0), m(2, 1), m(2, 2), m(2, 3));
1118  d.d = make_float4(m(3, 0), m(3, 1), m(3, 2), m(3, 3));
1119  return d;
1120 }
1121 
1122 // -----------------------------------------------------------------------------
1123 // Construct double3x3 matrix from upper left 3x3 sub-matrix of Matrix
1124 MIRTKCU_HOST_API inline double3x3 make_double3x3(const Matrix &m)
1125 {
1126  double3x3 d;
1127  d.a = make_double3(m(0, 0), m(0, 1), m(0, 2));
1128  d.b = make_double3(m(1, 0), m(1, 1), m(1, 2));
1129  d.c = make_double3(m(2, 0), m(2, 1), m(2, 2));
1130  return d;
1131 }
1132 
1133 // -----------------------------------------------------------------------------
1134 // Construct double3x4 matrix from upper left 3x4 sub-matrix of Matrix
1135 MIRTKCU_HOST_API inline double3x4 make_double3x4(const Matrix &m)
1136 {
1137  double3x4 d;
1138  d.a = make_double4(m(0, 0), m(0, 1), m(0, 2), m(0, 3));
1139  d.b = make_double4(m(1, 0), m(1, 1), m(1, 2), m(1, 3));
1140  d.c = make_double4(m(2, 0), m(2, 1), m(2, 2), m(2, 3));
1141  return d;
1142 }
1143 
1144 // -----------------------------------------------------------------------------
1145 // Construct double4x4 matrix from upper left 4x4 sub-matrix of Matrix
1146 MIRTKCU_HOST_API inline double4x4 make_double4x4(const Matrix &m)
1147 {
1148  double4x4 d;
1149  d.a = make_double4(m(0, 0), m(0, 1), m(0, 2), m(0, 3));
1150  d.b = make_double4(m(1, 0), m(1, 1), m(1, 2), m(1, 3));
1151  d.c = make_double4(m(2, 0), m(2, 1), m(2, 2), m(2, 3));
1152  d.d = make_double4(m(3, 0), m(3, 1), m(3, 2), m(3, 3));
1153  return d;
1154 }
1155 
1156 ////////////////////////////////////////////////////////////////////////////////
1157 // Means on Lie groups of transformation matrices
1158 ////////////////////////////////////////////////////////////////////////////////
1159 
1160 /// Compute log-Euclidean mean of transformation matrices
1161 ///
1162 /// \f[
1163 /// mu = \exp\left( \sum w_i \log\left( matrices_i \right) \right)
1164 /// \f]
1165 ///
1166 /// \param[in] n Number of matrices.
1167 /// \param[in] matrices Transformation matrices.
1168 /// \param[in] weights Weights of transformation matrices.
1169 /// Uniform weighting if \c NULL.
1170 ///
1171 /// \return Mean transformation matrix.
1172 Matrix LogEuclideanMean(int n, const Matrix *matrices, const double *weights = NULL);
1173 
1174 /// Compute exponential barycenter / bi-invariant mean of transformation matrices
1175 ///
1176 /// This function finds the exponential barycenter of a set of rigid/affine
1177 /// transformation matrices using a fixed point iteration (Gauss-Newton;
1178 /// Barycentric fixed point iteration on Lie groups).
1179 ///
1180 /// \f[
1181 /// mu_{t+1} = mu_t \exp\left( \sum w_i \log\left( mu_t^{-1} matrices_i \right) \right)
1182 /// \f]
1183 ///
1184 /// \see Arsigny and Pennec, Exponential Barycenters of the Canonical Cartan
1185 /// Connection and Invariant Means on Lie Groups,
1186 /// Matrix Information Geometry (2012)
1187 ///
1188 /// \param[in] n Number of matrices.
1189 /// \param[in] matrices Transformation matrices.
1190 /// \param[in] weights Weights of transformation matrices.
1191 /// Uniform weighting if \c NULL.
1192 /// \param[in] niter Maximum number of fixed point iterations.
1193 /// \param[in] tol Tolerance of residual infinity norm.
1194 /// \param[in] mu0 Start value of fixed point iteration.
1195 /// First matrix if \c NULL.
1196 ///
1197 /// \return Mean transformation matrix.
1198 Matrix BiInvariantMean(int n, const Matrix *matrices,
1199  const double *weights = NULL,
1200  int niter = 20, double tol = 1e-12,
1201  const Matrix *mu0 = NULL);
1202 
1203 // -----------------------------------------------------------------------------
1204 /// \deprecated Use BiInvariantMean instead
1205 inline Matrix FrechetMean(const Matrix *matrices, const double *weights, int n,
1206  int niter = 20, double tol = 1e-12,
1207  const Matrix *mu0 = NULL)
1208 {
1209  return BiInvariantMean(n, matrices, weights, niter, tol, mu0);
1210 }
1211 
1212 // -----------------------------------------------------------------------------
1213 /// \deprecated Use BiInvariantMean instead
1214 inline Matrix FrechetMean(const Matrix *matrices, int n,
1215  int niter = 20, double tol = 1e-12,
1216  const Matrix *mu0 = NULL)
1217 {
1218  return BiInvariantMean(n, matrices, NULL, niter, tol, mu0);
1219 }
1220 
1221 ////////////////////////////////////////////////////////////////////////////////
1222 // Affine transformation matrices
1223 ////////////////////////////////////////////////////////////////////////////////
1224 
1225 /// Muliply point by homogeneous transformation matrix
1226 inline void Transform(const Matrix &m, double x, double y, double z,
1227  double &mx, double &my, double &mz)
1228 {
1229  mx = m(0, 0) * x + m(0, 1) * y + m(0, 2) * z + m(0, 3);
1230  my = m(1, 0) * x + m(1, 1) * y + m(1, 2) * z + m(1, 3);
1231  mz = m(2, 0) * x + m(2, 1) * y + m(2, 2) * z + m(2, 3);
1232 }
1233 
1234 /// Muliply point by homogeneous transformation matrix
1235 inline void Transform(const Matrix &m, double &x, double &y, double &z)
1236 {
1237  Transform(m, x, y, z, x, y, z);
1238 }
1239 
1240 /// Muliply point by homogeneous transformation matrix
1241 inline Point Transform(const Matrix &m, const Point &p)
1242 {
1243  Point p2;
1244  Transform(m, p._x, p._y, p._z, p2._x, p2._y, p2._z);
1245  return p2;
1246 }
1247 
1248 /// Muliply vector by 3x3 transformation matrix
1249 inline void TransformVector(const Matrix &m, double x, double y, double z,
1250  double &mx, double &my, double &mz)
1251 {
1252  mx = m(0, 0) * x + m(0, 1) * y + m(0, 2) * z;
1253  my = m(1, 0) * x + m(1, 1) * y + m(1, 2) * z;
1254  mz = m(2, 0) * x + m(2, 1) * y + m(2, 2) * z;
1255 }
1256 
1257 /// Muliply vector by 3x3 transformation matrix
1258 inline void TransformVector(const Matrix &m, double &x, double &y, double &z)
1259 {
1260  TransformVector(m, x, y, z, x, y, z);
1261 }
1262 
1263 /// Muliply vector by 3x3 transformation matrix
1264 inline void TransformVector(const Matrix &m, Vector &v)
1265 {
1266  TransformVector(m, v(0), v(1), v(2));
1267 }
1268 
1269 /// Muliply vector by 3x3 transformation matrix
1270 inline Vector TransformVector(const Matrix &m, const Vector &v)
1271 {
1272  Vector u(v);
1273  TransformVector(m, u);
1274  return u;
1275 }
1276 
1277 /// Construct 4x4 homogeneous coordinate transformation matrix from rigid
1278 /// transformation parameters. The output transformation matrix is the
1279 /// composition of a rotation followed by a translation, i.e.,
1280 ///
1281 /// T = Translate * Rotate, where Rotate = (Rz Ry Rx)^T
1282 ///
1283 /// \note This overloaded function is mainly used by the linear transformation
1284 /// classes such as in particular irtkRigidTransformation as these
1285 /// store the cosine and sine values of the rotation angles as members.
1286 ///
1287 /// \param[in] tx Translation along x axis.
1288 /// \param[in] ty Translation along y axis.
1289 /// \param[in] tz Translation along z axis.
1290 /// \param[in] cosrx Cosine of rotation around x axis in radians.
1291 /// \param[in] cosry Cosine of rotation around y axis in radians.
1292 /// \param[in] cosrz Cosine of rotation around z axis in radians.
1293 /// \param[in] sinrx Sine of rotation around x axis in radians.
1294 /// \param[in] sinry Sine of rotation around y axis in radians.
1295 /// \param[in] sinrz Sine of rotation around z axis in radians.
1296 /// \param[out] m Homogeneous transformation matrix.
1297 void RigidParametersToMatrix(double tx, double ty, double tz,
1298  double cosrx, double cosry, double cosrz,
1299  double sinrx, double sinry, double sinrz,
1300  Matrix &m);
1301 
1302 /// Construct 4x4 homogeneous coordinate transformation matrix from rigid
1303 /// transformation parameters. The output transformation matrix is the
1304 /// composition of a rotation followed by a translation, i.e.,
1305 ///
1306 /// T = Translate * Rotate
1307 ///
1308 /// \param[in] tx Translation along x axis.
1309 /// \param[in] ty Translation along y axis.
1310 /// \param[in] tz Translation along z axis.
1311 /// \param[in] rx Rotation around x axis in radians.
1312 /// \param[in] ry Rotation around y axis in radians.
1313 /// \param[in] rz Rotation around z axis in radians.
1314 /// \param[out] m Homogeneous transformation matrix.
1315 void RigidParametersToMatrix(double tx, double ty, double tz,
1316  double rx, double ry, double rz, Matrix &m);
1317 
1318 /// Construct 4x4 homogeneous coordinate transformation matrix from rigid
1319 /// transformation parameters. The output transformation matrix is the
1320 /// composition of a rotation followed by a translation, i.e.,
1321 ///
1322 /// T = Translate * Rotate, where Rotate = (Rz Ry Rx)^T
1323 ///
1324 /// \param[in] tx Translation along x axis.
1325 /// \param[in] ty Translation along y axis.
1326 /// \param[in] tz Translation along z axis.
1327 /// \param[in] rx Rotation around x axis in radians.
1328 /// \param[in] ry Rotation around y axis in radians.
1329 /// \param[in] rz Rotation around z axis in radians.
1330 ///
1331 /// \returns Homogeneous transformation matrix.
1332 inline Matrix RigidParametersToMatrix(double tx, double ty, double tz,
1333  double rx, double ry, double rz)
1334 {
1335  Matrix m;
1336  RigidParametersToMatrix(tx, ty, tz, rx, ry, rz, m);
1337  return m;
1338 }
1339 
1340 /// Extract Euler angles from 4x4 homogeneous coordinate transformation matrix.
1341 /// The input transformation matrix is assumed to be the composition of a
1342 /// rotation followed by a translation, i.e.,
1343 ///
1344 /// T = Translate * Rotate, where Rotate = (Rz Ry Rx)^T
1345 ///
1346 /// \param[in] m Homogeneous coordinate transformation matrix.
1347 /// \param[out] rx Rotation around x axis in radians.
1348 /// \param[out] ry Rotation around y axis in radians.
1349 /// \param[out] rz Rotation around z axis in radians.
1350 void MatrixToEulerAngles(const Matrix &m,
1351  double &rx, double &ry, double &rz);
1352 
1353 /// Extract rigid transformation parameters from 4x4 homogeneous coordinate
1354 /// transformation matrix. The input transformation matrix is assumed to be
1355 /// the composition of a rotation followed by a translation, i.e.,
1356 ///
1357 /// T = Translate * Rotate, where Rotate = (Rz Ry Rx)^T
1358 ///
1359 /// \param[in] m Homogeneous coordinate transformation matrix.
1360 /// \param[out] tx Translation along x axis.
1361 /// \param[out] ty Translation along y axis.
1362 /// \param[out] tz Translation along z axis.
1363 /// \param[out] rx Rotation around x axis in radians.
1364 /// \param[out] ry Rotation around y axis in radians.
1365 /// \param[out] rz Rotation around z axis in radians.
1366 void MatrixToRigidParameters(const Matrix &m,
1367  double &tx, double &ty, double &tz,
1368  double &rx, double &ry, double &rz);
1369 
1370 /// Construct 4x4 homogeneous coordinate transformation matrix from affine
1371 /// transformation parameters. The output transformation matrix is the
1372 /// composition of a shearing, followed by a scaling, followed by a
1373 /// rotation, followed by a translation, i.e.,
1374 ///
1375 /// T = Translate * Rotate * Scale * Shear, where Rotate = (Rz Ry Rx)^T
1376 ///
1377 /// \param[in] tx Translation along x axis.
1378 /// \param[in] ty Translation along y axis.
1379 /// \param[in] tz Translation along z axis.
1380 /// \param[in] rx Rotation around x axis in radians.
1381 /// \param[in] ry Rotation around y axis in radians.
1382 /// \param[in] rz Rotation around z axis in radians.
1383 /// \param[in] sx Scaling of x axis (factor, not percentage).
1384 /// \param[in] sy Scaling of y axis (factor, not percentage).
1385 /// \param[in] sz Scaling of z axis (factor, not percentage).
1386 /// \param[in] sxy Skew between x and y axes in radians.
1387 /// \param[in] sxz Skew between x and z axes in radians.
1388 /// \param[in] syz Skew between y and z axes in radians.
1389 /// \param[out] m Homogeneous transformation matrix.
1390 void AffineParametersToMatrix(double tx, double ty, double tz,
1391  double rx, double ry, double rz,
1392  double sx, double sy, double sz,
1393  double sxy, double sxz, double syz, Matrix &m);
1394 
1395 /// Construct 4x4 homogeneous coordinate transformation matrix from affine
1396 /// transformation parameters. The output transformation matrix is the
1397 /// composition a scaling, followed by a rotation, followed by a translation, i.e.,
1398 ///
1399 /// T = Translate * Rotate * Scale, where Rotate = (Rz Ry Rx)^T
1400 ///
1401 /// \param[in] tx Translation along x axis.
1402 /// \param[in] ty Translation along y axis.
1403 /// \param[in] tz Translation along z axis.
1404 /// \param[in] rx Rotation around x axis in radians.
1405 /// \param[in] ry Rotation around y axis in radians.
1406 /// \param[in] rz Rotation around z axis in radians.
1407 /// \param[in] sx Scaling of x axis (factor, not percentage).
1408 /// \param[in] sy Scaling of y axis (factor, not percentage).
1409 /// \param[in] sz Scaling of z axis (factor, not percentage).
1410 /// \param[in] sxy Skew between x and y axes in radians.
1411 /// \param[in] sxz Skew between x and z axes in radians.
1412 /// \param[in] syz Skew between y and z axes in radians.
1413 ///
1414 /// \returns Homogeneous transformation matrix.
1415 inline Matrix AffineParametersToMatrix(double tx, double ty, double tz,
1416  double rx, double ry, double rz,
1417  double sx, double sy, double sz,
1418  double sxy, double sxz, double syz)
1419 {
1420  Matrix m(4, 4);
1421  AffineParametersToMatrix(tx, ty, tz, rx, ry, rz, sx, sy, sz, sxy, sxz, syz, m);
1422  return m;
1423 }
1424 
1425 /// Construct 4x4 homogeneous coordinate transformation matrix from affine
1426 /// transformation parameters. The output transformation matrix is the
1427 /// composition a scaling, followed by a rotation, followed by a translation, i.e.,
1428 ///
1429 /// T = Translate * Rotate * Scale, where Rotate = (Rz Ry Rx)^T
1430 ///
1431 /// \param[in] tx Translation along x axis.
1432 /// \param[in] ty Translation along y axis.
1433 /// \param[in] tz Translation along z axis.
1434 /// \param[in] rx Rotation around x axis in radians.
1435 /// \param[in] ry Rotation around y axis in radians.
1436 /// \param[in] rz Rotation around z axis in radians.
1437 /// \param[in] sx Scaling of x axis (factor, not percentage).
1438 /// \param[in] sy Scaling of y axis (factor, not percentage).
1439 /// \param[in] sz Scaling of z axis (factor, not percentage).
1440 /// \param[out] m Homogeneous transformation matrix.
1441 inline void AffineParametersToMatrix(double tx, double ty, double tz,
1442  double rx, double ry, double rz,
1443  double sx, double sy, double sz, Matrix &m)
1444 {
1445  AffineParametersToMatrix(tx, ty, tz, rx, ry, rz, sx, sy, sz, .0, .0, .0, m);
1446 }
1447 
1448 /// Construct 4x4 homogeneous coordinate transformation matrix from affine
1449 /// transformation parameters. The output transformation matrix is the
1450 /// composition a scaling, followed by a rotation, followed by a translation, i.e.,
1451 ///
1452 /// T = Translate * Rotate * Scale, where Rotate = (Rz Ry Rx)^T
1453 ///
1454 /// \param[in] tx Translation along x axis.
1455 /// \param[in] ty Translation along y axis.
1456 /// \param[in] tz Translation along z axis.
1457 /// \param[in] rx Rotation around x axis in radians.
1458 /// \param[in] ry Rotation around y axis in radians.
1459 /// \param[in] rz Rotation around z axis in radians.
1460 /// \param[in] sx Scaling of x axis (factor, not percentage).
1461 /// \param[in] sy Scaling of y axis (factor, not percentage).
1462 /// \param[in] sz Scaling of z axis (factor, not percentage).
1463 ///
1464 /// \returns Homogeneous transformation matrix.
1465 inline Matrix AffineParametersToMatrix(double tx, double ty, double tz,
1466  double rx, double ry, double rz,
1467  double sx, double sy, double sz)
1468 {
1469  Matrix m(4, 4);
1470  AffineParametersToMatrix(tx, ty, tz, rx, ry, rz, sx, sy, sz, .0, .0, .0, m);
1471  return m;
1472 }
1473 
1474 /// Extract affine transformation parameters from 4x4 homogeneous coordinate
1475 /// transformation matrix. The input transformation matrix is assumed to be
1476 /// the composition of a shearing, followed by a scaling, followed by a
1477 /// rotation, followed by a translation, i.e.,
1478 ///
1479 /// T = Translate * Rotate * Scale * Shear, where Rotate = (Rz Ry Rx)^T
1480 ///
1481 /// @sa Graphicx Gems II, with a 12 DoF model without perspective distortion
1482 /// https://github.com/erich666/GraphicsGems/blob/master/gemsii/unmatrix.c
1483 ///
1484 /// \param[in] m Homogeneous coordinate transformation matrix.
1485 /// \param[out] tx Translation along x axis.
1486 /// \param[out] ty Translation along y axis.
1487 /// \param[out] tz Translation along z axis.
1488 /// \param[out] rx Rotation around x axis in radians.
1489 /// \param[out] ry Rotation around y axis in radians.
1490 /// \param[out] rz Rotation around z axis in radians.
1491 /// \param[out] sx Scaling of x axis (factor, not percentage).
1492 /// \param[out] sy Scaling of y axis (factor, not percentage).
1493 /// \param[out] sz Scaling of z axis (factor, not percentage).
1494 /// \param[out] sxy Skew between x and y axes in radians.
1495 /// \param[out] sxz Skew between x and z axes in radians.
1496 /// \param[out] syz Skew between y and z axes in radians.
1497 void MatrixToAffineParameters(const Matrix &m,
1498  double &tx, double &ty, double &tz,
1499  double &rx, double &ry, double &rz,
1500  double &sx, double &sy, double &sz,
1501  double &sxy, double &sxz, double &syz);
1502 
1503 /// Find affine transformation matrix which minimizes the mean squared distance
1504 /// between two given sets of corresponding points (e.g., landmarks, fiducial markers)
1505 ///
1506 /// \param[in] target (Transformed) Target point set.
1507 /// \param[in] source Fixed source point set.
1508 /// \param[in] weight Weight of corresponding point pair. All correspondences
1509 /// are weighted equally if vector is empty.
1510 ///
1511 /// \returns Homogeneous transformation matrix of the target points.
1513  const PointSet &source,
1514  const Vector &weight);
1515 
1516 /// Find affine transformation matrix which minimizes the mean squared distance
1517 /// between two given sets of corresponding points (e.g., landmarks, fiducial markers)
1518 ///
1519 /// \param[in] target (Transformed) Target point set.
1520 /// \param[in] source Fixed source point set.
1521 ///
1522 /// \returns Homogeneous transformation matrix of the target points.
1524  const PointSet &source);
1525 
1526 /// Orthonormalize upper 3x3 matrix using stabilized Gram-Schmidt
1527 void OrthoNormalize3x3(Matrix &);
1528 
1529 
1530 } // namespace mirtk
1531 
1532 #endif // MIRTK_Matrix_H
void RowRange(int, double &, double &) const
Minimum and maximum value in specified row.
Definition: Matrix.h:924
double & operator()(int)
Get reference to element with specified linear index.
Definition: Matrix.h:638
void Resize(int, int=-1)
Resize matrix preserving existing entries.
bool Eigenvalues(Matrix &, Vector &, Matrix &) const
bool IsSquare() const
Whether matrix is square.
bool operator!=(const Matrix &) const
Matrix inequality.
Definition: Matrix.h:824
int NumberOfElements() const
Get number of elements.
Definition: Matrix.h:543
Matrix operator/(double) const
Return result of division by a double.
Definition: Matrix.h:801
Matrix & Adjugate(double &)
Adjugate matrix and return determinant.
double Get(int) const
Get value of element with specified linear index.
Definition: Matrix.h:668
Matrix & ScaleRow(int, double)
Scale row by a scalar.
Definition: Matrix.h:724
int _rows
Number of rows.
Definition: Matrix.h:63
Matrix operator!()
Matrix inversion operator.
Definition: Matrix.h:1045
double Trace() const
Calculate trace of matrix.
Definition: Matrix.h:970
void SubIndex(int, int &, int &) const
Get row and column index of element given its linear index.
Definition: Matrix.h:585
void MatrixToEulerAngles(const Matrix &m, double &rx, double &ry, double &rz)
bool IsIdentity() const
Returns true if the matrix is an identity matrix.
~Matrix()
Destructor.
Matrix PseudoInverse() const
Get pseudo inverse of matrix.
Definition: Matrix.h:1039
double Det() const
Calculate determinant of matrix.
void LeastSquaresFit(const Vector &, Vector &) const
Calculate least square fit via SVD.
void MatrixToRigidParameters(const Matrix &m, double &tx, double &ty, double &tz, double &rx, double &ry, double &rz)
3x4 single-precision coordinate transformation matrix
Definition: Math.h:329
4x4 single-precision matrix
Definition: Math.h:306
Matrix Sqrt() const
Matrix square root.
double Det3x3() const
Calculate determinant of a 3x3 matrix.
Definition: Matrix.h:1019
Matrix LogEuclideanMean(int n, const Matrix *matrices, const double *weights=NULL)
double * Col(int c)
Get pointer to matrix entries in specified column.
Definition: Matrix.h:626
void MatrixToAffineParameters(const Matrix &m, double &tx, double &ty, double &tz, double &rx, double &ry, double &rz, double &sx, double &sy, double &sz, double &sxy, double &sxz, double &syz)
void Read(const char *)
Read matrix from file.
void Zero()
Set elements to zero.
double ColMax(int) const
Maximum value in specified column.
Definition: Matrix.h:947
double RowMax(int) const
Maximum value in specified row.
Definition: Matrix.h:915
bool IsSymmetric() const
Whether matrix is symmetric.
double _x
x coordinate of Point
Definition: Point.h:46
3x3 double-precision matrix
Definition: Math.h:375
Matrix ApproximateAffineMatrix(const PointSet &target, const PointSet &source, const Vector &weight)
void SymmetricEigen(Matrix &, Vector &) const
Calculate eigendecomposition of symmetric matrix.
void Allocate(Type *&matrix, int n)
Allocate 1D array.
Definition: Allocate.h:62
void RigidParametersToMatrix(double tx, double ty, double tz, double cosrx, double cosry, double cosrz, double sinrx, double sinry, double sinrz, Matrix &m)
double Norm() const
Calculate norm of matrix.
Definition: Matrix.h:986
Matrix & PermuteCols(Array< int >)
Permute columns.
bool WriteMAT(const char *, const char *="A") const
int ColIndex(int) const
Get column index of element given its linear index.
Definition: Matrix.h:579
Matrix & Ident()
Set to identity matrix.
Matrix & Transpose()
Transpose matrix.
3x3 single-precision matrix
Definition: Math.h:284
void LU(Matrix &, Matrix &, double &) const
Calculate LU decomposition of square matrix.
friend ostream & operator<<(ostream &, const Matrix &)
Interface to output stream.
int RowIndex(int) const
Get row index of element given its linear index.
Definition: Matrix.h:573
Matrix & operator/=(double)
Division by a double.
Definition: Matrix.h:774
void Import(const char *, int, int)
Import matrix from text file (requires no. of expected rows and cols)
int Cols() const
Get number of columns.
Definition: Matrix.h:561
double ColStd(int) const
Standard deviation of row values in specified column.
MIRTKCU_API bool fequal(double a, double b, double tol=1e-12)
Definition: Math.h:138
Matrix Inverse(bool use_svd_if_singular=true) const
Get inverse matrix.
Definition: Matrix.h:1027
void Initialize(int, int=-1, double *=NULL)
Initialize matrix with number of rows and columns.
double ColVar(int) const
Variance of row values in specified column.
void MakeSymmetric()
Make square matrix symmetric by adding its transpose and divide by 2.
Matrix & Invert(bool use_svd_if_singular=true)
Invert matrix.
Definition: IOConfig.h:41
void Print(Indent=0) const
Print matrix.
Matrix & ScaleCol(int, double)
Scale column by a scalar.
Definition: Matrix.h:731
3x4 double-precision coordinate transformation matrix
Definition: Math.h:418
4x4 double-precision matrix
Definition: Math.h:396
Matrix operator-(double) const
Return result of subtraction of a double.
Definition: Matrix.h:783
bool _owner
Whether this instance owns the memory of the matrix elements.
Definition: Matrix.h:72
Matrix & operator=(double)
Assign scalar value to all elements.
Definition: Matrix.h:738
friend istream & operator>>(istream &, Matrix &)
Interface to input stream.
Matrix SVDInverse() const
Get inverse of (singular) matrix using SVD.
Definition: Matrix.h:1033
double ** _matrix
Matrix values.
Definition: Matrix.h:69
void Clear()
Free memory.
void Put(int, double)
Set value of element with specified linear index.
Definition: Matrix.h:662
Matrix operator~()
Matrix transpose operator.
Definition: Matrix.h:1057
double RowSum(int) const
Sum of column values in specified row.
Matrix Transposed() const
Get transposed matrix.
Definition: Matrix.h:1051
Matrix()
Default constructor.
Matrix & AddToRow(int, double)
Add scalar to values in specified row.
Definition: Matrix.h:710
Array< int > operator>(double) const
Definition: Matrix.h:878
Matrix3x3 To3x3() const
Get upper left 3x3 sub-matrix.
Definition: Matrix.h:686
double * RawPointer(int r=0, int c=0)
Get pointer to linear memory which stores matrix elements in column-major order.
Definition: Matrix.h:602
Matrix & PermuteRows(Array< int >)
Permute rows.
double ColMean(int) const
Mean of row values in specified column.
void Write(const char *) const
Write matrix to file.
Matrix BiInvariantMean(int n, const Matrix *matrices, const double *weights=NULL, int niter=20, double tol=1e-12, const Matrix *mu0=NULL)
Matrix FrechetMean(const Matrix *matrices, const double *weights, int n, int niter=20, double tol=1e-12, const Matrix *mu0=NULL)
Definition: Matrix.h:1205
Array< int > operator<(double) const
Definition: Matrix.h:854
Matrix Log() const
Matrix logarithm.
void TransformVector(const Matrix &m, double x, double y, double z, double &mx, double &my, double &mz)
Muliply vector by 3x3 transformation matrix.
Definition: Matrix.h:1249
Matrix & SVDInvert()
Invert (singular) matrix using SVD.
bool IsDiagonalizable() const
Whether matrix is diagonalizable.
double ColSum(int) const
Sum of row values in specified column.
int Index(int, int) const
Get linear index of element given its row and column indices.
Definition: Matrix.h:567
Matrix & operator*=(double)
Multiplication with a double.
Definition: Matrix.h:765
Matrix operator*(double) const
Return result of multiplication with a double.
Definition: Matrix.h:795
Array< int > operator<=(double) const
Definition: Matrix.h:866
Matrix & AddToCol(int, double)
Add scalar to values in specified column.
Definition: Matrix.h:717
double RowMean(int) const
Mean of column values in specified row.
Matrix operator+(double) const
Return result of addition of a double.
Definition: Matrix.h:789
void ColRange(int, double &, double &) const
Minimum and maximum value in specified column.
Definition: Matrix.h:956
Array< int > operator>=(double) const
Definition: Matrix.h:890
Matrix Exp() const
double * GetPointerToElements(int r=0, int c=0)
Definition: Matrix.h:614
double _z
z coordinate of Point
Definition: Point.h:48
void AffineParametersToMatrix(double tx, double ty, double tz, double rx, double ry, double rz, double sx, double sy, double sz, double sxy, double sxz, double syz, Matrix &m)
bool operator==(const Matrix &) const
Matrix equality.
Definition: Matrix.h:811
double RowMin(int) const
Minimum value in specified row.
Definition: Matrix.h:906
Matrix & operator+=(double)
Addition of a double.
Definition: Matrix.h:756
double _y
y coordinate of Point
Definition: Point.h:47
int Rows() const
Get number of rows.
Definition: Matrix.h:555
void SVD(Matrix &, Vector &, Matrix &) const
Calculate singular value decomposition.
double RowVar(int) const
Variance of column values in specified row.
void OrthoNormalize3x3(Matrix &)
Orthonormalize upper 3x3 matrix using stabilized Gram-Schmidt.
Matrix & PseudoInvert()
Invert matrix using pseudo inverse.
double ColMin(int) const
Minimum value in specified column.
Definition: Matrix.h:938
int _cols
Number of colums.
Definition: Matrix.h:66
void Transform(Array< T > &values, UnaryOperation op)
Apply unary operation for each array element in-place.
Definition: Algorithm.h:91
Matrix & operator-=(double)
Subtraction of a double.
Definition: Matrix.h:747
double RowStd(int) const
Standard deviation of column values in specified row.
Pair< int, int > Size() const
Get matrix size in each dimension.
Definition: Matrix.h:549