Cantera  2.1.2
DenseMatrix.cpp
Go to the documentation of this file.
1 /**
2  * @file DenseMatrix.cpp
3  */
4 
5 // Copyright 2001 California Institute of Technology
6 
7 #include "cantera/base/ct_defs.h"
12 #include "cantera/base/global.h"
13 
14 namespace Cantera
15 {
16 
18  Array2D(0,0,0.0),
19  m_ipiv(0),
20  m_useReturnErrorCode(0),
21  m_printLevel(0)
22 {
23 }
24 
25 DenseMatrix::DenseMatrix(size_t n, size_t m, doublereal v) :
26  Array2D(n, m, v),
27  m_ipiv(0),
28  m_useReturnErrorCode(0),
29  m_printLevel(0)
30 {
31  m_ipiv.resize(std::max(n, m));
32  m_colPts.resize(m);
33  if (!m_data.empty()) {
34  for (size_t j = 0; j < m; j++) {
35  m_colPts[j] = &(m_data[m_nrows*j]);
36  }
37  }
38 }
39 
41  Array2D(y),
42  m_ipiv(0),
43  m_useReturnErrorCode(0),
44  m_printLevel(0)
45 {
46  m_ipiv = y.ipiv();
47  m_colPts.resize(m_ncols);
48  if (!m_data.empty()) {
49  for (size_t j = 0; j < m_ncols; j++) {
50  m_colPts[j] = &(m_data[m_nrows*j]);
51  }
52  }
53 }
54 
56 {
57  if (&y == this) {
58  return *this;
59  }
61  m_ipiv = y.ipiv();
62  m_colPts.resize(m_ncols);
63  for (size_t j = 0; j < m_ncols; j++) {
64  m_colPts[j] = &(m_data[m_nrows*j]);
65  }
68  return *this;
69 }
70 
71 void DenseMatrix::resize(size_t n, size_t m, doublereal v)
72 {
73  Array2D::resize(n,m,v);
74  m_ipiv.resize(std::max(n,m));
75  m_colPts.resize(m_ncols);
76  if (!m_data.empty()) {
77  for (size_t j = 0; j < m_ncols; j++) {
78  m_colPts[j] = &(m_data[m_nrows*j]);
79  }
80  }
81 }
82 
83 doublereal* const* DenseMatrix::colPts()
84 {
85  return &(m_colPts[0]);
86 }
87 
88 const doublereal* const* DenseMatrix::const_colPts() const
89 {
90  return &(m_colPts[0]);
91 }
92 
93 void DenseMatrix::mult(const double* b, double* prod) const
94 {
95  ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
96  static_cast<int>(nRows()),
97  static_cast<int>(nRows()), 1.0, ptrColumn(0), //begin(),
98  static_cast<int>(nRows()), b, 1, 0.0, prod, 1);
99 }
100 
101 void DenseMatrix::mult(const DenseMatrix& B, DenseMatrix& prod) const
102 {
103  if (m_ncols != B.nColumns() || m_nrows != B.nRows() || m_ncols != m_nrows || m_ncols != prod.nColumns() || m_nrows != prod.nColumns()) {
104  throw CanteraError("mult(const DenseMatrix &B, DenseMatrix &prod)",
105  "Cannot multiply matrices that are not square and/or not the same size.");
106  }
107  const doublereal* const* bcols = B.const_colPts();
108  doublereal* const* prodcols = prod.colPts();
109  for (size_t col=0; col < m_ncols; ++col) {
110  // Loop over ncols multiplying A*column of B and storing in corresponding prod column
111  mult(bcols[col], prodcols[col]);
112  }
113 }
114 
115 void DenseMatrix::leftMult(const double* const b, double* const prod) const
116 {
117  size_t nc = nColumns();
118  size_t nr = nRows();
119  double sum = 0.0;
120  for (size_t n = 0; n < nc; n++) {
121  sum = 0.0;
122  for (size_t i = 0; i < nr; i++) {
123  sum += value(i,n)*b[i];
124  }
125  prod[n] = sum;
126  }
127 }
128 
130 {
131  return m_ipiv;
132 }
133 
134 int solve(DenseMatrix& A, double* b)
135 {
136  int info = 0;
137  if (A.nColumns() != A.nRows()) {
138  if (A.m_printLevel) {
139  writelogf("solve(DenseMatrix& A, double* b): Can only solve a square matrix\n");
140  }
141  throw CELapackError("solve(DenseMatrix& A, double* b)", "Can only solve a square matrix");
142  }
143  ct_dgetrf(A.nRows(), A.nColumns(), A.ptrColumn(0),
144  A.nRows(), &A.ipiv()[0], info);
145  if (info > 0) {
146  if (A.m_printLevel) {
147  writelogf("solve(DenseMatrix& A, double* b): DGETRF returned INFO = %d U(i,i) is exactly zero. The factorization has"
148  " been completed, but the factor U is exactly singular, and division by zero will occur if "
149  "it is used to solve a system of equations.\n", info);
150  }
151  if (!A.m_useReturnErrorCode) {
152  throw CELapackError("solve(DenseMatrix& A, double* b)",
153  "DGETRF returned INFO = "+int2str(info) + ". U(i,i) is exactly zero. The factorization has"
154  " been completed, but the factor U is exactly singular, and division by zero will occur if "
155  "it is used to solve a system of equations.");
156  }
157  return info;
158  } else if (info < 0) {
159  if (A.m_printLevel) {
160  writelogf("solve(DenseMatrix& A, double* b): DGETRF returned INFO = %d. The argument i has an illegal value\n", info);
161  }
162 
163  throw CELapackError("solve(DenseMatrix& A, double* b)",
164  "DGETRF returned INFO = "+int2str(info) + ". The argument i has an illegal value");
165  }
166 
167  ct_dgetrs(ctlapack::NoTranspose, A.nRows(), 1, A.ptrColumn(0),
168  A.nRows(), &A.ipiv()[0], b, A.nColumns(), info);
169  if (info != 0) {
170  if (A.m_printLevel) {
171  writelogf("solve(DenseMatrix& A, double* b): DGETRS returned INFO = %d\n", info);
172  }
173  if (info < 0 || !A.m_useReturnErrorCode) {
174  throw CELapackError("solve(DenseMatrix& A, double* b)", "DGETRS returned INFO = "+int2str(info));
175  }
176  }
177  return info;
178 }
179 
181 {
182  int info = 0;
183  if (A.nColumns() != A.nRows()) {
184  if (A.m_printLevel) {
185  writelogf("solve(DenseMatrix& A, DenseMatrix& b): Can only solve a square matrix\n");
186  }
187  if (! A.m_useReturnErrorCode) {
188  throw CELapackError("solve(DenseMatrix& A, DenseMatrix& b)", "Can only solve a square matrix");
189  }
190  return -1;
191  }
192  ct_dgetrf(A.nRows(), A.nColumns(), A.ptrColumn(0),
193  A.nRows(), &A.ipiv()[0], info);
194  if (info != 0) {
195  if (info > 0) {
196  if (A.m_printLevel) {
197  writelogf("solve(DenseMatrix& A, DenseMatrix& b): DGETRF returned INFO = %d U(i,i) is exactly zero. The factorization has"
198  " been completed, but the factor U is exactly singular, and division by zero will occur if "
199  "it is used to solve a system of equations.\n", info);
200  }
201  if (! A.m_useReturnErrorCode) {
202  throw CELapackError("solve(DenseMatrix& A, DenseMatrix& b)",
203  "DGETRF returned INFO = "+int2str(info) + ". U(i,i) is exactly zero. The factorization has"
204  " been completed, but the factor U is exactly singular, and division by zero will occur if "
205  "it is used to solve a system of equations.");
206  }
207  } else {
208  if (A.m_printLevel) {
209  writelogf("solve(DenseMatrix& A, DenseMatrix& b): DGETRF returned INFO = %d. The argument i has an illegal value\n", info);
210  }
211  if (! A.m_useReturnErrorCode) {
212  throw CELapackError("solve(DenseMatrix& A, DenseMatrix& b)",
213  "DGETRF returned INFO = "+int2str(info) + ". The argument i has an illegal value");
214  }
215  }
216  return info;
217  }
218 
219  ct_dgetrs(ctlapack::NoTranspose, A.nRows(), b.nColumns(), A.ptrColumn(0),
220  A.nRows(), &A.ipiv()[0], b.ptrColumn(0), b.nRows(), info);
221  if (info != 0) {
222  if (A.m_printLevel) {
223  writelogf("solve(DenseMatrix& A, DenseMatrix& b): DGETRS returned INFO = %d\n", info);
224  }
225  if (! A.m_useReturnErrorCode) {
226  throw CELapackError("solve(DenseMatrix& A, DenseMatrix& b)", "DGETRS returned INFO = "+int2str(info));
227  }
228  }
229 
230  return info;
231 }
232 
233 void multiply(const DenseMatrix& A, const double* const b, double* const prod)
234 {
235  ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
236  static_cast<int>(A.nRows()), static_cast<int>(A.nColumns()), 1.0,
237  A.ptrColumn(0), static_cast<int>(A.nRows()), b, 1, 0.0, prod, 1);
238 }
239 
240 void increment(const DenseMatrix& A, const double* b, double* prod)
241 {
242  ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
243  static_cast<int>(A.nRows()), static_cast<int>(A.nRows()), 1.0,
244  A.ptrColumn(0), static_cast<int>(A.nRows()), b, 1, 1.0, prod, 1);
245 }
246 
247 int invert(DenseMatrix& A, size_t nn)
248 {
249  integer n = static_cast<int>(nn != npos ? nn : A.nRows());
250  int info=0;
251  ct_dgetrf(n, n, A.ptrColumn(0), static_cast<int>(A.nRows()),
252  &A.ipiv()[0], info);
253  if (info != 0) {
254  if (A.m_printLevel) {
255  writelogf("invert(DenseMatrix& A, int nn): DGETRS returned INFO = %d\n", info);
256  }
257  if (! A.m_useReturnErrorCode) {
258  throw CELapackError("invert(DenseMatrix& A, int nn)", "DGETRS returned INFO = "+int2str(info));
259  }
260  return info;
261  }
262 
263  vector_fp work(n);
264  integer lwork = static_cast<int>(work.size());
265  ct_dgetri(n, A.ptrColumn(0), static_cast<int>(A.nRows()),
266  &A.ipiv()[0], &work[0], lwork, info);
267  if (info != 0) {
268  if (A.m_printLevel) {
269  writelogf("invert(DenseMatrix& A, int nn): DGETRS returned INFO = %d\n", info);
270  }
271  if (! A.m_useReturnErrorCode) {
272  throw CELapackError("invert(DenseMatrix& A, int nn)", "DGETRI returned INFO="+int2str(info));
273  }
274  }
275  return info;
276 }
277 
278 }
const doublereal *const * const_colPts() const
Return a const vector of const pointers to the columns.
Definition: DenseMatrix.cpp:88
DenseMatrix & operator=(const DenseMatrix &y)
Assignment operator.
Definition: DenseMatrix.cpp:55
size_t nRows() const
Number of rows.
Definition: Array.h:317
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:40
int invert(DenseMatrix &A, size_t nn)
invert A. A is overwritten with A^-1.
vector_fp m_data
Data stored in a single array.
Definition: Array.h:381
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
Definition: Array.h:128
Various templated functions that carry out common vector operations (see Templated Utility Functions)...
Array2D & operator=(const Array2D &y)
assignment operator
Definition: Array.h:111
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:173
vector_int m_ipiv
Vector of pivots. Length is equal to the max of m and n.
Definition: DenseMatrix.h:154
This file contains definitions of terms that are used in internal routines and are unlikely to need m...
void increment(const DenseMatrix &A, const double *b, double *prod)
Multiply A*b and add it to the result in prod. Uses BLAS routine DGEMV.
int m_printLevel
Print Level.
Definition: DenseMatrix.h:175
int solve(DenseMatrix &A, double *b)
Solve Ax = b. Array b is overwritten on exit with x.
doublereal * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
Definition: Array.h:363
This file contains definitions for utility functions and text for modules, inputfiles, logs, textlogs, HTML_logs (see Input File Handling, Diagnostic Output, Writing messages to the screen and Writing HTML Logfiles).
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:33
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:167
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
Definition: DenseMatrix.cpp:71
void writelogf(const char *fmt,...)
Write a formatted message to the screen.
Definition: global.cpp:48
std::vector< doublereal * > m_colPts
Vector of column pointers.
Definition: DenseMatrix.h:157
size_t nColumns() const
Number of columns.
Definition: Array.h:322
void multiply(const DenseMatrix &A, const double *const b, double *const prod)
Multiply A*b and return the result in prod. Uses BLAS routine DGEMV.
size_t m_ncols
Number of columns.
Definition: Array.h:387
size_t m_nrows
Number of rows.
Definition: Array.h:384
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
doublereal & value(size_t i, size_t j)
Returns a changeable reference to position in the matrix.
Definition: Array.h:300
virtual void leftMult(const double *const b, double *const prod) const
Left-multiply the matrix by transpose(b), and write the result to prod.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:165
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
Contains declarations for string manipulation functions within Cantera.
Exception thrown when an LAPACK error is encountered associated with inverting or solving a matrix...
Definition: DenseMatrix.h:34
DenseMatrix()
Default Constructor.
Definition: DenseMatrix.cpp:17
int m_useReturnErrorCode
Error Handling Flag.
Definition: DenseMatrix.h:167
vector_int & ipiv()
Return a changeable value of the pivot vector.
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
Definition: DenseMatrix.h:70