libROM  v1.0
Data-driven physical simulation library
Matrix.h
1 
11 // Description: A simple, parallel Matrix class with the utility needed to
12 // support the basis generation methods of this library. A
13 // distributed Matrix has its rows distributed across processors.
14 
15 #ifndef included_Matrix_h
16 #define included_Matrix_h
17 
18 #include "Vector.h"
19 #include <vector>
20 #include <complex>
21 #include <memory>
22 #include <string>
23 #include <climits>
24 
25 namespace CAROM {
26 
32 class Matrix
33 {
34 public:
36  Matrix();
37 
53  Matrix(
54  int num_rows,
55  int num_cols,
56  bool distributed,
57  bool randomized = false);
58 
77  Matrix(
78  double* mat,
79  int num_rows,
80  int num_cols,
81  bool distributed,
82  bool copy_data = true);
83 
89  Matrix(
90  const Matrix& other);
91 
95  ~Matrix();
96 
104  Matrix&
105  operator = (
106  const Matrix& rhs);
107 
115  Matrix&
116  operator = (
117  const double a);
118 
126  Matrix&
127  operator += (
128  const Matrix& rhs);
129 
137  Matrix&
138  operator -= (
139  const Matrix& rhs);
140 
148  void
150  int num_rows,
151  int num_cols)
152  {
153  // Check integer multiplication overflow
154  if (num_rows > INT_MAX / num_cols)
155  CAROM_ERROR("Matrix::setSize- new size exceeds maximum integer value!\n");
156 
157  int new_size = num_rows*num_cols;
158  if (new_size > d_alloc_size) {
159  if (!d_owns_data) {
160  CAROM_ERROR("Can not reallocate externally owned storage.");
161  }
162  if (d_mat) {
163  delete [] d_mat;
164  }
165 
166  // Allocate new array and initialize all values to zero.
167  d_mat = new double [new_size] {0.0};
168  d_alloc_size = new_size;
169  }
170  d_num_rows = num_rows;
171  d_num_cols = num_cols;
172  if (d_distributed) {
173  calculateNumDistributedRows();
174  }
175  }
176 
182  bool
183  distributed() const
184  {
185  return d_distributed;
186  }
187 
192  bool balanced() const;
193 
199  int
200  numRows() const
201  {
202  return d_num_rows;
203  }
204 
210  int
212  {
213  if (!d_distributed) {
214  return d_num_rows;
215  }
216  return d_num_distributed_rows;
217  }
218 
225  int
226  numColumns() const
227  {
228  return d_num_cols;
229  }
230 
240  std::unique_ptr<Matrix>
241  getFirstNColumns(int n) const;
242 
253  void
255  int n,
256  Matrix& result) const;
257 
272  std::unique_ptr<Matrix>
274  const Matrix& other) const
275  {
276  Matrix* result = new Matrix(d_num_rows, other.d_num_cols, d_distributed);
277  mult(other, *result);
278  return std::unique_ptr<Matrix>(result);
279  }
280 
297  void
298  mult(
299  const Matrix& other,
300  Matrix& result) const;
301 
316  std::unique_ptr<Vector>
318  const Vector& other) const
319  {
320  Vector* result = new Vector(d_num_rows, d_distributed);
321  mult(other, *result);
322  return std::unique_ptr<Vector>(result);
323  }
324 
341  void
342  mult(
343  const Vector& other,
344  Vector& result) const;
345 
363  void
365  int this_row,
366  const Vector& other,
367  Vector& result) const;
368 
386  void
388  int this_row,
389  Vector& other) const;
390 
403  std::unique_ptr<Matrix>
405  const Matrix& other) const
406  {
407  Matrix *result = new Matrix(d_num_rows, d_num_cols, d_distributed);
408  elementwise_mult(other, *result);
409  return std::unique_ptr<Matrix>(result);
410  }
411 
424  void
426  const Matrix& other,
427  Matrix& result) const;
428 
434  std::unique_ptr<Matrix>
436  {
437  Matrix *result = new Matrix(d_num_rows, d_num_cols, d_distributed);
438  elementwise_square(*result);
439  return std::unique_ptr<Matrix>(result);
440  }
441 
448  void
450  Matrix& result) const;
451 
469  void
470  multPlus(
471  Vector& a,
472  const Vector& b,
473  double c) const;
474 
490  std::unique_ptr<Matrix>
492  const Matrix& other) const
493  {
494  Matrix* result = new Matrix(d_num_cols, other.d_num_cols, false);
495  transposeMult(other, *result);
496  return std::unique_ptr<Matrix>(result);
497  }
498 
514  void
516  const Matrix& other,
517  Matrix& result) const;
518 
534  std::unique_ptr<Vector>
536  const Vector& other) const
537  {
538  Vector* result = new Vector(d_num_cols, false);
539  transposeMult(other, *result);
540  return std::unique_ptr<Vector>(result);
541  }
542 
559  void
561  const Vector& other,
562  Vector& result) const;
563 
572  std::unique_ptr<Matrix>
573  inverse() const
574  {
575  Matrix* result = new Matrix(d_num_rows, d_num_cols, false);
576  inverse(*result);
577  return std::unique_ptr<Matrix>(result);
578  }
579 
592  void
593  inverse(
594  Matrix& result) const;
595 
602  void
603  inverse();
604 
610  std::unique_ptr<Vector>
611  getColumn(int column) const
612  {
613  Vector* result = new Vector(d_num_rows, true);
614  getColumn(column, *result);
615  return std::unique_ptr<Vector>(result);
616  }
617 
623  void
624  getColumn(int column,
625  Vector& result) const;
626 
634  void transpose();
635 
645  void transposePseudoinverse();
646 
652  std::unique_ptr<Matrix>
653  qr_factorize() const;
654 
660  void qr_factorize(std::vector<std::unique_ptr<Matrix>> & QR) const;
661 
677  void
678  qrcp_pivots_transpose(int* row_pivot,
679  int* row_pivot_owner,
680  int pivots_requested) const;
681 
696  void
697  orthogonalize(bool double_pass = false, double zero_tol = 1.0e-15);
698 
718  void
719  orthogonalize_last(int ncols = -1, bool double_pass = false,
720  double zero_tol = 1.0e-15);
721 
725  void
727 
731  void
733 
745  const double&
746  item(int row,
747  int col) const
748  {
749  CAROM_ASSERT((0 <= row) && (row < numRows()));
750  CAROM_ASSERT((0 <= col) && (col < numColumns()));
751  return d_mat[row*d_num_cols+col];
752  }
753 
767  double&
768  item(int row,
769  int col)
770  {
771  CAROM_ASSERT((0 <= row) && (row < numRows()));
772  CAROM_ASSERT((0 <= col) && (col < numColumns()));
773  return d_mat[row*d_num_cols+col];
774  }
775 
786  const double& operator() (int row, int col) const
787  {
788  return item(row, col);
789  }
790 
803  double& operator() (int row, int col)
804  {
805  return item(row, col);
806  }
807 
814  void print(const char * prefix) const;
815 
822  void write(const std::string& base_file_name) const;
823 
830  void read(const std::string& base_file_name);
831 
839  void local_read(const std::string& base_file_name, int rank);
840 
844  double *getData() const
845  {
846  return d_mat;
847  }
848 
859  void distribute(const int &local_num_rows);
860 
868  void gather();
869 
870 private:
876  void
877  calculateNumDistributedRows();
878 
893  void
894  qrcp_pivots_transpose_serial(int* row_pivot,
895  int* row_pivot_owner,
896  int pivots_requested) const;
897 
912  void
913  qrcp_pivots_transpose_distributed(int* row_pivot,
914  int* row_pivot_owner,
915  int pivots_requested) const;
916 
917  void
918  qrcp_pivots_transpose_distributed_scalapack(int* row_pivot,
919  int* row_pivot_owner,
920  int pivots_requested) const;
921 
937  void
938  qrcp_pivots_transpose_distributed_elemental(int* row_pivot,
939  int* row_pivot_owner,
940  int pivots_requested) const;
941 
957  void
958  qrcp_pivots_transpose_distributed_elemental_balanced
959  (int* row_pivot, int* row_pivot_owner, int pivots_requested) const;
960 
976  void
977  qrcp_pivots_transpose_distributed_elemental_unbalanced
978  (int* row_pivot, int* row_pivot_owner, int pivots_requested) const;
979 
991  void qr_factorize(bool computeR, std::vector<Matrix*> & QR) const;
992 
996  double* d_mat;
997 
1001  int d_num_rows;
1002 
1006  int d_num_distributed_rows;
1007 
1014  int d_num_cols;
1015 
1021  int d_alloc_size;
1022 
1028  bool d_distributed;
1029 
1033  int d_num_procs;
1034 
1038  int d_rank;
1039 
1046  bool d_owns_data;
1047 };
1048 
1063 // NOTE(goxberry@gmail.com; oxberry1@llnl.gov): Passing by value is
1064 // supposed to be more idiomatic C++11; consider passing by value
1065 // instead of passing by reference.
1066 Matrix outerProduct(const Vector &v, const Vector &w);
1067 
1082 Matrix DiagonalMatrixFactory(const Vector &v);
1083 
1098 Matrix IdentityMatrixFactory(const Vector &v);
1099 
1104 struct EigenPair {
1105 
1110 
1114  std::vector<double> eigs;
1115 };
1116 
1122 
1127 
1132 
1136  std::vector<std::complex<double>> eigs;
1137 };
1138 
1144 {
1149 
1154 
1159 };
1160 
1172 void SerialSVD(Matrix* A,
1173  Matrix* U,
1174  Vector* S,
1175  Matrix* V);
1176 
1187 
1197 
1207 
1208 std::unique_ptr<Matrix> SpaceTimeProduct(const CAROM::Matrix & As,
1209  const CAROM::Matrix & At, const CAROM::Matrix & Bs,
1210  const CAROM::Matrix & Bt,
1211  const std::vector<double> *tscale=NULL,
1212  const bool At0at0=false, const bool Bt0at0=false,
1213  const bool lagB=false, const bool skip0=false);
1214 }
1215 
1216 #endif
void local_read(const std::string &base_file_name, int rank)
read a single rank of a distributed Matrix into (a) HDF file(s).
Definition: Matrix.cpp:730
void setSize(int num_rows, int num_cols)
Sets the number of rows and columns of the matrix and reallocates storage if needed....
Definition: Matrix.h:149
std::unique_ptr< Vector > mult(const Vector &other) const
Multiplies this Matrix with other and returns the product.
Definition: Matrix.h:317
double * getData() const
Get the matrix data as a pointer.
Definition: Matrix.h:844
bool balanced() const
Returns true if rows of matrix are load-balanced.
Definition: Matrix.cpp:207
const double & operator()(int row, int col) const
Const Matrix member access.
Definition: Matrix.h:786
void transposePseudoinverse()
Computes the transposePseudoinverse of this.
Definition: Matrix.cpp:605
bool distributed() const
Returns true if the Matrix is distributed.
Definition: Matrix.h:183
void rescale_rows_max()
Rescale every matrix row by its maximum absolute value.
Definition: Matrix.cpp:1731
Matrix & operator=(const Matrix &rhs)
Assignment operator.
Definition: Matrix.cpp:176
void write(const std::string &base_file_name) const
write Matrix into (a) HDF file(s).
Definition: Matrix.cpp:658
int numColumns() const
Returns the number of columns in the Matrix. This method will return the same value from each process...
Definition: Matrix.h:226
std::unique_ptr< Vector > transposeMult(const Vector &other) const
Multiplies the transpose of this Matrix with other and returns the product.
Definition: Matrix.h:535
void distribute(const int &local_num_rows)
Distribute this matrix rows among MPI processes, based on the specified local number of rows....
Definition: Matrix.cpp:767
void gather()
Gather all the distributed rows among MPI processes. This becomes not distributed after this function...
Definition: Matrix.cpp:794
void orthogonalize_last(int ncols=-1, bool double_pass=false, double zero_tol=1.0e-15)
Orthonormalizes the matrix's last column, assuming the previous columns are already orthonormal.
Definition: Matrix.cpp:1681
std::unique_ptr< Matrix > qr_factorize() const
Computes and returns the Q of the QR factorization of this.
Definition: Matrix.cpp:846
Matrix & operator+=(const Matrix &rhs)
Addition operator.
Definition: Matrix.cpp:187
int numDistributedRows() const
Returns the number of rows of the Matrix across all processors.
Definition: Matrix.h:211
Matrix & operator-=(const Matrix &rhs)
Subtraction operator.
Definition: Matrix.cpp:197
std::unique_ptr< Vector > getColumn(int column) const
Returns a deep copy of a column of the matrix.
Definition: Matrix.h:611
void orthogonalize(bool double_pass=false, double zero_tol=1.0e-15)
Orthonormalizes the matrix.
Definition: Matrix.cpp:1631
std::unique_ptr< Matrix > inverse() const
Computes and returns the inverse of this.
Definition: Matrix.h:573
void multPlus(Vector &a, const Vector &b, double c) const
Computes a += this*b*c.
Definition: Matrix.cpp:407
double & item(int row, int col)
Non-const Matrix member access. Matrix data is stored in row-major format.
Definition: Matrix.h:768
void print(const char *prefix) const
print Matrix into (a) ascii file(s).
Definition: Matrix.cpp:639
std::unique_ptr< Matrix > getFirstNColumns(int n) const
Get the first N columns of a matrix.
Definition: Matrix.cpp:260
std::unique_ptr< Matrix > elementwise_mult(const Matrix &other) const
Multiplies two matrices element-wise.
Definition: Matrix.h:404
void pointwise_mult(int this_row, const Vector &other, Vector &result) const
Multiplies a specified row of this Matrix with other pointwise.
Definition: Matrix.cpp:336
~Matrix()
Destructor.
Definition: Matrix.cpp:168
const double & item(int row, int col) const
Const Matrix member access. Matrix data is stored in row-major format.
Definition: Matrix.h:746
int numRows() const
Returns the number of rows of the Matrix on this processor.
Definition: Matrix.h:200
void read(const std::string &base_file_name)
read Matrix into (a) HDF file(s).
Definition: Matrix.cpp:690
std::unique_ptr< Matrix > mult(const Matrix &other) const
Multiplies this Matrix with other and returns the product.
Definition: Matrix.h:273
void transpose()
Replaces this Matrix with its transpose (in place), in the serial square case only.
Definition: Matrix.cpp:547
std::unique_ptr< Matrix > elementwise_square() const
Square every element in the matrix.
Definition: Matrix.h:435
std::unique_ptr< Matrix > transposeMult(const Matrix &other) const
Multiplies the transpose of this Matrix with other and returns the product.
Definition: Matrix.h:491
void rescale_cols_max()
Rescale every matrix column by its maximum absolute value.
Definition: Matrix.cpp:1758
void qrcp_pivots_transpose(int *row_pivot, int *row_pivot_owner, int pivots_requested) const
Compute the leading numColumns() column pivots from a QR decomposition with column pivots (QRCP) of t...
Definition: Matrix.cpp:1026
ComplexEigenPair NonSymmetricRightEigenSolve(const Matrix &A)
Computes the eigenvectors/eigenvalues of an NxN real nonsymmetric matrix.
Definition: Matrix.cpp:2031
Matrix IdentityMatrixFactory(const Vector &v)
Factory function to make an identity matrix with rows distributed in the same fashion as its Vector a...
Definition: Matrix.cpp:1977
Matrix outerProduct(const Vector &v, const Vector &w)
Computes the outer product of two Vectors, v and w.
Definition: Matrix.cpp:1801
void SerialSVD(Matrix *A, Matrix *U, Vector *S, Matrix *V)
Computes the SVD of a undistributed matrix in serial.
Definition: Matrix.cpp:2107
Matrix DiagonalMatrixFactory(const Vector &v)
Factory function to make a diagonal matrix with nonzero entries as in its Vector argument....
Definition: Matrix.cpp:1901
EigenPair SymmetricRightEigenSolve(const Matrix &A)
Computes the eigenvectors/eigenvalues of an NxN real symmetric matrix.
Definition: Matrix.cpp:1984
Matrix * ev_real
The real component of the eigenvectors in matrix form.
Definition: Matrix.h:1126
std::vector< std::complex< double > > eigs
The corresponding complex eigenvalues.
Definition: Matrix.h:1136
Matrix * ev_imaginary
The imaginary component of the eigenvectors in matrix form.
Definition: Matrix.h:1131
std::vector< double > eigs
The corresponding eigenvalues.
Definition: Matrix.h:1114
Matrix * ev
The eigenvectors in matrix form.
Definition: Matrix.h:1109
Matrix * U
The left singular vectors.
Definition: Matrix.h:1148
Vector * S
The singular values.
Definition: Matrix.h:1153
Matrix * V
The right singular vectors.
Definition: Matrix.h:1158