queso-0.56.1
GslMatrix.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // QUESO - a library to support the Quantification of Uncertainty
5 // for Estimation, Simulation and Optimization
6 //
7 // Copyright (C) 2008-2015 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 #include <queso/GslMatrix.h>
26 #include <queso/GslVector.h>
27 #include <queso/Defines.h>
28 #include <gsl/gsl_linalg.h>
29 #include <gsl/gsl_eigen.h>
30 #include <sys/time.h>
31 #include <cmath>
32 
33 namespace QUESO {
34 
35 GslMatrix::GslMatrix( // can be a rectangular matrix
36  const BaseEnvironment& env,
37  const Map& map,
38  unsigned int nCols)
39  :
40  Matrix (env,map),
41  m_mat (gsl_matrix_calloc(map.NumGlobalElements(),nCols)),
42  m_LU (NULL),
43  m_inverse (NULL),
44  m_svdColMap (NULL),
45  m_svdUmat (NULL),
46  m_svdSvec (NULL),
47  m_svdVmat (NULL),
48  m_svdVTmat (NULL),
49  m_determinant (-INFINITY),
50  m_lnDeterminant(-INFINITY),
51  m_permutation (NULL),
52  m_signum (0),
53  m_isSingular (false)
54 {
55  queso_require_msg(m_mat, "null matrix generated");
56 }
57 
58 // Shaped constructor --------------------------------------------------
59 GslMatrix::GslMatrix( // square matrix
60  const BaseEnvironment& env,
61  const Map& map,
62  double diagValue)
63  :
64  Matrix (env,map),
65  m_mat (gsl_matrix_calloc(map.NumGlobalElements(),map.NumGlobalElements())),
66  m_LU (NULL),
67  m_inverse (NULL),
68  m_svdColMap (NULL),
69  m_svdUmat (NULL),
70  m_svdSvec (NULL),
71  m_svdVmat (NULL),
72  m_svdVTmat (NULL),
73  m_determinant (-INFINITY),
74  m_lnDeterminant(-INFINITY),
75  m_permutation (NULL),
76  m_signum (0),
77  m_isSingular (false)
78 {
79  queso_require_msg(m_mat, "null matrix generated");
80 
81  for (unsigned int i = 0; i < m_mat->size1; ++i) {
82  (*this)(i,i) = diagValue;
83  }
84 }
85 // Shaped constructor --------------------------------------------------
86 GslMatrix::GslMatrix( // square matrix
87  const GslVector& v,
88  double diagValue)
89  :
90  Matrix (v.env(),v.map()),
91  m_mat (gsl_matrix_calloc(v.sizeLocal(),v.sizeLocal())),
92  m_LU (NULL),
93  m_inverse (NULL),
94  m_svdColMap (NULL),
95  m_svdUmat (NULL),
96  m_svdSvec (NULL),
97  m_svdVmat (NULL),
98  m_svdVTmat (NULL),
99  m_determinant (-INFINITY),
100  m_lnDeterminant(-INFINITY),
101  m_permutation (NULL),
102  m_signum (0),
103  m_isSingular (false)
104 {
105  queso_require_msg(m_mat, "null matrix generated");
106 
107  for (unsigned int i = 0; i < m_mat->size1; ++i) {
108  (*this)(i,i) = diagValue;
109  }
110 }
111 // Shaped constructor --------------------------------------------------
112 GslMatrix::GslMatrix(const GslVector& v) // square matrix
113  :
114  Matrix (v.env(),v.map()),
115  m_mat (gsl_matrix_calloc(v.sizeLocal(),v.sizeLocal())),
116  m_LU (NULL),
117  m_inverse (NULL),
118  m_svdColMap (NULL),
119  m_svdUmat (NULL),
120  m_svdSvec (NULL),
121  m_svdVmat (NULL),
122  m_svdVTmat (NULL),
123  m_determinant (-INFINITY),
124  m_lnDeterminant(-INFINITY),
125  m_permutation (NULL),
126  m_signum (0),
127  m_isSingular (false)
128 {
129  queso_require_msg(m_mat, "null matrix generated");
130 
131  unsigned int dim = v.sizeLocal();
132  for (unsigned int i = 0; i < dim; ++i) {
133  (*this)(i,i) = v[i];
134  }
135 }
136 
137 // Shaped constructor --------------------------------------------------
138 GslMatrix::GslMatrix(const GslMatrix& B) // can be a rectangular matrix
139  :
140  Matrix (B.env(),B.map()),
141  m_mat (gsl_matrix_calloc(B.numRowsLocal(),B.numCols())),
142  m_LU (NULL),
143  m_inverse (NULL),
144  m_svdColMap (NULL),
145  m_svdUmat (NULL),
146  m_svdSvec (NULL),
147  m_svdVmat (NULL),
148  m_svdVTmat (NULL),
149  m_determinant (-INFINITY),
150  m_lnDeterminant(-INFINITY),
151  m_permutation (NULL),
152  m_signum (0),
153  m_isSingular (false)
154 {
155  queso_require_msg(m_mat, "null vector generated");
156  this->Matrix::base_copy(B);
157  this->copy(B);
158 }
159 
160 // Destructor ----------------------------------------------------------
162 {
163  this->resetLU();
164  if (m_mat) gsl_matrix_free(m_mat);
165 }
166 
167 // Set methods (operators) ---------------------------------------------
168 GslMatrix&
170 {
171  this->resetLU();
172  this->copy(obj);
173  return *this;
174 }
175 
176 GslMatrix&
178 {
179  this->resetLU();
180  int iRC;
181  iRC = gsl_matrix_scale(m_mat,a);
182  queso_require_msg(!(iRC), "scaling failed");
183  return *this;
184 }
185 
186 GslMatrix&
188 {
189  this->resetLU();
190  *this *= (1./a);
191 
192  return *this;
193 }
194 
195 GslMatrix&
197 {
198  this->resetLU();
199  int iRC;
200  iRC = gsl_matrix_add(m_mat,rhs.m_mat);
201  queso_require_msg(!(iRC), "failed");
202 
203  return *this;
204 }
205 
206 GslMatrix&
208 {
209  this->resetLU();
210  int iRC;
211  iRC = gsl_matrix_sub(m_mat,rhs.m_mat);
212  queso_require_msg(!(iRC), "failed");
213 
214  return *this;
215 }
216 
217 
218 
219 void
221 {
222  // FIXME - should we be calling Matrix::base_copy here? - RHS
223  this->resetLU();
224  int iRC;
225  iRC = gsl_matrix_memcpy(this->m_mat, src.m_mat);
226  queso_require_msg(!(iRC), "failed");
227 
228  return;
229 }
230 
231 void
233 {
234  if (m_LU) {
235  gsl_matrix_free(m_LU);
236  m_LU = NULL;
237  }
238  if (m_inverse) {
239  delete m_inverse;
240  m_inverse = NULL;
241  }
242  if (m_svdColMap) {
243  delete m_svdColMap;
244  m_svdColMap = NULL;
245  }
246  if (m_svdUmat) {
247  delete m_svdUmat;
248  m_svdUmat = NULL;
249  }
250  if (m_svdSvec) {
251  delete m_svdSvec;
252  m_svdSvec = NULL;
253  }
254  if (m_svdVmat) {
255  delete m_svdVmat;
256  m_svdVmat = NULL;
257  }
258  if (m_svdVTmat) {
259  delete m_svdVTmat;
260  m_svdVTmat = NULL;
261  }
262  m_determinant = -INFINITY;
263  m_lnDeterminant = -INFINITY;
264  if (m_permutation) {
265  gsl_permutation_free(m_permutation);
266  m_permutation = NULL;
267  }
268  m_signum = 0;
269  m_isSingular = false;
270 
271  return;
272 }
273 
274 unsigned int
276 {
277  return m_mat->size1;
278 }
279 
280 unsigned int
282 {
283  return m_mat->size1;
284 }
285 
286 unsigned int
288 {
289  return m_mat->size2;
290 }
291 
292 double
294 {
295  double value = 0.;
296 
297  unsigned int nRows = this->numRowsLocal();
298  unsigned int nCols = this->numCols();
299  double aux = 0.;
300  for (unsigned int i = 0; i < nRows; i++) {
301  for (unsigned int j = 0; j < nCols; j++) {
302  aux = (*this)(i,j);
303  value += aux*aux;
304  }
305  }
306 
307  return sqrt(value);
308 }
309 
310 double
312 {
313  double value = 0.;
314 
315  unsigned int nRows = this->numRowsLocal();
316  unsigned int nCols = this->numCols();
317  double aux = 0.;
318  for (unsigned int i = 0; i < nRows; i++) {
319  for (unsigned int j = 0; j < nCols; j++) {
320  aux = fabs((*this)(i,j));
321  if (aux > value) value = aux;
322  }
323  }
324 
325  return value;
326 }
327 
328 double
330 {
331  double value = -INFINITY;
332 
333  unsigned int nRows = this->numRowsLocal();
334  unsigned int nCols = this->numCols();
335  double aux = 0.;
336  for (unsigned int i = 0; i < nRows; i++) {
337  for (unsigned int j = 0; j < nCols; j++) {
338  aux = (*this)(i,j);
339  if (aux > value) value = aux;
340  }
341  }
342 
343  return value;
344 }
345 
346 void
347 GslMatrix::cwSet(double value)
348 {
349  unsigned int nRows = this->numRowsLocal();
350  unsigned int nCols = this->numCols();
351 
352  for (unsigned int row = 0; row < nRows; ++row) {
353  for (unsigned int col = 0; col < nCols; ++col) {
354  *gsl_matrix_ptr(m_mat,row,col) = value;
355  }
356  }
357 
358  return;
359 }
360 
361 void
363  unsigned int initialTargetRowId,
364  unsigned int initialTargetColId,
365  const GslMatrix& mat)
366 {
367  queso_require_less_msg(initialTargetRowId, this->numRowsLocal(), "invalid initialTargetRowId");
368 
369  queso_require_less_equal_msg((initialTargetRowId + mat.numRowsLocal()), this->numRowsLocal(), "invalid vec.numRowsLocal()");
370 
371  queso_require_less_msg(initialTargetColId, this->numCols(), "invalid initialTargetColId");
372 
373  queso_require_less_equal_msg((initialTargetColId + mat.numCols()), this->numCols(), "invalid vec.numCols()");
374 
375  for (unsigned int i = 0; i < mat.numRowsLocal(); ++i) {
376  for (unsigned int j = 0; j < mat.numCols(); ++j) {
377  (*this)(initialTargetRowId+i,initialTargetColId+j) = mat(i,j);
378  }
379  }
380 
381  return;
382 }
383 
384 void
386  unsigned int initialTargetRowId,
387  unsigned int initialTargetColId,
388  GslMatrix& mat) const
389 {
390  queso_require_less_msg(initialTargetRowId, this->numRowsLocal(), "invalid initialTargetRowId");
391 
392  queso_require_less_equal_msg((initialTargetRowId + mat.numRowsLocal()), this->numRowsLocal(), "invalid vec.numRowsLocal()");
393 
394  queso_require_less_msg(initialTargetColId, this->numCols(), "invalid initialTargetColId");
395 
396  queso_require_less_equal_msg((initialTargetColId + mat.numCols()), this->numCols(), "invalid vec.numCols()");
397 
398  for (unsigned int i = 0; i < mat.numRowsLocal(); ++i) {
399  for (unsigned int j = 0; j < mat.numCols(); ++j) {
400  mat(i,j) = (*this)(initialTargetRowId+i,initialTargetColId+j) ;
401  }
402  }
403 
404  return;
405 }
406 
407 int
409 {
410  int iRC;
411  //std::cout << "Calling gsl_linalg_cholesky_decomp()..." << std::endl;
412  gsl_error_handler_t* oldHandler;
413  oldHandler = gsl_set_error_handler_off();
414  iRC = gsl_linalg_cholesky_decomp(m_mat);
415  if (iRC != 0) {
416  std::cerr << "In GslMatrix::chol()"
417  << ": iRC = " << iRC
418  << ", gsl error message = " << gsl_strerror(iRC)
419  << std::endl;
420  std::cerr << "Here is the offending matrix: " << std::endl;
421  std::cerr << *this << std::endl;
422  }
423  gsl_set_error_handler(oldHandler);
424  //std::cout << "Returned from gsl_linalg_cholesky_decomp() with iRC = " << iRC << std::endl;
425  UQ_RC_MACRO(iRC, // Yes, *not* a fatal check on RC
426  m_env.worldRank(),
427  "GslMatrix::chol()",
428  "matrix is not positive definite",
430 
431  return iRC;
432 }
433 
434 int
435 GslMatrix::svd(GslMatrix& matU, GslVector& vecS, GslMatrix& matVt) const
436 {
437  unsigned int nRows = this->numRowsLocal();
438  unsigned int nCols = this->numCols();
439 
440  queso_require_msg(!((matU.numRowsLocal() != nRows) || (matU.numCols() != nCols)), "invalid matU");
441 
442  queso_require_equal_to_msg(vecS.sizeLocal(), nCols, "invalid vecS");
443 
444  queso_require_msg(!((matVt.numRowsLocal() != nCols) || (matVt.numCols() != nCols)), "invalid matVt");
445 
446  int iRC = internalSvd();
447 
448  matU = *m_svdUmat;
449  vecS = *m_svdSvec;
450  matVt = *m_svdVTmat;
451 
452  return iRC;
453 }
454 
455 int
456 GslMatrix::svdSolve(const GslVector& rhsVec, GslVector& solVec) const
457 {
458  unsigned int nRows = this->numRowsLocal();
459  unsigned int nCols = this->numCols();
460 
461  queso_require_equal_to_msg(rhsVec.sizeLocal(), nRows, "invalid rhsVec");
462 
463  queso_require_equal_to_msg(solVec.sizeLocal(), nCols, "invalid solVec");
464 
465  int iRC = internalSvd();
466 
467  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
468  *m_env.subDisplayFile() << "In GslMatrix::svdSolve():"
469  << "\n this->numRowsLocal() = " << this->numRowsLocal()
470  << ", this->numCols() = " << this->numCols()
471  << "\n m_svdUmat->numRowsLocal() = " << m_svdUmat->numRowsLocal()
472  << ", m_svdUmat->numCols() = " << m_svdUmat->numCols()
473  << "\n m_svdVmat->numRowsLocal() = " << m_svdVmat->numRowsLocal()
474  << ", m_svdVmat->numCols() = " << m_svdVmat->numCols()
475  << "\n m_svdSvec->sizeLocal() = " << m_svdSvec->sizeLocal()
476  << "\n rhsVec.sizeLocal() = " << rhsVec.sizeLocal()
477  << "\n solVec.sizeLocal() = " << solVec.sizeLocal()
478  << std::endl;
479  }
480 
481  if (iRC == 0) iRC = gsl_linalg_SV_solve(m_svdUmat->data(), m_svdVmat->data(), m_svdSvec->data(), rhsVec.data(), solVec.data());
482 
483  return iRC;
484 }
485 
486 int
487 GslMatrix::svdSolve(const GslMatrix& rhsMat, GslMatrix& solMat) const
488 {
489  unsigned int nRows = this->numRowsLocal();
490  unsigned int nCols = this->numCols();
491 
492  queso_require_equal_to_msg(rhsMat.numRowsLocal(), nRows, "invalid rhsMat");
493 
494  queso_require_equal_to_msg(solMat.numRowsLocal(), nCols, "invalid solMat");
495 
496  queso_require_equal_to_msg(rhsMat.numCols(), solMat.numCols(), "rhsMat and solMat are not compatible");
497 
498  GslVector rhsVec(m_env,rhsMat.map());
499  GslVector solVec(m_env,solMat.map());
500  int iRC = 0;
501  for (unsigned int j = 0; j < rhsMat.numCols(); ++j) {
502  rhsVec = rhsMat.getColumn(j);
503  iRC = this->svdSolve(rhsVec, solVec);
504  if (iRC) break;
505  solMat.setColumn(j,solVec);
506  }
507 
508  return iRC;
509 }
510 
511 const GslMatrix&
513 {
514  int iRC = 0;
515  iRC = internalSvd();
516  if (iRC) {}; // just to remove compiler warning
517 
518  return *m_svdUmat;
519 }
520 
521 const GslMatrix&
523 {
524  int iRC = 0;
525  iRC = internalSvd();
526  if (iRC) {}; // just to remove compiler warning
527 
528  return *m_svdVmat;
529 }
530 
531 int
533 {
534  int iRC = 0;
535 
536  if (m_svdColMap == NULL) {
537  unsigned int nRows = this->numRowsLocal();
538  unsigned int nCols = this->numCols();
539  queso_require_greater_equal_msg(nRows, nCols, "GSL only supports cases where nRows >= nCols");
540 
541  m_svdColMap = new Map(this->numCols(),0,this->map().Comm()); // see 'VectorSpace<.,.>::newMap()' in src/basic/src/GslVectorSpace.C
542  m_svdUmat = new GslMatrix(*this); // Yes, 'this'
544  m_svdVmat = new GslMatrix(*m_svdSvec);
546 
547  //std::cout << "In GslMatrix::internalSvd()"
548  // << ", calling gsl_linalg_SV_decomp_jacobi()..."
549  // << ": nRows = " << nRows
550  // << ", nCols = " << nCols
551  // << std::endl;
552  struct timeval timevalBegin;
553  gettimeofday(&timevalBegin, NULL);
554  gsl_error_handler_t* oldHandler;
555  oldHandler = gsl_set_error_handler_off();
556 #if 1
557  iRC = gsl_linalg_SV_decomp_jacobi(m_svdUmat->data(), m_svdVmat->data(), m_svdSvec->data());
558 #else
559  GslVector vecWork(*m_svdSvec );
560  iRC = gsl_linalg_SV_decomp(m_svdUmat->data(), m_svdVmat->data(), m_svdSvec->data(), vecWork.data());
561 #endif
562  if (iRC != 0) {
563  std::cerr << "In GslMatrix::internalSvd()"
564  << ": iRC = " << iRC
565  << ", gsl error message = " << gsl_strerror(iRC)
566  << std::endl;
567  }
568  gsl_set_error_handler(oldHandler);
569 
570  struct timeval timevalNow;
571  gettimeofday(&timevalNow, NULL);
572  //std::cout << "In GslMatrix::internalSvd()"
573  // << ": returned from gsl_linalg_SV_decomp_jacobi() with iRC = " << iRC
574  // << " after " << timevalNow.tv_sec - timevalBegin.tv_sec
575  // << " seconds"
576  // << std::endl;
577  UQ_RC_MACRO(iRC, // Yes, *not* a fatal check on RC
578  m_env.worldRank(),
579  "GslMatrix::internalSvd()",
580  "matrix svd failed",
583  }
584 
585  return iRC;
586 }
587 
588 
589 
590 void
591 GslMatrix::zeroLower(bool includeDiagonal)
592 {
593  unsigned int nRows = this->numRowsLocal();
594  unsigned int nCols = this->numCols();
595 
596  queso_require_equal_to_msg(nRows, nCols, "routine works only for square matrices");
597 
598  this->resetLU();
599 
600  if (includeDiagonal) {
601  for (unsigned int i = 0; i < nRows; i++) {
602  for (unsigned int j = 0; j <= i; j++) {
603  (*this)(i,j) = 0.;
604  }
605  }
606  }
607  else {
608  for (unsigned int i = 0; i < nRows; i++) {
609  for (unsigned int j = 0; j < i; j++) {
610  (*this)(i,j) = 0.;
611  }
612  }
613  }
614 
615  return;
616 }
617 
618 void
619 GslMatrix::zeroUpper(bool includeDiagonal)
620 {
621  unsigned int nRows = this->numRowsLocal();
622  unsigned int nCols = this->numCols();
623 
624  queso_require_equal_to_msg(nRows, nCols, "routine works only for square matrices");
625 
626  this->resetLU();
627 
628  if (includeDiagonal) {
629  for (unsigned int i = 0; i < nRows; i++) {
630  for (unsigned int j = i; j < nCols; j++) {
631  (*this)(i,j) = 0.;
632  }
633  }
634  }
635  else {
636  for (unsigned int i = 0; i < nRows; i++) {
637  for (unsigned int j = (i+1); j < nCols; j++) {
638  (*this)(i,j) = 0.;
639  }
640  }
641  }
642 
643  return;
644 }
645 
646 void
647 GslMatrix::filterSmallValues(double thresholdValue)
648 {
649  unsigned int nRows = this->numRowsLocal();
650  unsigned int nCols = this->numCols();
651  for (unsigned int i = 0; i < nRows; ++i) {
652  for (unsigned int j = 0; j < nCols; ++j) {
653  double aux = (*this)(i,j);
654  // If 'thresholdValue' is negative, no values will be filtered
655  if ((aux < 0. ) &&
656  (-thresholdValue < aux)) {
657  (*this)(i,j) = 0.;
658  }
659  if ((aux > 0. ) &&
660  (thresholdValue > aux)) {
661  (*this)(i,j) = 0.;
662  }
663  }
664  }
665 
666  return;
667 }
668 
669 void
670 GslMatrix::filterLargeValues(double thresholdValue)
671 {
672  unsigned int nRows = this->numRowsLocal();
673  unsigned int nCols = this->numCols();
674  for (unsigned int i = 0; i < nRows; ++i) {
675  for (unsigned int j = 0; j < nCols; ++j) {
676  double aux = (*this)(i,j);
677  // If 'thresholdValue' is negative, no values will be filtered
678  if ((aux < 0. ) &&
679  (-thresholdValue > aux)) {
680  (*this)(i,j) = 0.;
681  }
682  if ((aux > 0. ) &&
683  (thresholdValue < aux)) {
684  (*this)(i,j) = 0.;
685  }
686  }
687  }
688 
689  return;
690 }
691 
692 GslMatrix
694 {
695  unsigned int nRows = this->numRowsGlobal();
696  unsigned int nCols = this->numCols();
697 
698  const MpiComm & comm = this->map().Comm();
699  Map serial_map(nCols, 0, comm);
700 
701  GslMatrix mat(m_env,serial_map,nRows);
702 
703  for (unsigned int row = 0; row < nRows; ++row) {
704  for (unsigned int col = 0; col < nCols; ++col) {
705  mat(col,row) = (*this)(row,col);
706  }
707  }
708 
709  return mat;
710 }
711 
712 GslMatrix
714 {
715  unsigned int nRows = this->numRowsLocal();
716  unsigned int nCols = this->numCols();
717 
718  queso_require_equal_to_msg(nRows, nCols, "matrix is not square");
719 
720  if (m_inverse == NULL) {
721  m_inverse = new GslMatrix(m_env,m_map,nCols);
722  GslVector unitVector(m_env,m_map);
723  unitVector.cwSet(0.);
724  GslVector multVector(m_env,m_map);
725  for (unsigned int j = 0; j < nCols; ++j) {
726  if (j > 0) unitVector[j-1] = 0.;
727  unitVector[j] = 1.;
728  this->invertMultiply(unitVector, multVector);
729  for (unsigned int i = 0; i < nRows; ++i) {
730  (*m_inverse)(i,j) = multVector[i];
731  }
732  }
733  }
734  if (m_env.checkingLevel() >= 1) {
735  *m_env.subDisplayFile() << "CHECKING In GslMatrix::inverse()"
736  << ": M.lnDet = " << this->lnDeterminant()
737  << ", M^{-1}.lnDet = " << m_inverse->lnDeterminant()
738  << std::endl;
739  }
740  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
741  *m_env.subDisplayFile() << "In GslMatrix::inverse():"
742  << "\n M = " << *this
743  << "\n M^{-1} = " << *m_inverse
744  << "\n M*M^{-1} = " << (*this)*(*m_inverse)
745  << "\n M^{-1}*M = " << (*m_inverse)*(*this)
746  << std::endl;
747  }
748 
749  return *m_inverse;
750 }
751 
752 void
754  unsigned int initialTargetRowId,
755  unsigned int initialTargetColId,
756  const std::vector<const GslMatrix* >& matrices,
757  bool checkForExactNumRowsMatching,
758  bool checkForExactNumColsMatching)
759 {
760  unsigned int sumNumRowsLocals = 0;
761  unsigned int sumNumCols = 0;
762  for (unsigned int i = 0; i < matrices.size(); ++i) {
763  sumNumRowsLocals += matrices[i]->numRowsLocal();
764  sumNumCols += matrices[i]->numCols();
765  }
766  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "too big number of rows");
767  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "inconsistent number of rows");
768  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
769  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
770 
771  unsigned int cumulativeRowId = 0;
772  unsigned int cumulativeColId = 0;
773  for (unsigned int i = 0; i < matrices.size(); ++i) {
774  unsigned int nRows = matrices[i]->numRowsLocal();
775  unsigned int nCols = matrices[i]->numCols();
776  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
777  for (unsigned int colId = 0; colId < nCols; ++colId) {
778  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
779  }
780  }
781  cumulativeRowId += nRows;
782  cumulativeColId += nCols;
783  }
784 
785  return;
786 }
787 
788 void
790  unsigned int initialTargetRowId,
791  unsigned int initialTargetColId,
792  const std::vector<GslMatrix* >& matrices,
793  bool checkForExactNumRowsMatching,
794  bool checkForExactNumColsMatching)
795 {
796  unsigned int sumNumRowsLocals = 0;
797  unsigned int sumNumCols = 0;
798  for (unsigned int i = 0; i < matrices.size(); ++i) {
799  sumNumRowsLocals += matrices[i]->numRowsLocal();
800  sumNumCols += matrices[i]->numCols();
801  }
802  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "too big number of rows");
803  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "inconsistent number of rows");
804  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
805  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
806 
807  unsigned int cumulativeRowId = 0;
808  unsigned int cumulativeColId = 0;
809  for (unsigned int i = 0; i < matrices.size(); ++i) {
810  unsigned int nRows = matrices[i]->numRowsLocal();
811  unsigned int nCols = matrices[i]->numCols();
812  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
813  for (unsigned int colId = 0; colId < nCols; ++colId) {
814  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
815  }
816  }
817  cumulativeRowId += nRows;
818  cumulativeColId += nCols;
819  }
820 
821  return;
822 }
823 
824 void
826  unsigned int initialTargetRowId,
827  unsigned int initialTargetColId,
828  const std::vector<const GslMatrix* >& matrices,
829  bool checkForExactNumRowsMatching,
830  bool checkForExactNumColsMatching)
831 {
832  unsigned int sumNumCols = 0;
833  for (unsigned int i = 0; i < matrices.size(); ++i) {
834  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "too big number of rows");
835  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "inconsistent number of rows");
836  sumNumCols += matrices[i]->numCols();
837  }
838  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
839  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
840 
841  unsigned int cumulativeColId = 0;
842  for (unsigned int i = 0; i < matrices.size(); ++i) {
843  unsigned int nRows = matrices[i]->numRowsLocal();
844  unsigned int nCols = matrices[i]->numCols();
845  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
846  for (unsigned int colId = 0; colId < nCols; ++colId) {
847  (*this)(initialTargetRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
848  }
849  }
850  cumulativeColId += nCols;
851  }
852 
853  return;
854 }
855 
856 void
858  unsigned int initialTargetRowId,
859  unsigned int initialTargetColId,
860  const std::vector<GslMatrix* >& matrices,
861  bool checkForExactNumRowsMatching,
862  bool checkForExactNumColsMatching)
863 {
864  unsigned int sumNumCols = 0;
865  for (unsigned int i = 0; i < matrices.size(); ++i) {
866  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "too big number of rows");
867  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "inconsistent number of rows");
868  sumNumCols += matrices[i]->numCols();
869  }
870  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
871  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
872 
873  unsigned int cumulativeColId = 0;
874  for (unsigned int i = 0; i < matrices.size(); ++i) {
875  unsigned int nRows = matrices[i]->numRowsLocal();
876  unsigned int nCols = matrices[i]->numCols();
877  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
878  for (unsigned int colId = 0; colId < nCols; ++colId) {
879  (*this)(initialTargetRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
880  }
881  }
882  cumulativeColId += nCols;
883  }
884 
885  return;
886 }
887 
888 void
890  unsigned int initialTargetRowId,
891  unsigned int initialTargetColId,
892  const std::vector<const GslMatrix* >& matrices,
893  bool checkForExactNumRowsMatching,
894  bool checkForExactNumColsMatching)
895 {
896  unsigned int sumNumRows = 0;
897  for (unsigned int i = 0; i < matrices.size(); ++i) {
898  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "too big number of cols");
899  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "inconsistent number of cols");
900  sumNumRows += matrices[i]->numRowsLocal();
901  }
902  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "too big number of rows");
903  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "inconsistent number of rows");
904 
905  unsigned int cumulativeRowId = 0;
906  for (unsigned int i = 0; i < matrices.size(); ++i) {
907  unsigned int nRows = matrices[i]->numRowsLocal();
908  unsigned int nCols = matrices[i]->numCols();
909  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
910  for (unsigned int colId = 0; colId < nCols; ++colId) {
911  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + colId) = (*(matrices[i]))(rowId,colId);
912  }
913  }
914  cumulativeRowId += nRows;
915  }
916 
917  return;
918 }
919 
920 void
922  unsigned int initialTargetRowId,
923  unsigned int initialTargetColId,
924  const std::vector<GslMatrix* >& matrices,
925  bool checkForExactNumRowsMatching,
926  bool checkForExactNumColsMatching)
927 {
928  unsigned int sumNumRows = 0;
929  for (unsigned int i = 0; i < matrices.size(); ++i) {
930  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "too big number of cols");
931  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "inconsistent number of cols");
932  sumNumRows += matrices[i]->numRowsLocal();
933  }
934  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "too big number of rows");
935  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "inconsistent number of rows");
936 
937  unsigned int cumulativeRowId = 0;
938  for (unsigned int i = 0; i < matrices.size(); ++i) {
939  unsigned int nRows = matrices[i]->numRowsLocal();
940  unsigned int nCols = matrices[i]->numCols();
941  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
942  for (unsigned int colId = 0; colId < nCols; ++colId) {
943  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + colId) = (*(matrices[i]))(rowId,colId);
944  }
945  }
946  cumulativeRowId += nRows;
947  }
948 
949  return;
950 }
951 
952 void
954  unsigned int initialTargetRowId,
955  unsigned int initialTargetColId,
956  const GslMatrix& mat1,
957  const GslMatrix& mat2,
958  bool checkForExactNumRowsMatching,
959  bool checkForExactNumColsMatching)
960 {
961  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * mat2.numRowsLocal())), "too big number of rows");
962  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * mat2.numRowsLocal())), "inconsistent number of rows");
963  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * mat2.numCols())), "too big number of columns");
964  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * mat2.numCols())), "inconsistent number of columns");
965 
966  for (unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
967  for (unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
968  double multiplicativeFactor = mat1(rowId1,colId1);
969  unsigned int targetRowId = rowId1 * mat2.numRowsLocal();
970  unsigned int targetColId = colId1 * mat2.numCols();
971  for (unsigned int rowId2 = 0; rowId2 < mat2.numRowsLocal(); ++rowId2) {
972  for (unsigned int colId2 = 0; colId2 < mat2.numCols(); ++colId2) {
973  (*this)(initialTargetRowId + targetRowId + rowId2, initialTargetColId + targetColId + colId2) = multiplicativeFactor * mat2(rowId2,colId2);
974  }
975  }
976  }
977  }
978 
979  return;
980 }
981 
982 void
984  unsigned int initialTargetRowId,
985  unsigned int initialTargetColId,
986  const GslMatrix& mat1,
987  const GslVector& vec2,
988  bool checkForExactNumRowsMatching,
989  bool checkForExactNumColsMatching)
990 {
991  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * vec2.sizeLocal())), "too big number of rows");
992  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * vec2.sizeLocal())), "inconsistent number of rows");
993  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * 1)), "too big number of columns");
994  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * 1)), "inconsistent number of columns");
995 
996  for (unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
997  for (unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
998  double multiplicativeFactor = mat1(rowId1,colId1);
999  unsigned int targetRowId = rowId1 * vec2.sizeLocal();
1000  unsigned int targetColId = colId1 * 1;
1001  for (unsigned int rowId2 = 0; rowId2 < vec2.sizeLocal(); ++rowId2) {
1002  for (unsigned int colId2 = 0; colId2 < 1; ++colId2) {
1003  (*this)(initialTargetRowId + targetRowId + rowId2, initialTargetColId + targetColId + colId2) = multiplicativeFactor * vec2[rowId2];
1004  }
1005  }
1006  }
1007  }
1008 
1009 
1010  return;
1011 }
1012 
1013 void
1015  unsigned int initialTargetRowId,
1016  unsigned int initialTargetColId,
1017  const GslMatrix& mat,
1018  bool checkForExactNumRowsMatching,
1019  bool checkForExactNumColsMatching)
1020 {
1021  unsigned int nRows = mat.numRowsLocal();
1022  unsigned int nCols = mat.numCols();
1023  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + nCols), "too big number of rows");
1024  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + nCols), "inconsistent number of rows");
1025  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + nRows), "too big number of cols");
1026  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + nRows), "inconsistent number of cols");
1027 
1028  for (unsigned int row = 0; row < nRows; ++row) {
1029  for (unsigned int col = 0; col < nCols; ++col) {
1030  (*this)(initialTargetRowId + col, initialTargetColId + row) = mat(row,col);
1031  }
1032  }
1033 
1034  return;
1035 }
1036 
1037 double
1039 {
1040  if (m_determinant == -INFINITY) {
1041  if (m_LU == NULL) {
1042  GslVector tmpB(m_env,m_map);
1043  GslVector tmpX(m_env,m_map);
1044  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1045  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1046  << ": before 'this->invertMultiply()'"
1047  << std::endl;
1048  }
1049  this->invertMultiply(tmpB,tmpX);
1050  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1051  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1052  << ": after 'this->invertMultiply()'"
1053  << std::endl;
1054  }
1055  }
1056  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1057  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1058  << ": before 'gsl_linalg_LU_det()'"
1059  << std::endl;
1060  }
1061  m_determinant = gsl_linalg_LU_det(m_LU,m_signum);
1062  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1063  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1064  << ": after 'gsl_linalg_LU_det()'"
1065  << std::endl;
1066  }
1067  m_lnDeterminant = gsl_linalg_LU_lndet(m_LU);
1068  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1069  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1070  << ": after 'gsl_linalg_LU_lndet()'"
1071  << std::endl;
1072  }
1073  }
1074 
1075  return m_determinant;
1076 }
1077 
1078 double
1080 {
1081  if (m_lnDeterminant == -INFINITY) {
1082  if (m_LU == NULL) {
1083  GslVector tmpB(m_env,m_map);
1084  GslVector tmpX(m_env,m_map);
1085  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1086  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1087  << ": before 'this->invertMultiply()'"
1088  << std::endl;
1089  }
1090  this->invertMultiply(tmpB,tmpX);
1091  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1092  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1093  << ": after 'this->invertMultiply()'"
1094  << std::endl;
1095  }
1096  }
1097  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1098  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1099  << ": before 'gsl_linalg_LU_det()'"
1100  << std::endl;
1101  }
1102  m_determinant = gsl_linalg_LU_det(m_LU,m_signum);
1103  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1104  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1105  << ": after 'gsl_linalg_LU_det()'"
1106  << std::endl;
1107  }
1108  m_lnDeterminant = gsl_linalg_LU_lndet(m_LU);
1109  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1110  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1111  << ": before 'gsl_linalg_LU_lndet()'"
1112  << std::endl;
1113  }
1114  }
1115 
1116  return m_lnDeterminant;
1117 }
1118 
1119 unsigned int
1120 GslMatrix::rank(double absoluteZeroThreshold, double relativeZeroThreshold) const
1121 {
1122  int iRC = 0;
1123  iRC = internalSvd();
1124  if (iRC) {}; // just to remove compiler warning
1125 
1126  GslVector relativeVec(*m_svdSvec);
1127  if (relativeVec[0] > 0.) {
1128  relativeVec = (1./relativeVec[0])*relativeVec;
1129  }
1130 
1131  unsigned int rankValue = 0;
1132  for (unsigned int i = 0; i < relativeVec.sizeLocal(); ++i) {
1133  if (( (*m_svdSvec)[i] >= absoluteZeroThreshold ) &&
1134  ( relativeVec [i] >= relativeZeroThreshold )) {
1135  rankValue += 1;
1136  }
1137  }
1138 
1139  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 3)) {
1140  *m_env.subDisplayFile() << "In GslMatrix::rank()"
1141  << ": this->numRowsLocal() = " << this->numRowsLocal()
1142  << ", this->numCols() = " << this->numCols()
1143  << ", absoluteZeroThreshold = " << absoluteZeroThreshold
1144  << ", relativeZeroThreshold = " << relativeZeroThreshold
1145  << ", rankValue = " << rankValue
1146  << ", m_svdSvec = " << *m_svdSvec
1147  << ", relativeVec = " << relativeVec
1148  << std::endl;
1149  }
1150 
1151  return rankValue;
1152 }
1153 
1154 GslVector
1156  const GslVector& x) const
1157 {
1158  queso_require_equal_to_msg(this->numCols(), x.sizeLocal(), "matrix and vector have incompatible sizes");
1159 
1160  GslVector y(m_env,m_map);
1161  this->multiply(x,y);
1162 
1163  return y;
1164 }
1165 
1166 void
1168  const GslVector& x,
1169  GslVector& y) const
1170 {
1171  queso_require_equal_to_msg(this->numCols(), x.sizeLocal(), "matrix and x have incompatible sizes");
1172 
1173  queso_require_equal_to_msg(this->numRowsLocal(), y.sizeLocal(), "matrix and y have incompatible sizes");
1174 
1175  unsigned int sizeX = this->numCols();
1176  unsigned int sizeY = this->numRowsLocal();
1177  for (unsigned int i = 0; i < sizeY; ++i) {
1178  double value = 0.;
1179  for (unsigned int j = 0; j < sizeX; ++j) {
1180  value += (*this)(i,j)*x[j];
1181  }
1182  y[i] = value;
1183  }
1184 
1185  return;
1186 }
1187 
1188 GslMatrix
1190  const GslMatrix & X) const
1191 {
1192  GslMatrix Y(m_env,m_map,X.numCols());
1193  this->multiply(X,Y);
1194 
1195  return Y;
1196 }
1197 
1198 
1199 
1200 void
1202  const GslMatrix & X,
1203  GslMatrix & Y) const
1204 {
1205  queso_require_equal_to_msg(this->numCols(), X.numRowsGlobal(), "matrix and X have incompatible sizes");
1206  queso_require_equal_to_msg(this->numRowsGlobal(), Y.numRowsGlobal(), "matrix and Y have incompatible sizes");
1207  queso_require_equal_to_msg(X.numCols(), Y.numCols(), "X and Y have incompatible sizes");
1208 
1209  const unsigned int m_s = this->numRowsGlobal();
1210  const unsigned int p_s = this->numCols();
1211  const unsigned int n_s = X.numCols();
1212 
1213  for (unsigned int k=0; k<p_s; k++)
1214  for (unsigned int j=0; j<n_s; j++)
1215  if (X(k,j) != 0.)
1216  for (unsigned int i=0; i<m_s; i++)
1217  Y(i,j) += (*this)(i,k) * X(k,j);
1218 }
1219 
1220 
1221 GslVector
1223  const GslVector& b) const
1224 {
1225  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1226 
1227  GslVector x(m_env,m_map);
1228  this->invertMultiply(b,x);
1229 
1230  return x;
1231 }
1232 
1233 void
1235  const GslVector& b,
1236  GslVector& x) const
1237 {
1238  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1239 
1240  queso_require_equal_to_msg(x.sizeLocal(), b.sizeLocal(), "solution and rhs have incompatible sizes");
1241 
1242  int iRC;
1243  if (m_LU == NULL) {
1244  queso_require_msg(!(m_permutation), "m_permutation should be NULL");
1245 
1246  m_LU = gsl_matrix_calloc(this->numRowsLocal(),this->numCols());
1247  queso_require_msg(m_LU, "gsl_matrix_calloc() failed");
1248 
1249  iRC = gsl_matrix_memcpy(m_LU, m_mat);
1250  queso_require_msg(!(iRC), "gsl_matrix_memcpy() failed");
1251 
1252  m_permutation = gsl_permutation_calloc(numCols());
1253  queso_require_msg(m_permutation, "gsl_permutation_calloc() failed");
1254 
1255  if (m_inDebugMode) {
1256  std::cout << "In GslMatrix::invertMultiply()"
1257  << ": before LU decomposition, m_LU = ";
1258  gsl_matrix_fprintf(stdout, m_LU, "%f");
1259  std::cout << std::endl;
1260  }
1261 
1262  gsl_error_handler_t* oldHandler;
1263  oldHandler = gsl_set_error_handler_off();
1264  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1265  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1266  << ": before 'gsl_linalg_LU_decomp()'"
1267  << std::endl;
1268  }
1269  iRC = gsl_linalg_LU_decomp(m_LU,m_permutation,&m_signum);
1270  if (iRC != 0) {
1271  std::cerr << "In GslMatrix::invertMultiply()"
1272  << ", after gsl_linalg_LU_decomp()"
1273  << ": iRC = " << iRC
1274  << ", gsl error message = " << gsl_strerror(iRC)
1275  << std::endl;
1276  }
1277  gsl_set_error_handler(oldHandler);
1278  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1279  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1280  << ": after 'gsl_linalg_LU_decomp()'"
1281  << ", IRC = " << iRC
1282  << std::endl;
1283  }
1284  queso_require_msg(!(iRC), "gsl_linalg_LU_decomp() failed");
1285 
1286  if (m_inDebugMode) {
1287  std::cout << "In GslMatrix::invertMultiply()"
1288  << ": after LU decomposition, m_LU = ";
1289  gsl_matrix_fprintf(stdout, m_LU, "%f");
1290  std::cout << std::endl;
1291  }
1292  }
1293 
1294  gsl_error_handler_t* oldHandler;
1295  oldHandler = gsl_set_error_handler_off();
1296  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1297  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1298  << ": before 'gsl_linalg_LU_solve()'"
1299  << std::endl;
1300  }
1301  iRC = gsl_linalg_LU_solve(m_LU,m_permutation,b.data(),x.data());
1302  if (iRC != 0) {
1303  m_isSingular = true;
1304  std::cerr << "In GslMatrix::invertMultiply()"
1305  << ", after gsl_linalg_LU_solve()"
1306  << ": iRC = " << iRC
1307  << ", gsl error message = " << gsl_strerror(iRC)
1308  << std::endl;
1309  }
1310  gsl_set_error_handler(oldHandler);
1311  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1312  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1313  << ": after 'gsl_linalg_LU_solve()'"
1314  << ", IRC = " << iRC
1315  << std::endl;
1316  }
1317 
1318 
1319  // m_env.worldRank(),
1320  // "GslMatrix::invertMultiply()",
1321  // "gsl_linalg_LU_solve() failed");
1322 
1323  if (m_inDebugMode) {
1324  GslVector tmpVec(b - (*this)*x);
1325  std::cout << "In GslMatrix::invertMultiply()"
1326  << ": ||b - Ax||_2 = " << tmpVec.norm2()
1327  << ": ||b - Ax||_2/||b||_2 = " << tmpVec.norm2()/b.norm2()
1328  << std::endl;
1329  }
1330 
1331  return;
1332 }
1333 
1334 GslMatrix
1336 {
1337  GslMatrix X(m_env,m_map,B.numCols());
1338  this->invertMultiply(B,X);
1339 
1340  return X;
1341 }
1342 
1343 void
1345 {
1346  // Sanity Checks
1348  "Matrices B and X are incompatible");
1350  "Matrices B and X are incompatible");
1352  "This and X matrices are incompatible");
1353 
1354  // Some local variables used within the loop.
1355  GslVector b(m_env, m_map);
1356  GslVector x(m_env, m_map);
1357 
1358  for( unsigned int j = 0; j < B.numCols(); ++j )
1359  {
1360  b = B.getColumn( j );
1361 
1362  //invertMultiply will only do the LU once and store it. So we don't
1363  //need to worry about it doing LU multiple times.
1364  x = this->invertMultiply( b );
1365 
1366  X.setColumn( j, x );
1367  }
1368 
1369  return;
1370 }
1371 
1372 GslVector
1374  const GslVector& b) const
1375 {
1376  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1377 
1378  GslVector x(m_env,m_map);
1379  this->invertMultiplyForceLU(b,x);
1380 
1381  return x;
1382 }
1383 
1384 void
1386  const GslVector& b,
1387  GslVector& x) const
1388 {
1389  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1390 
1391  queso_require_equal_to_msg(x.sizeLocal(), b.sizeLocal(), "solution and rhs have incompatible sizes");
1392 
1393  int iRC;
1394 
1395  if ( m_LU == NULL ) {
1396  queso_require_msg(!(m_permutation), "m_permutation should be NULL");
1397  m_LU = gsl_matrix_calloc(this->numRowsLocal(),this->numCols());
1398  }
1399  queso_require_msg(m_LU, "gsl_matrix_calloc() failed");
1400 
1401  iRC = gsl_matrix_memcpy(m_LU, m_mat);
1402  queso_require_msg(!(iRC), "gsl_matrix_memcpy() failed");
1403 
1404  if( m_permutation == NULL ) m_permutation = gsl_permutation_calloc(numCols());
1405  queso_require_msg(m_permutation, "gsl_permutation_calloc() failed");
1406 
1407  iRC = gsl_linalg_LU_decomp(m_LU,m_permutation,&m_signum);
1408  queso_require_msg(!(iRC), "gsl_linalg_LU_decomp() failed");
1409 
1410  iRC = gsl_linalg_LU_solve(m_LU,m_permutation,b.data(),x.data());
1411  if (iRC != 0) {
1412  m_isSingular = true;
1413  }
1414  queso_require_msg(!(iRC), "gsl_linalg_LU_solve() failed");
1415 
1416  return;
1417 }
1418 
1419 void
1420 GslMatrix::eigen(GslVector& eigenValues, GslMatrix* eigenVectors) const
1421 {
1422  unsigned int n = eigenValues.sizeLocal();
1423 
1424  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1425 
1426  if (eigenVectors) {
1427  queso_require_equal_to_msg(eigenValues.sizeLocal(), eigenVectors->numRowsLocal(), "different input vector sizes");
1428  }
1429 
1430  if (eigenVectors == NULL) {
1431  gsl_eigen_symm_workspace* w = gsl_eigen_symm_alloc((size_t) n);
1432  gsl_eigen_symm(m_mat,eigenValues.data(),w);
1433  gsl_eigen_symm_free(w);
1434  }
1435  else {
1436  gsl_eigen_symmv_workspace* w = gsl_eigen_symmv_alloc((size_t) n);
1437  gsl_eigen_symmv(m_mat,eigenValues.data(),eigenVectors->m_mat,w);
1438  gsl_eigen_symmv_sort(eigenValues.data(),eigenVectors->m_mat,GSL_EIGEN_SORT_VAL_ASC);
1439  gsl_eigen_symmv_free(w);
1440  }
1441 
1442  return;
1443 }
1444 
1445 void
1446 GslMatrix::largestEigen(double& eigenValue, GslVector& eigenVector) const
1447 {
1448 
1449  // Sanity Checks
1450  unsigned int n = eigenVector.sizeLocal();
1451 
1452  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1453 
1454  /* The following notation is used:
1455  z = vector used in iteration that ends up being the eigenvector corresponding to the
1456  largest eigenvalue
1457  w = vector used in iteration that we extract the largest eigenvalue from. */
1458 
1459  // Some parameters associated with the algorithm
1460  // TODO: Do we want to add the ability to have these set by the user?
1461  const unsigned int max_num_iterations = 10000;
1462  const double tolerance = 1.0e-13;
1463 
1464  // Create temporary working vectors.
1465  // TODO: We shouldn't have to use these - we ought to be able to work directly
1466  // TODO: with eigenValue and eigenVector. Optimize this once we have regression
1467  // TODO: tests.
1468  GslVector z(m_env, m_map, 1.0 ); // Needs to be initialized to 1.0
1469  GslVector w(m_env, m_map);
1470 
1471  // Some variables we use inside the loop.
1472  int index;
1473  double residual;
1474  double lambda;
1475 
1476  for( unsigned int k = 0; k < max_num_iterations; ++k )
1477  {
1478  w = (*this) * z;
1479 
1480  // For this algorithm, it's crucial to get the maximum in
1481  // absolute value, but then to normalize by the actual value
1482  // and *not* the absolute value.
1483  index = (w.abs()).getMaxValueIndex();
1484 
1485  lambda = w[index];
1486 
1487  z = (1.0/lambda) * w;
1488 
1489  // Here we use the norm of the residual as our convergence check:
1490  // norm( A*x - \lambda*x )
1491  residual = ( (*this)*z - lambda*z ).norm2();
1492 
1493  if( residual < tolerance )
1494  {
1495  eigenValue = lambda;
1496 
1497  // TODO: Do we want to normalize this so eigenVector.norm2() = 1?
1498  eigenVector = z;
1499  return;
1500  }
1501 
1502  }
1503 
1504  // If we reach this point, then we didn't converge. Print error message
1505  // to this effect.
1506  // TODO: We know we failed at this point - need a way to not need a test
1507  // TODO: Just specify the error.
1508  queso_require_less_msg(residual, tolerance, "Maximum num iterations exceeded");
1509 
1510 
1511  return;
1512 }
1513 
1514 void
1515 GslMatrix::smallestEigen(double& eigenValue, GslVector& eigenVector) const
1516 {
1517  // Sanity Checks
1518  unsigned int n = eigenVector.sizeLocal();
1519 
1520  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1521 
1522  /* The following notation is used:
1523  z = vector used in iteration that ends up being the eigenvector corresponding to the
1524  largest eigenvalue
1525  w = vector used in iteration that we extract the largest eigenvalue from. */
1526 
1527  // Some parameters associated with the algorithm
1528  // TODO: Do we want to add the ability to have these set by the user?
1529  const unsigned int max_num_iterations = 1000;
1530  const double tolerance = 1.0e-13;
1531 
1532  // Create temporary working vectors.
1533  // TODO: We shouldn't have to use these - we ought to be able to work directly
1534  // TODO: with eigenValue and eigenVector. Optimize this once we have regression
1535  // TODO: tests.
1536  GslVector z(m_env, m_map, 1.0 ); // Needs to be initialized to 1.0
1537  GslVector w(m_env, m_map);
1538 
1539  // Some variables we use inside the loop.
1540  int index;
1541  double residual;
1542  double one_over_lambda;
1543  double lambda;
1544 
1545  for( unsigned int k = 0; k < max_num_iterations; ++k )
1546  {
1547  w = (*this).invertMultiplyForceLU( z );
1548 
1549  // For this algorithm, it's crucial to get the maximum in
1550  // absolute value, but then to normalize by the actual value
1551  // and *not* the absolute value.
1552  index = (w.abs()).getMaxValueIndex();
1553 
1554  // Remember: Inverse power method solves for max 1/lambda ==> lambda smallest
1555  one_over_lambda = w[index];
1556 
1557  lambda = 1.0/one_over_lambda;
1558 
1559  z = lambda * w;
1560 
1561  // Here we use the norm of the residual as our convergence check:
1562  // norm( A*x - \lambda*x )
1563  residual = ( (*this)*z - lambda*z ).norm2();
1564 
1565  if( residual < tolerance )
1566  {
1567  eigenValue = lambda;
1568 
1569  // TODO: Do we want to normalize this so eigenVector.norm2() = 1?
1570  eigenVector = z;
1571  return;
1572  }
1573 
1574  }
1575 
1576  // If we reach this point, then we didn't converge. Print error message
1577  // to this effect.
1578  // TODO: We know we failed at this point - need a way to not need a test
1579  // TODO: Just specify the error.
1580  queso_require_less_msg(residual, tolerance, "Maximum num iterations exceeded");
1581 
1582  return;
1583 }
1584 
1585 void
1586 GslMatrix::getColumn(unsigned int column_num, GslVector& column) const
1587 {
1588  // Sanity checks
1589  queso_require_less_msg(column_num, this->numCols(), "Specified row number not within range");
1590 
1591  queso_require_equal_to_msg(column.sizeLocal(), this->numRowsLocal(), "column vector not same size as this matrix");
1592 
1593  // Temporary working vector
1594  gsl_vector* gsl_column = gsl_vector_alloc( column.sizeLocal() );
1595 
1596  int error_code = gsl_matrix_get_col( gsl_column, m_mat, column_num );
1597  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_get_col failed");
1598 
1599  // Copy column from gsl matrix into our GslVector object
1600  for( unsigned int i = 0; i < column.sizeLocal(); ++i )
1601  {
1602  column[i] = gsl_vector_get( gsl_column, i );
1603  }
1604 
1605  // Clean up gsl temporaries
1606  gsl_vector_free( gsl_column );
1607 
1608  return;
1609 }
1610 
1611 void
1612 GslMatrix::getRow(unsigned int row_num, GslVector& row) const
1613 {
1614  // Sanity checks
1615  queso_require_less_msg(row_num, this->numRowsLocal(), "Specified row number not within range");
1616 
1617  queso_require_equal_to_msg(row.sizeLocal(), this->numCols(), "row vector not same size as this matrix");
1618 
1619  // Temporary working vector
1620  gsl_vector* gsl_row = gsl_vector_alloc( row.sizeLocal() );
1621 
1622  int error_code = gsl_matrix_get_row( gsl_row, m_mat, row_num );
1623  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_get_row failed");
1624 
1625  // Copy row from gsl matrix into our GslVector object
1626  for( unsigned int i = 0; i < row.sizeLocal(); ++i )
1627  {
1628  row[i] = gsl_vector_get( gsl_row, i );
1629  }
1630 
1631  // Clean up gsl temporaries
1632  gsl_vector_free( gsl_row );
1633 
1634  return;
1635 }
1636 
1637 GslVector
1638 GslMatrix::getRow(unsigned int row_num ) const
1639 {
1640  // We rely on the void getRow's to do sanity checks
1641  // So we don't do them here.
1642 
1643  GslVector row(m_env, m_map);
1644 
1645  this->getRow( row_num, row );
1646 
1647  return row;
1648 }
1649 
1650 GslVector
1651 GslMatrix::getColumn(unsigned int column_num ) const
1652 {
1653  // We rely on the void getRow's to do sanity checks
1654  // So we don't do them here.
1655 
1656  GslVector column(m_env, m_map);
1657 
1658  this->getColumn( column_num, column );
1659 
1660  return column;
1661 }
1662 
1663 void
1664 GslMatrix::setRow(unsigned int row_num, const GslVector& row)
1665 {
1666  this->resetLU();
1667  // Sanity checks
1668  queso_require_less_msg(row_num, this->numRowsLocal(), "Specified row number not within range");
1669 
1670  queso_require_equal_to_msg(row.sizeLocal(), this->numCols(), "row vector not same size as this matrix");
1671 
1672  gsl_vector* gsl_row = row.data();
1673 
1674  int error_code = gsl_matrix_set_row( m_mat, row_num, gsl_row );
1675  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_set_row failed");
1676 
1677  return;
1678 }
1679 
1680 void
1681 GslMatrix::setColumn(unsigned int column_num, const GslVector& column)
1682 {
1683  this->resetLU();
1684  // Sanity checks
1685  queso_require_less_msg(column_num, this->numCols(), "Specified column number not within range");
1686 
1687  queso_require_equal_to_msg(column.sizeLocal(), this->numRowsLocal(), "column vector not same size as this matrix");
1688 
1689  gsl_vector* gsl_column = column.data();
1690 
1691  int error_code = gsl_matrix_set_col( m_mat, column_num, gsl_column );
1692  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_set_col failed");
1693 
1694  return;
1695 }
1696 
1697 void
1698 GslMatrix::mpiSum( const MpiComm& comm, GslMatrix& M_global ) const
1699 {
1700  // Sanity Checks
1701  UQ_FATAL_RC_MACRO(((this->numRowsLocal() != M_global.numRowsLocal()) ||
1702  (this->numCols() != M_global.numCols() )),
1703  env().fullRank(),
1704  "GslMatrix::mpiSum()",
1705  "local and global matrices incompatible");
1706 
1707  /* TODO: Probably a better way to handle this unpacking/packing of data */
1708  int size = M_global.numRowsLocal()*M_global.numCols();
1709  std::vector<double> local( size, 0.0 );
1710  std::vector<double> global( size, 0.0 );
1711 
1712  int k;
1713  for( unsigned int i = 0; i < this->numRowsLocal(); i++ )
1714  {
1715  for( unsigned int j = 0; j < this->numCols(); j++ )
1716  {
1717  k = i + j*M_global.numCols();
1718 
1719  local[k] = (*this)(i,j);
1720  }
1721  }
1722 
1723  comm.Allreduce<double>(&local[0], &global[0], size, RawValue_MPI_SUM,
1724  "GslMatrix::mpiSum()",
1725  "failed MPI.Allreduce()");
1726 
1727  for( unsigned int i = 0; i < this->numRowsLocal(); i++ )
1728  {
1729  for( unsigned int j = 0; j < this->numCols(); j++ )
1730  {
1731  k = i + j*M_global.numCols();
1732 
1733  M_global(i,j) = global[k];
1734  }
1735  }
1736 
1737  return;
1738 }
1739 
1740 void
1742  const GslVector& x1Vec,
1743  const GslMatrix& y1Mat,
1744  const GslVector& x2Vec)
1745 {
1746  queso_require_greater_msg(x1Vec.sizeLocal(), 1, "invalid 'x1' size");
1747 
1748  queso_require_equal_to_msg(x1Vec.sizeLocal(), y1Mat.numRowsLocal(), "invalid 'x1' and 'y1' sizes");
1749 
1750  queso_require_equal_to_msg(x2Vec.sizeLocal(), this->numRowsLocal(), "invalid 'x2' and 'this' sizes");
1751 
1752  queso_require_equal_to_msg(y1Mat.numCols(), this->numCols(), "invalid 'y1' and 'this' sizes");
1753 
1754  GslVector y1Vec(x1Vec);
1755  GslVector y2Vec(x2Vec);
1756  for (unsigned int colId = 0; colId < y1Mat.numCols(); ++colId) {
1757  y1Mat.getColumn(colId,y1Vec);
1758  y2Vec.matlabLinearInterpExtrap(x1Vec,y1Vec,x2Vec);
1759  this->setColumn(colId,y2Vec);
1760  }
1761 
1762  return;
1763 }
1764 
1765 gsl_matrix*
1767 {
1768  return m_mat;
1769 }
1770 
1771 void
1772 GslMatrix::print(std::ostream& os) const
1773 {
1774  unsigned int nRows = this->numRowsLocal();
1775  unsigned int nCols = this->numCols();
1776 
1777  if (m_printHorizontally) {
1778  for (unsigned int i = 0; i < nRows; ++i) {
1779  for (unsigned int j = 0; j < nCols; ++j) {
1780  os << (*this)(i,j)
1781  << " ";
1782  }
1783  if (i != (nRows-1)) os << "; ";
1784  }
1785  //os << std::endl;
1786  }
1787  else {
1788  for (unsigned int i = 0; i < nRows; ++i) {
1789  for (unsigned int j = 0; j < nCols; ++j) {
1790  os << (*this)(i,j)
1791  << " ";
1792  }
1793  os << std::endl;
1794  }
1795  }
1796 
1797  return;
1798 }
1799 
1800 void
1802  const std::string& varNamePrefix,
1803  const std::string& fileName,
1804  const std::string& fileType,
1805  const std::set<unsigned int>& allowedSubEnvIds) const
1806 {
1807  queso_require_greater_equal_msg(m_env.subRank(), 0, "unexpected subRank");
1808 
1809  queso_require_less_equal_msg(this->numOfProcsForStorage(), 1, "implemented just for sequential vectors for now");
1810 
1811  FilePtrSetStruct filePtrSet;
1812  if (m_env.openOutputFile(fileName,
1813  fileType, // "m or hdf"
1814  allowedSubEnvIds,
1815  false,
1816  filePtrSet)) {
1817  unsigned int nRows = this->numRowsLocal();
1818  unsigned int nCols = this->numCols();
1819  *filePtrSet.ofsVar << varNamePrefix << "_sub" << m_env.subIdString() << " = zeros(" << nRows
1820  << "," << nCols
1821  << ");"
1822  << std::endl;
1823  *filePtrSet.ofsVar << varNamePrefix << "_sub" << m_env.subIdString() << " = [";
1824 
1825  for (unsigned int i = 0; i < nRows; ++i) {
1826  for (unsigned int j = 0; j < nCols; ++j) {
1827  *filePtrSet.ofsVar << (*this)(i,j)
1828  << " ";
1829  }
1830  *filePtrSet.ofsVar << "\n";
1831  }
1832  *filePtrSet.ofsVar << "];\n";
1833 
1834  m_env.closeFile(filePtrSet,fileType);
1835  }
1836 
1837  return;
1838 }
1839 
1840 void
1842  const std::string& fileName,
1843  const std::string& fileType,
1844  const std::set<unsigned int>& allowedSubEnvIds)
1845 {
1846  queso_require_greater_equal_msg(m_env.subRank(), 0, "unexpected subRank");
1847 
1848  queso_require_less_equal_msg(this->numOfProcsForStorage(), 1, "implemented just for sequential vectors for now");
1849 
1850  FilePtrSetStruct filePtrSet;
1851  if (m_env.openInputFile(fileName,
1852  fileType, // "m or hdf"
1853  allowedSubEnvIds,
1854  filePtrSet)) {
1855 
1856  // palms
1857  unsigned int nRowsLocal = this->numRowsLocal();
1858 
1859  // In the logic below, the id of a line' begins with value 0 (zero)
1860  unsigned int idOfMyFirstLine = 1;
1861  unsigned int idOfMyLastLine = nRowsLocal;
1862  unsigned int nCols = this->numCols();
1863 
1864  // Read number of matrix rows in the file by taking care of the first line,
1865  // which resembles something like 'variable_name = zeros(n_rows,n_cols);'
1866  std::string tmpString;
1867 
1868  // Read 'variable name' string
1869  *filePtrSet.ifsVar >> tmpString;
1870  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1871 
1872  // Read '=' sign
1873  *filePtrSet.ifsVar >> tmpString;
1874  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1875  queso_require_equal_to_msg(tmpString, std::string("="), std::string("string should be the '=' sign"));
1876 
1877  // Read 'zeros(n_rows,n_cols)' string
1878  *filePtrSet.ifsVar >> tmpString;
1879  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1880  unsigned int posInTmpString = 6;
1881 
1882  // Isolate 'n_rows' in a string
1883  char nRowsString[tmpString.size()-posInTmpString+1];
1884  unsigned int posInRowsString = 0;
1885  do {
1886  queso_require_less_msg(posInTmpString, tmpString.size(), "symbol ',' not found in first line of file");
1887  nRowsString[posInRowsString++] = tmpString[posInTmpString++];
1888  } while (tmpString[posInTmpString] != ',');
1889  nRowsString[posInRowsString] = '\0';
1890 
1891  // Isolate 'n_cols' in a string
1892  posInTmpString++; // Avoid reading ',' char
1893  char nColsString[tmpString.size()-posInTmpString+1];
1894  unsigned int posInColsString = 0;
1895  do {
1896  queso_require_less_msg(posInTmpString, tmpString.size(), "symbol ')' not found in first line of file");
1897  nColsString[posInColsString++] = tmpString[posInTmpString++];
1898  } while (tmpString[posInTmpString] != ')');
1899  nColsString[posInColsString] = '\0';
1900 
1901  // Convert 'n_rows' and 'n_cols' strings to numbers
1902  unsigned int numRowsInFile = (unsigned int) strtod(nRowsString,NULL);
1903  unsigned int numColsInFile = (unsigned int) strtod(nColsString,NULL);
1904  if (m_env.subDisplayFile()) {
1905  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1906  << ": fullRank " << m_env.fullRank()
1907  << ", numRowsInFile = " << numRowsInFile
1908  << ", numColsInFile = " << numColsInFile
1909  << ", nRowsLocal = " << nRowsLocal
1910  << ", nCols = " << nCols
1911  << std::endl;
1912  }
1913 
1914  // Check if [num of rows in file] == [requested matrix row size]
1915  queso_require_equal_to_msg(numRowsInFile, nRowsLocal, "size of vec in file is not big enough");
1916 
1917  // Check if [num of cols in file] == [num cols in current matrix]
1918  queso_require_equal_to_msg(numColsInFile, nCols, "number of parameters of vec in file is different than number of parameters in this vec object");
1919 
1920  // Code common to any core in a communicator
1921  unsigned int maxCharsPerLine = 64*nCols; // Up to about 60 characters to represent each parameter value
1922 
1923  unsigned int lineId = 0;
1924  while (lineId < idOfMyFirstLine) {
1925  filePtrSet.ifsVar->ignore(maxCharsPerLine,'\n');
1926  lineId++;
1927  };
1928 
1929  if (m_env.subDisplayFile()) {
1930  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1931  << ": beginning to read input actual data"
1932  << std::endl;
1933  }
1934 
1935  // Take care of initial part of the first data line,
1936  // which resembles something like 'variable_name = [value1 value2 ...'
1937  // Read 'variable name' string
1938  *filePtrSet.ifsVar >> tmpString;
1939  //std::cout << "Core 0 just read '" << tmpString << "'" << std::endl;
1940 
1941  // Read '=' sign
1942  *filePtrSet.ifsVar >> tmpString;
1943  //std::cout << "Core 0 just read '" << tmpString << "'" << std::endl;
1944  queso_require_equal_to_msg(tmpString, std::string("="), std::string("in core 0, string should be the '=' sign"));
1945 
1946  // Take into account the ' [' portion
1947  std::streampos tmpPos = filePtrSet.ifsVar->tellg();
1948  filePtrSet.ifsVar->seekg(tmpPos+(std::streampos)2);
1949 
1950  if (m_env.subDisplayFile()) {
1951  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1952  << ": beginning to read lines with numbers only"
1953  << ", lineId = " << lineId
1954  << ", idOfMyFirstLine = " << idOfMyFirstLine
1955  << ", idOfMyLastLine = " << idOfMyLastLine
1956  << std::endl;
1957  }
1958 
1959  double tmpRead;
1960  while (lineId <= idOfMyLastLine) {
1961  for (unsigned int j = 0; j < nCols; ++j) {
1962  *filePtrSet.ifsVar >> tmpRead;
1963  (*this)(lineId-idOfMyFirstLine,j) = tmpRead;
1964  }
1965  lineId++;
1966  };
1967 
1968  m_env.closeFile(filePtrSet,fileType);
1969  }
1970 
1971  return;
1972 }
1973 
1974 std::ostream&
1975 operator<<(std::ostream& os, const GslMatrix& obj)
1976 {
1977  obj.print(os);
1978 
1979  return os;
1980 }
1981 
1982 GslMatrix operator*(double a, const GslMatrix& mat)
1983 {
1984  GslMatrix answer(mat);
1985  answer *= a;
1986  return answer;
1987 }
1988 
1989 GslVector operator*(const GslMatrix& mat, const GslVector& vec)
1990 {
1991  return mat.multiply(vec);
1992 }
1993 
1995 {
1996  unsigned int m1Rows = m1.numRowsLocal();
1997  unsigned int m1Cols = m1.numCols();
1998  unsigned int m2Rows = m2.numRowsLocal();
1999  unsigned int m2Cols = m2.numCols();
2000 
2001  queso_require_equal_to_msg(m1Cols, m2Rows, "different sizes m1Cols and m2Rows");
2002 
2003  GslMatrix mat(m1.env(),m1.map(),m2Cols);
2004 
2005  //std::cout << "In GslMatrix(mat * mat): m1Cols = " << m1Cols << std::endl;
2006 
2007  unsigned int commonSize = m1Cols;
2008  for (unsigned int row1 = 0; row1 < m1Rows; ++row1) {
2009  for (unsigned int col2 = 0; col2 < m2Cols; ++col2) {
2010  double result = 0.;
2011  for (unsigned int k = 0; k < commonSize; ++k) {
2012  result += m1(row1,k)*m2(k,col2);
2013  }
2014  mat(row1,col2) = result;
2015  }
2016  //std::cout << "In GslMatrix(mat * mat): ended row " << row1 << std::endl;
2017  }
2018 
2019  return mat;
2020 }
2021 
2023 {
2024  GslMatrix answer(m1);
2025  answer += m2;
2026  return answer;
2027 }
2028 
2030 {
2031  GslMatrix answer(m1);
2032  answer -= m2;
2033  return answer;
2034 }
2035 
2037 {
2038  unsigned int nRows = v1.sizeLocal();
2039  unsigned int nCols = v2.sizeLocal();
2040  GslMatrix answer(v1.env(),v1.map(),nCols);
2041 
2042  for (unsigned int i = 0; i < nRows; ++i) {
2043  double value1 = v1[i];
2044  for (unsigned int j = 0; j < nCols; ++j) {
2045  answer(i,j) = value1*v2[j];
2046  }
2047  }
2048 
2049  return answer;
2050 }
2051 
2053 {
2054  unsigned int vSize = vec.sizeLocal();
2055  unsigned int mRows = mat.numRowsLocal();
2056  unsigned int mCols = mat.numCols();
2057 
2058  queso_require_equal_to_msg(vSize, mRows, "size of vector is different from the number of rows in matrix");
2059 
2060  queso_require_equal_to_msg(mCols, mRows, "routine currently works for square matrices only");
2061 
2062  GslMatrix answer(mat);
2063  for (unsigned int i = 0; i < mRows; ++i) {
2064  double vecValue = vec[i];
2065  for (unsigned int j = 0; j < mCols; ++j) {
2066  answer(i,j) *= vecValue;
2067  }
2068  }
2069 
2070  return answer;
2071 }
2072 
2074 {
2075  unsigned int vSize = vec.sizeLocal();
2076  unsigned int mRows = mat.numRowsLocal();
2077  unsigned int mCols = mat.numCols();
2078 
2079  queso_require_equal_to_msg(vSize, mCols, "size of vector is different from the number of cols in matrix");
2080 
2081  queso_require_equal_to_msg(mCols, mRows, "routine currently works for square matrices only");
2082 
2083  GslMatrix answer(mat);
2084  for (unsigned int j = 0; j < mCols; ++j) {
2085  double vecValue = vec[j];
2086  for (unsigned int i = 0; i < mRows; ++i) {
2087  answer(i,j) *= vecValue;
2088  }
2089  }
2090 
2091  return answer;
2092 }
2093 
2094 } // End namespace QUESO
double norm2() const
Returns the 2-norm (Euclidean norm) of the vector.
Definition: GslVector.C:280
GslMatrix operator+(const GslMatrix &m1, const GslMatrix &m2)
Definition: GslMatrix.C:2022
void zeroUpper(bool includeDiagonal=false)
This function sets all the entries above the main diagonal of this matrix to zero.
Definition: GslMatrix.C:619
double normMax() const
Returns the Frobenius norm of this matrix.
Definition: GslMatrix.C:311
void zeroLower(bool includeDiagonal=false)
This function sets all the entries bellow the main diagonal of this matrix to zero.
Definition: GslMatrix.C:591
void eigen(GslVector &eigenValues, GslMatrix *eigenVectors) const
This function computes the eigenvalues of a real symmetric matrix.
Definition: GslMatrix.C:1420
GslMatrix operator-(const GslMatrix &m1, const GslMatrix &m2)
Definition: GslMatrix.C:2029
gsl_matrix * m_mat
GSL matrix, also referred to as this matrix.
Definition: GslMatrix.h:409
void fillWithBlocksVertically(unsigned int rowId, unsigned int colId, const std::vector< const GslMatrix * > &matrices, bool checkForExactNumRowsMatching, bool checkForExactNumColsMatching)
This function fills this matrix vertically with const block matrices.
Definition: GslMatrix.C:889
bool m_isSingular
Indicates whether or not this matrix is singular.
Definition: GslMatrix.h:464
int worldRank() const
Returns the process world rank.
Definition: Environment.C:262
const Map & map() const
Definition: Vector.C:61
const int UQ_MATRIX_IS_NOT_POS_DEFINITE_RC
Definition: Defines.h:97
std::ofstream * subDisplayFile() const
Access function for m_subDisplayFile (displays file on stream).
Definition: Environment.C:320
#define RawValue_MPI_SUM
Definition: MpiComm.h:71
#define queso_require_greater_equal_msg(expr1, expr2, msg)
Definition: asserts.h:78
const GslMatrix & svdMatV() const
This function calls private member GslMatrix::internalSvd() to set a N-by-N orthogonal square matrix ...
Definition: GslMatrix.C:522
void filterLargeValues(double thresholdValue)
This function sets to zero (filters) all entries of this matrix which are greater than thresholdValue...
Definition: GslMatrix.C:670
void fillWithTranspose(unsigned int rowId, unsigned int colId, const GslMatrix &mat, bool checkForExactNumRowsMatching, bool checkForExactNumColsMatching)
This function stores the transpose of this matrix into this matrix.
Definition: GslMatrix.C:1014
int subRank() const
Access function for sub-rank.
Definition: Environment.C:287
std::ifstream * ifsVar
Provides a stream interface to read data from files.
Definition: Environment.h:88
void largestEigen(double &eigenValue, GslVector &eigenVector) const
This function finds largest eigenvalue, namely eigenValue, of this matrix and its corresponding eigen...
Definition: GslMatrix.C:1446
int dim
Definition: ann2fig.cpp:81
int internalSvd() const
This function factorizes the M-by-N matrix A into the singular value decomposition A = U S V^T for M ...
Definition: GslMatrix.C:532
This (virtual) class sets up the environment underlying the use of the QUESO library by an executable...
Definition: Environment.h:197
void fillWithBlocksHorizontally(unsigned int rowId, unsigned int colId, const std::vector< const GslMatrix * > &matrices, bool checkForExactNumRowsMatching, bool checkForExactNumColsMatching)
This function fills this matrix horizontally with const block matrices.
Definition: GslMatrix.C:825
void fillWithTensorProduct(unsigned int rowId, unsigned int colId, const GslMatrix &mat1, const GslMatrix &mat2, bool checkForExactNumRowsMatching, bool checkForExactNumColsMatching)
This function calculates the tensor product of matrices mat1 and mat2 and stores it in this matrix...
Definition: GslMatrix.C:953
gsl_matrix * data()
Returns this matrix.
Definition: GslMatrix.C:1766
void subWriteContents(const std::string &varNamePrefix, const std::string &fileName, const std::string &fileType, const std::set< unsigned int > &allowedSubEnvIds) const
Write contents of subenvironment in file fileName.
Definition: GslMatrix.C:1801
bool m_printHorizontally
Flag for either or not print this matrix.
Definition: Matrix.h:131
GslMatrix & operator/=(double a)
Stores in this the coordinate-wise division of this by a.
Definition: GslMatrix.C:187
int svdSolve(const GslVector &rhsVec, GslVector &solVec) const
This function solves the system A x = b using the singular value decomposition (U, S, V) of A which must have been computed previously with GslMatrix::svd (x=solVec, b=rhsVec).
Definition: GslMatrix.C:456
#define UQ_RC_MACRO(macroIRc, givenRank, where, what, retValue)
Definition: Defines.h:137
double lnDeterminant() const
Calculates the ln(determinant) of this matrix.
Definition: GslMatrix.C:1079
GslVector * m_svdSvec
m_svdSvec stores the diagonal of the N-by-N diagonal matrix of singular values S after the singular v...
Definition: GslMatrix.h:431
double max() const
Returns the maximum element value of the matrix.
Definition: GslMatrix.C:329
GslVector multiply(const GslVector &x) const
This function multiplies this matrix by vector x and returns the resulting vector.
Definition: GslMatrix.C:1155
GslMatrix operator*(double a, const GslMatrix &mat)
Definition: GslMatrix.C:1982
#define queso_require_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:73
bool openInputFile(const std::string &fileName, const std::string &fileType, const std::set< unsigned int > &allowedSubEnvIds, FilePtrSetStruct &filePtrSet) const
Opens an input file.
Definition: Environment.C:895
#define queso_require_less_msg(expr1, expr2, msg)
Definition: asserts.h:75
void mpiSum(const MpiComm &comm, GslMatrix &M_global) const
Definition: GslMatrix.C:1698
const BaseEnvironment & env() const
Definition: Vector.C:54
bool m_inDebugMode
Flag for either or not QUESO is in debug mode.
Definition: Matrix.h:134
A class for partitioning vectors and matrices.
Definition: Map.h:49
void getRow(const unsigned int row_num, GslVector &row) const
This function gets the row_num-th column of this matrix and stores it into vector row...
Definition: GslMatrix.C:1612
const GslMatrix & svdMatU() const
This function calls private member GslMatrix::internalSvd() to set a M-by-N orthogonal matrix U of th...
Definition: GslMatrix.C:512
GslMatrix * m_svdUmat
m_svdUmat stores the M-by-N orthogonal matrix U after the singular value decomposition of a matrix...
Definition: GslMatrix.h:424
GslVector invertMultiplyForceLU(const GslVector &b) const
This function calculates the inverse of this matrix and multiplies it with vector b...
Definition: GslMatrix.C:1373
int k
Definition: ann_sample.cpp:53
Struct for handling data input and output from files.
Definition: Environment.h:76
void setColumn(const unsigned int column_num, const GslVector &column)
This function copies vector column into the column_num-th column of this matrix.
Definition: GslMatrix.C:1681
unsigned int numRowsGlobal() const
Returns the global row dimension of this matrix.
Definition: GslMatrix.C:281
const BaseEnvironment & env() const
Definition: Matrix.C:47
const Map & m_map
Mapping variable.
Definition: Matrix.h:126
Class for vector operations using GSL library.
Definition: GslVector.h:49
void resetLU()
In this function resets the LU decomposition of this matrix, as well as deletes the private member po...
Definition: GslMatrix.C:232
unsigned int numOfProcsForStorage() const
Definition: Matrix.C:62
#define UQ_FATAL_RC_MACRO(macroIRc, givenRank, where, what)
Definition: Defines.h:168
std::ostream & operator<<(std::ostream &os, const BaseEnvironment &obj)
const Map & map() const
Definition: Matrix.C:54
unsigned int numRowsLocal() const
Returns the local row dimension of this matrix.
Definition: GslMatrix.C:275
int m_signum
m_signum stores the sign of the permutation of the LU decomposition PA = LU.
Definition: GslMatrix.h:461
void cwSet(double value)
Component-wise sets all values to this with value.
Definition: GslVector.C:326
const BaseEnvironment & m_env
QUESO environment variable.
Definition: Matrix.h:116
GslVector invertMultiply(const GslVector &b) const
This function calculates the inverse of this matrix and multiplies it with vector b...
Definition: GslMatrix.C:1222
const std::string & subIdString() const
Access to the attribute m_subIdString; which stores the string for the sub-environment, and it will be used, for instance, to create the output files for each sub-environment.
Definition: Environment.C:347
GslMatrix * m_svdVmat
m_svdVmat stores the N-by-N orthogonal square matrix V after the singular value decomposition of a ma...
Definition: GslMatrix.h:437
GslMatrix transpose() const
This function calculated the transpose of this matrix (square).
Definition: GslMatrix.C:693
int chol()
Computes Cholesky factorization of a real symmetric positive definite matrix this.
Definition: GslMatrix.C:408
GslMatrix & operator*=(double a)
Stores in this the coordinate-wise multiplication of this and a.
Definition: GslMatrix.C:177
gsl_matrix * m_LU
GSL matrix for the LU decomposition of m_mat.
Definition: GslMatrix.h:412
#define queso_require_greater_msg(expr1, expr2, msg)
Definition: asserts.h:76
double m_lnDeterminant
The natural logarithm of the determinant of this matrix.
Definition: GslMatrix.h:449
void closeFile(FilePtrSetStruct &filePtrSet, const std::string &fileType) const
Closes the file.
Definition: Environment.C:1083
int fullRank() const
Returns the process full rank.
Definition: Environment.C:268
void matlabLinearInterpExtrap(const GslVector &x1Vec, const GslVector &y1Vec, const GslVector &x2Vec)
Definition: GslVector.C:556
GslMatrix & operator-=(const GslMatrix &rhs)
Stores in this the coordinate-wise subtraction of this by rhs.
Definition: GslMatrix.C:207
std::ofstream * ofsVar
Provides a stream interface to write data to files.
Definition: Environment.h:85
GslMatrix inverse() const
This function calculated the inverse of this matrix (square).
Definition: GslMatrix.C:713
void smallestEigen(double &eigenValue, GslVector &eigenVector) const
This function finds smallest eigenvalue, namely eigenValue, of this matrix and its corresponding eige...
Definition: GslMatrix.C:1515
bool openOutputFile(const std::string &fileName, const std::string &fileType, const std::set< unsigned int > &allowedSubEnvIds, bool writeOver, FilePtrSetStruct &filePtrSet) const
Opens an output file for each sub-environment that was chosen to send data to the file...
Definition: Environment.C:520
#define queso_require_not_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:74
void copy(const GslMatrix &src)
In this function this matrix receives a copy of matrix src.
Definition: GslMatrix.C:220
unsigned int checkingLevel() const
Access function to private attribute m_checkingLevel.
Definition: Environment.C:463
GslMatrix & operator+=(const GslMatrix &rhs)
Stores in this the coordinate-wise addition of this and rhs.
Definition: GslMatrix.C:196
#define queso_require_less_equal_msg(expr1, expr2, msg)
Definition: asserts.h:77
const int UQ_MATRIX_SVD_FAILED_RC
Definition: Defines.h:100
unsigned int displayVerbosity() const
Definition: Environment.C:449
GslMatrix leftDiagScaling(const GslVector &vec, const GslMatrix &mat)
Definition: GslMatrix.C:2052
unsigned int sizeLocal() const
Returns the length of this vector.
Definition: GslVector.C:240
void cwExtract(unsigned int rowId, unsigned int colId, GslMatrix &mat) const
Definition: GslMatrix.C:385
#define queso_require_msg(asserted, msg)
Definition: asserts.h:69
The QUESO MPI Communicator Class.
Definition: MpiComm.h:203
void cwSet(double value)
Component-wise set all values to this with value.
Definition: GslMatrix.C:347
GslMatrix * m_svdVTmat
m_svdVmatT stores the transpose of N-by-N orthogonal square matrix V, namely V^T, after the singular ...
Definition: GslMatrix.h:443
virtual void base_copy(const Matrix &src)
Copies base data from matrix src to this matrix.
Definition: Matrix.C:99
GslMatrix * m_inverse
Inverse matrix of this.
Definition: GslMatrix.h:415
Class for matrix operations (virtual).
Definition: Matrix.h:46
void setRow(const unsigned int row_num, const GslVector &row)
This function copies vector row into the row_num-th column of this matrix.
Definition: GslMatrix.C:1664
void matlabLinearInterpExtrap(const GslVector &x1Vec, const GslMatrix &y1Mat, const GslVector &x2Vec)
Definition: GslMatrix.C:1741
void getColumn(const unsigned int column_num, GslVector &column) const
This function gets the column_num-th column of this matrix and stores it into vector column...
Definition: GslMatrix.C:1586
~GslMatrix()
Destructor.
Definition: GslMatrix.C:161
double determinant() const
Calculates the determinant of this matrix.
Definition: GslMatrix.C:1038
const MpiComm & Comm() const
Access function for MpiComm communicator.
Definition: Map.C:131
void Allreduce(void *sendbuf, void *recvbuf, int count, RawType_MPI_Datatype datatype, RawType_MPI_Op op, const char *whereMsg, const char *whatMsg) const
Combines values from all processes and distributes the result back to all processes.
Definition: MpiComm.C:133
GslMatrix rightDiagScaling(const GslMatrix &mat, const GslVector &vec)
Definition: GslMatrix.C:2073
double normFrob() const
Returns the Frobenius norm of this matrix.
Definition: GslMatrix.C:293
void subReadContents(const std::string &fileName, const std::string &fileType, const std::set< unsigned int > &allowedSubEnvIds)
Read contents of subenvironment from file fileName.
Definition: GslMatrix.C:1841
double m_determinant
The determinant of this matrix.
Definition: GslMatrix.h:446
void filterSmallValues(double thresholdValue)
This function sets to zero (filters) all entries of this matrix which are smaller than thresholdValue...
Definition: GslMatrix.C:647
GslMatrix()
Default Constructor.
void print(std::ostream &os) const
Print method. Defines the behavior of the ostream &lt;&lt; operator inherited from the Object class...
Definition: GslMatrix.C:1772
gsl_permutation * m_permutation
The permutation matrix of a LU decomposition.
Definition: GslMatrix.h:455
void fillWithBlocksDiagonally(unsigned int rowId, unsigned int colId, const std::vector< const GslMatrix * > &matrices, bool checkForExactNumRowsMatching, bool checkForExactNumColsMatching)
This function fills this matrix diagonally with const block matrices.
Definition: GslMatrix.C:753
GslMatrix matrixProduct(const GslVector &v1, const GslVector &v2)
Definition: GslMatrix.C:2036
GslMatrix & operator=(const GslMatrix &rhs)
Copies values from matrix rhs to this.
Definition: GslMatrix.C:169
Map * m_svdColMap
Mapping for matrices involved in the singular value decomposition (svd) routine.
Definition: GslMatrix.h:418
gsl_vector * data() const
Definition: GslVector.C:969
unsigned int rank(double absoluteZeroThreshold, double relativeZeroThreshold) const
This function returns the number of singular values of this matrix (rank).
Definition: GslMatrix.C:1120
unsigned int numCols() const
Returns the column dimension of this matrix.
Definition: GslMatrix.C:287
int svd(GslMatrix &matU, GslVector &vecS, GslMatrix &matVt) const
Checks for the dimension of this matrix, matU, VecS and matVt, and calls the protected routine intern...
Definition: GslMatrix.C:435
GslVector abs() const
This function returns absolute value of elements in this.
Definition: GslVector.C:1081
Class for matrix operations using GSL library.
Definition: GslMatrix.h:49

Generated on Thu Dec 15 2016 13:23:10 for queso-0.56.1 by  doxygen 1.8.5