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  Matrix*
241  getFirstNColumns(int n) const;
242 
253  void
255  int n,
256  Matrix*& result) const;
257 
268  void
270  int n,
271  Matrix& result) const;
272 
288  Matrix*
290  const Matrix& other) const
291  {
292  Matrix* result = 0;
293  mult(other, result);
294  return result;
295  }
296 
313  Matrix*
315  const Matrix* other) const
316  {
317  CAROM_VERIFY(other != 0);
318  return mult(*other);
319  }
320 
338  void
339  mult(
340  const Matrix& other,
341  Matrix*& result) const;
342 
359  void
360  mult(
361  const Matrix& other,
362  Matrix& result) const;
363 
379  Vector*
381  const Vector& other) const
382  {
383  Vector* result = 0;
384  mult(other, result);
385  return result;
386  }
387 
404  Vector*
406  const Vector* other) const
407  {
408  CAROM_VERIFY(other != 0);
409  return mult(*other);
410  }
411 
429  void
430  mult(
431  const Vector& other,
432  Vector*& result) const;
433 
450  void
451  mult(
452  const Vector& other,
453  Vector& result) const;
454 
472  void
474  int this_row,
475  const Vector& other,
476  Vector& result) const;
477 
495  void
497  int this_row,
498  Vector& other) const;
499 
512  Matrix*
514  const Matrix& other) const
515  {
516  Matrix* result = 0;
517  elementwise_mult(other, result);
518  return result;
519  }
520 
534  Matrix*
536  const Matrix* other) const
537  {
538  CAROM_VERIFY(other != 0);
539  return elementwise_mult(*other);
540  }
541 
554  void
556  const Matrix& other,
557  Matrix*& result) const;
558 
571  void
573  const Matrix& other,
574  Matrix& result) const;
575 
581  Matrix*
583  {
584  Matrix* result = 0;
585  elementwise_square(result);
586  return result;
587  }
588 
595  void
597  Matrix*& result) const;
598 
605  void
607  Matrix& result) const;
608 
626  void
627  multPlus(
628  Vector& a,
629  const Vector& b,
630  double c) const;
631 
647  Matrix*
649  const Matrix& other) const
650  {
651  Matrix* result = 0;
652  transposeMult(other, result);
653  return result;
654  }
655 
672  Matrix*
674  const Matrix* other) const
675  {
676  CAROM_VERIFY(other != 0);
677  return transposeMult(*other);
678  }
679 
696  void
698  const Matrix& other,
699  Matrix*& result) const;
700 
716  void
718  const Matrix& other,
719  Matrix& result) const;
720 
736  Vector*
738  const Vector& other) const
739  {
740  Vector* result = 0;
741  transposeMult(other, result);
742  return result;
743  }
744 
761  Vector*
763  const Vector* other) const
764  {
765  CAROM_VERIFY(other != 0);
766  return transposeMult(*other);
767  }
768 
785  void
787  const Vector& other,
788  Vector*& result) const;
789 
806  void
808  const Vector& other,
809  Vector& result) const;
810 
819  Matrix*
820  inverse() const
821  {
822  Matrix* result = 0;
823  inverse(result);
824  return result;
825  }
826 
841  void
842  inverse(
843  Matrix*& result) const;
844 
857  void
858  inverse(
859  Matrix& result) const;
860 
867  void
868  inverse();
869 
875  Vector*
876  getColumn(int column) const
877  {
878  Vector* result = 0;
879  getColumn(column, result);
880  return result;
881  }
882 
888  void
889  getColumn(int column,
890  Vector*& result) const;
891 
897  void
898  getColumn(int column,
899  Vector& result) const;
900 
908  void transpose();
909 
919  void transposePseudoinverse();
920 
926  std::unique_ptr<Matrix>
927  qr_factorize() const;
928 
934  void qr_factorize(std::vector<std::unique_ptr<Matrix>> & QR) const;
935 
951  void
952  qrcp_pivots_transpose(int* row_pivot,
953  int* row_pivot_owner,
954  int pivots_requested) const;
955 
970  void
971  orthogonalize(bool double_pass = false, double zero_tol = 1.0e-15);
972 
992  void
993  orthogonalize_last(int ncols = -1, bool double_pass = false,
994  double zero_tol = 1.0e-15);
995 
999  void
1000  rescale_rows_max();
1001 
1005  void
1006  rescale_cols_max();
1007 
1019  const double&
1021  int row,
1022  int col) const
1023  {
1024  CAROM_ASSERT((0 <= row) && (row < numRows()));
1025  CAROM_ASSERT((0 <= col) && (col < numColumns()));
1026  return d_mat[row*d_num_cols+col];
1027  }
1028 
1042  double&
1044  int row,
1045  int col)
1046  {
1047  CAROM_ASSERT((0 <= row) && (row < numRows()));
1048  CAROM_ASSERT((0 <= col) && (col < numColumns()));
1049  return d_mat[row*d_num_cols+col];
1050  }
1051 
1062  const double& operator() (int row, int col) const
1063  {
1064  return item(row, col);
1065  }
1066 
1079  double& operator() (int row, int col)
1080  {
1081  return item(row, col);
1082  }
1083 
1090  void print(const char * prefix) const;
1091 
1098  void write(const std::string& base_file_name) const;
1099 
1106  void read(const std::string& base_file_name);
1107 
1115  void local_read(const std::string& base_file_name, int rank);
1116 
1120  double *getData() const
1121  {
1122  return d_mat;
1123  }
1124 
1135  void distribute(const int &local_num_rows);
1136 
1144  void gather();
1145 
1146 private:
1152  void
1153  calculateNumDistributedRows();
1154 
1169  void
1170  qrcp_pivots_transpose_serial(int* row_pivot,
1171  int* row_pivot_owner,
1172  int pivots_requested) const;
1173 
1188  void
1189  qrcp_pivots_transpose_distributed(int* row_pivot,
1190  int* row_pivot_owner,
1191  int pivots_requested) const;
1192 
1193  void
1194  qrcp_pivots_transpose_distributed_scalapack(int* row_pivot,
1195  int* row_pivot_owner,
1196  int pivots_requested) const;
1197 
1213  void
1214  qrcp_pivots_transpose_distributed_elemental(int* row_pivot,
1215  int* row_pivot_owner,
1216  int pivots_requested) const;
1217 
1233  void
1234  qrcp_pivots_transpose_distributed_elemental_balanced
1235  (int* row_pivot, int* row_pivot_owner, int pivots_requested) const;
1236 
1252  void
1253  qrcp_pivots_transpose_distributed_elemental_unbalanced
1254  (int* row_pivot, int* row_pivot_owner, int pivots_requested) const;
1255 
1267  void qr_factorize(bool computeR, std::vector<Matrix*> & QR) const;
1268 
1272  double* d_mat;
1273 
1277  int d_num_rows;
1278 
1282  int d_num_distributed_rows;
1283 
1290  int d_num_cols;
1291 
1297  int d_alloc_size;
1298 
1304  bool d_distributed;
1305 
1309  int d_num_procs;
1310 
1314  int d_rank;
1315 
1322  bool d_owns_data;
1323 };
1324 
1339 // NOTE(goxberry@gmail.com; oxberry1@llnl.gov): Passing by value is
1340 // supposed to be more idiomatic C++11; consider passing by value
1341 // instead of passing by reference.
1342 Matrix outerProduct(const Vector &v, const Vector &w);
1343 
1358 Matrix DiagonalMatrixFactory(const Vector &v);
1359 
1374 Matrix IdentityMatrixFactory(const Vector &v);
1375 
1380 struct EigenPair {
1381 
1386 
1390  std::vector<double> eigs;
1391 };
1392 
1398 
1403 
1408 
1412  std::vector<std::complex<double>> eigs;
1413 };
1414 
1420 {
1425 
1430 
1435 };
1436 
1448 void SerialSVD(Matrix* A,
1449  Matrix* U,
1450  Vector* S,
1451  Matrix* V);
1452 
1463 
1473 
1483 
1484 Matrix* SpaceTimeProduct(const CAROM::Matrix* As, const CAROM::Matrix* At,
1485  const CAROM::Matrix* Bs, const CAROM::Matrix* Bt,
1486  const std::vector<double> *tscale=NULL,
1487  const bool At0at0=false, const bool Bt0at0=false,
1488  const bool lagB=false, const bool skip0=false);
1489 }
1490 
1491 #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:1013
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
Matrix * getFirstNColumns(int n) const
Get the first N columns of a matrix.
Definition: Matrix.cpp:260
double * getData() const
Get the matrix data as a pointer.
Definition: Matrix.h:1120
bool balanced() const
Returns true if rows of matrix are load-balanced.
Definition: Matrix.cpp:207
Matrix * inverse() const
Computes and returns the inverse of this.
Definition: Matrix.h:820
const double & operator()(int row, int col) const
Const Matrix member access.
Definition: Matrix.h:1062
void transposePseudoinverse()
Computes the transposePseudoinverse of this.
Definition: Matrix.cpp:886
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:2013
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:941
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
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:1050
void gather()
Gather all the distributed rows among MPI processes. This becomes not distributed after this function...
Definition: Matrix.cpp:1077
Matrix * elementwise_mult(const Matrix &other) const
Multiplies two matrices element-wise.
Definition: Matrix.h:513
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:1963
std::unique_ptr< Matrix > qr_factorize() const
Computes and returns the Q of the QR factorization of this.
Definition: Matrix.cpp:1128
Matrix & operator+=(const Matrix &rhs)
Addition operator.
Definition: Matrix.cpp:187
Matrix * mult(const Matrix *other) const
Multiplies this Matrix with other and returns the product, pointer version.
Definition: Matrix.h:314
int numDistributedRows() const
Returns the number of rows of the Matrix across all processors.
Definition: Matrix.h:211
Vector * getColumn(int column) const
Returns a column of the matrix (not owned by Matrix).
Definition: Matrix.h:876
Matrix & operator-=(const Matrix &rhs)
Subtraction operator.
Definition: Matrix.cpp:197
void orthogonalize(bool double_pass=false, double zero_tol=1.0e-15)
Orthonormalizes the matrix.
Definition: Matrix.cpp:1913
void multPlus(Vector &a, const Vector &b, double c) const
Computes a += this*b*c.
Definition: Matrix.cpp:543
Vector * transposeMult(const Vector &other) const
Multiplies the transpose of this Matrix with other and returns the product, reference version.
Definition: Matrix.h:737
double & item(int row, int col)
Non-const Matrix member access. Matrix data is stored in row-major format.
Definition: Matrix.h:1043
void print(const char *prefix) const
print Matrix into (a) ascii file(s).
Definition: Matrix.cpp:922
Matrix * transposeMult(const Matrix &other) const
Multiplies the transpose of this Matrix with other and returns the product, reference version.
Definition: Matrix.h:648
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:422
Matrix * mult(const Matrix &other) const
Multiplies this Matrix with other and returns the product, reference version.
Definition: Matrix.h:289
Vector * mult(const Vector *other) const
Multiplies this Matrix with other and returns the product, pointer version.
Definition: Matrix.h:405
~Matrix()
Destructor.
Definition: Matrix.cpp:168
Matrix * elementwise_mult(const Matrix *other) const
Multiplies two matrices element-wise and returns the product, pointer version.
Definition: Matrix.h:535
const double & item(int row, int col) const
Const Matrix member access. Matrix data is stored in row-major format.
Definition: Matrix.h:1020
Vector * mult(const Vector &other) const
Multiplies this Matrix with other and returns the product, reference version.
Definition: Matrix.h:380
Matrix * transposeMult(const Matrix *other) const
Multiplies the transpose of this Matrix with other and returns the product, pointer version.
Definition: Matrix.h:673
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:973
Matrix * elementwise_square() const
Square every element in the matrix.
Definition: Matrix.h:582
Vector * transposeMult(const Vector *other) const
Multiplies the transpose of this Matrix with other and returns the product, pointer version.
Definition: Matrix.h:762
void transpose()
Replaces this Matrix with its transpose (in place), in the serial square case only.
Definition: Matrix.cpp:828
void rescale_cols_max()
Rescale every matrix column by its maximum absolute value.
Definition: Matrix.cpp:2040
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:1308
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:2259
struct ComplexEigenPair NonSymmetricRightEigenSolve(Matrix *A)
Computes the eigenvectors/eigenvalues of an NxN real nonsymmetric matrix.
Definition: Matrix.cpp:2313
struct EigenPair SymmetricRightEigenSolve(Matrix *A)
Computes the eigenvectors/eigenvalues of an NxN real symmetric matrix.
Definition: Matrix.cpp:2266
Matrix outerProduct(const Vector &v, const Vector &w)
Computes the outer product of two Vectors, v and w.
Definition: Matrix.cpp:2083
void SerialSVD(Matrix *A, Matrix *U, Vector *S, Matrix *V)
Computes the SVD of a undistributed matrix in serial.
Definition: Matrix.cpp:2389
Matrix DiagonalMatrixFactory(const Vector &v)
Factory function to make a diagonal matrix with nonzero entries as in its Vector argument....
Definition: Matrix.cpp:2183
Matrix * ev_real
The real component of the eigenvectors in matrix form.
Definition: Matrix.h:1402
std::vector< std::complex< double > > eigs
The corresponding complex eigenvalues.
Definition: Matrix.h:1412
Matrix * ev_imaginary
The imaginary component of the eigenvectors in matrix form.
Definition: Matrix.h:1407
std::vector< double > eigs
The corresponding eigenvalues.
Definition: Matrix.h:1390
Matrix * ev
The eigenvectors in matrix form.
Definition: Matrix.h:1385
Matrix * U
The left singular vectors.
Definition: Matrix.h:1424
Vector * S
The singular values.
Definition: Matrix.h:1429
Matrix * V
The right singular vectors.
Definition: Matrix.h:1434