queso-0.55.0
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->numRowsLocal();
696  unsigned int nCols = this->numCols();
697 
698  queso_require_equal_to_msg(nRows, nCols, "routine works only for square matrices");
699 
700  GslMatrix mat(m_env,m_map,nCols);
701  for (unsigned int row = 0; row < nRows; ++row) {
702  for (unsigned int col = 0; col < nCols; ++col) {
703  mat(row,col) = (*this)(col,row);
704  }
705  }
706 
707  return mat;
708 }
709 
710 GslMatrix
712 {
713  unsigned int nRows = this->numRowsLocal();
714  unsigned int nCols = this->numCols();
715 
716  queso_require_equal_to_msg(nRows, nCols, "matrix is not square");
717 
718  if (m_inverse == NULL) {
719  m_inverse = new GslMatrix(m_env,m_map,nCols);
720  GslVector unitVector(m_env,m_map);
721  unitVector.cwSet(0.);
722  GslVector multVector(m_env,m_map);
723  for (unsigned int j = 0; j < nCols; ++j) {
724  if (j > 0) unitVector[j-1] = 0.;
725  unitVector[j] = 1.;
726  this->invertMultiply(unitVector, multVector);
727  for (unsigned int i = 0; i < nRows; ++i) {
728  (*m_inverse)(i,j) = multVector[i];
729  }
730  }
731  }
732  if (m_env.checkingLevel() >= 1) {
733  *m_env.subDisplayFile() << "CHECKING In GslMatrix::inverse()"
734  << ": M.lnDet = " << this->lnDeterminant()
735  << ", M^{-1}.lnDet = " << m_inverse->lnDeterminant()
736  << std::endl;
737  }
738  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
739  *m_env.subDisplayFile() << "In GslMatrix::inverse():"
740  << "\n M = " << *this
741  << "\n M^{-1} = " << *m_inverse
742  << "\n M*M^{-1} = " << (*this)*(*m_inverse)
743  << "\n M^{-1}*M = " << (*m_inverse)*(*this)
744  << std::endl;
745  }
746 
747  return *m_inverse;
748 }
749 
750 void
752  unsigned int initialTargetRowId,
753  unsigned int initialTargetColId,
754  const std::vector<const GslMatrix* >& matrices,
755  bool checkForExactNumRowsMatching,
756  bool checkForExactNumColsMatching)
757 {
758  unsigned int sumNumRowsLocals = 0;
759  unsigned int sumNumCols = 0;
760  for (unsigned int i = 0; i < matrices.size(); ++i) {
761  sumNumRowsLocals += matrices[i]->numRowsLocal();
762  sumNumCols += matrices[i]->numCols();
763  }
764  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "too big number of rows");
765  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "inconsistent number of rows");
766  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
767  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
768 
769  unsigned int cumulativeRowId = 0;
770  unsigned int cumulativeColId = 0;
771  for (unsigned int i = 0; i < matrices.size(); ++i) {
772  unsigned int nRows = matrices[i]->numRowsLocal();
773  unsigned int nCols = matrices[i]->numCols();
774  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
775  for (unsigned int colId = 0; colId < nCols; ++colId) {
776  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
777  }
778  }
779  cumulativeRowId += nRows;
780  cumulativeColId += nCols;
781  }
782 
783  return;
784 }
785 
786 void
788  unsigned int initialTargetRowId,
789  unsigned int initialTargetColId,
790  const std::vector<GslMatrix* >& matrices,
791  bool checkForExactNumRowsMatching,
792  bool checkForExactNumColsMatching)
793 {
794  unsigned int sumNumRowsLocals = 0;
795  unsigned int sumNumCols = 0;
796  for (unsigned int i = 0; i < matrices.size(); ++i) {
797  sumNumRowsLocals += matrices[i]->numRowsLocal();
798  sumNumCols += matrices[i]->numCols();
799  }
800  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "too big number of rows");
801  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRowsLocals), "inconsistent number of rows");
802  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
803  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
804 
805  unsigned int cumulativeRowId = 0;
806  unsigned int cumulativeColId = 0;
807  for (unsigned int i = 0; i < matrices.size(); ++i) {
808  unsigned int nRows = matrices[i]->numRowsLocal();
809  unsigned int nCols = matrices[i]->numCols();
810  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
811  for (unsigned int colId = 0; colId < nCols; ++colId) {
812  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
813  }
814  }
815  cumulativeRowId += nRows;
816  cumulativeColId += nCols;
817  }
818 
819  return;
820 }
821 
822 void
824  unsigned int initialTargetRowId,
825  unsigned int initialTargetColId,
826  const std::vector<const GslMatrix* >& matrices,
827  bool checkForExactNumRowsMatching,
828  bool checkForExactNumColsMatching)
829 {
830  unsigned int sumNumCols = 0;
831  for (unsigned int i = 0; i < matrices.size(); ++i) {
832  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "too big number of rows");
833  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "inconsistent number of rows");
834  sumNumCols += matrices[i]->numCols();
835  }
836  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
837  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
838 
839  unsigned int cumulativeColId = 0;
840  for (unsigned int i = 0; i < matrices.size(); ++i) {
841  unsigned int nRows = matrices[i]->numRowsLocal();
842  unsigned int nCols = matrices[i]->numCols();
843  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
844  for (unsigned int colId = 0; colId < nCols; ++colId) {
845  (*this)(initialTargetRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
846  }
847  }
848  cumulativeColId += nCols;
849  }
850 
851  return;
852 }
853 
854 void
856  unsigned int initialTargetRowId,
857  unsigned int initialTargetColId,
858  const std::vector<GslMatrix* >& matrices,
859  bool checkForExactNumRowsMatching,
860  bool checkForExactNumColsMatching)
861 {
862  unsigned int sumNumCols = 0;
863  for (unsigned int i = 0; i < matrices.size(); ++i) {
864  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "too big number of rows");
865  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + matrices[i]->numRowsLocal()), "inconsistent number of rows");
866  sumNumCols += matrices[i]->numCols();
867  }
868  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + sumNumCols), "too big number of cols");
869  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + sumNumCols), "inconsistent number of cols");
870 
871  unsigned int cumulativeColId = 0;
872  for (unsigned int i = 0; i < matrices.size(); ++i) {
873  unsigned int nRows = matrices[i]->numRowsLocal();
874  unsigned int nCols = matrices[i]->numCols();
875  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
876  for (unsigned int colId = 0; colId < nCols; ++colId) {
877  (*this)(initialTargetRowId + rowId, initialTargetColId + cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
878  }
879  }
880  cumulativeColId += nCols;
881  }
882 
883  return;
884 }
885 
886 void
888  unsigned int initialTargetRowId,
889  unsigned int initialTargetColId,
890  const std::vector<const GslMatrix* >& matrices,
891  bool checkForExactNumRowsMatching,
892  bool checkForExactNumColsMatching)
893 {
894  unsigned int sumNumRows = 0;
895  for (unsigned int i = 0; i < matrices.size(); ++i) {
896  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "too big number of cols");
897  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "inconsistent number of cols");
898  sumNumRows += matrices[i]->numRowsLocal();
899  }
900  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "too big number of rows");
901  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "inconsistent number of rows");
902 
903  unsigned int cumulativeRowId = 0;
904  for (unsigned int i = 0; i < matrices.size(); ++i) {
905  unsigned int nRows = matrices[i]->numRowsLocal();
906  unsigned int nCols = matrices[i]->numCols();
907  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
908  for (unsigned int colId = 0; colId < nCols; ++colId) {
909  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + colId) = (*(matrices[i]))(rowId,colId);
910  }
911  }
912  cumulativeRowId += nRows;
913  }
914 
915  return;
916 }
917 
918 void
920  unsigned int initialTargetRowId,
921  unsigned int initialTargetColId,
922  const std::vector<GslMatrix* >& matrices,
923  bool checkForExactNumRowsMatching,
924  bool checkForExactNumColsMatching)
925 {
926  unsigned int sumNumRows = 0;
927  for (unsigned int i = 0; i < matrices.size(); ++i) {
928  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "too big number of cols");
929  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + matrices[i]->numCols()), "inconsistent number of cols");
930  sumNumRows += matrices[i]->numRowsLocal();
931  }
932  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "too big number of rows");
933  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + sumNumRows), "inconsistent number of rows");
934 
935  unsigned int cumulativeRowId = 0;
936  for (unsigned int i = 0; i < matrices.size(); ++i) {
937  unsigned int nRows = matrices[i]->numRowsLocal();
938  unsigned int nCols = matrices[i]->numCols();
939  for (unsigned int rowId = 0; rowId < nRows; ++rowId) {
940  for (unsigned int colId = 0; colId < nCols; ++colId) {
941  (*this)(initialTargetRowId + cumulativeRowId + rowId, initialTargetColId + colId) = (*(matrices[i]))(rowId,colId);
942  }
943  }
944  cumulativeRowId += nRows;
945  }
946 
947  return;
948 }
949 
950 void
952  unsigned int initialTargetRowId,
953  unsigned int initialTargetColId,
954  const GslMatrix& mat1,
955  const GslMatrix& mat2,
956  bool checkForExactNumRowsMatching,
957  bool checkForExactNumColsMatching)
958 {
959  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * mat2.numRowsLocal())), "too big number of rows");
960  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * mat2.numRowsLocal())), "inconsistent number of rows");
961  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * mat2.numCols())), "too big number of columns");
962  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * mat2.numCols())), "inconsistent number of columns");
963 
964  for (unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
965  for (unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
966  double multiplicativeFactor = mat1(rowId1,colId1);
967  unsigned int targetRowId = rowId1 * mat2.numRowsLocal();
968  unsigned int targetColId = colId1 * mat2.numCols();
969  for (unsigned int rowId2 = 0; rowId2 < mat2.numRowsLocal(); ++rowId2) {
970  for (unsigned int colId2 = 0; colId2 < mat2.numCols(); ++colId2) {
971  (*this)(initialTargetRowId + targetRowId + rowId2, initialTargetColId + targetColId + colId2) = multiplicativeFactor * mat2(rowId2,colId2);
972  }
973  }
974  }
975  }
976 
977  return;
978 }
979 
980 void
982  unsigned int initialTargetRowId,
983  unsigned int initialTargetColId,
984  const GslMatrix& mat1,
985  const GslVector& vec2,
986  bool checkForExactNumRowsMatching,
987  bool checkForExactNumColsMatching)
988 {
989  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * vec2.sizeLocal())), "too big number of rows");
990  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + (mat1.numRowsLocal() * vec2.sizeLocal())), "inconsistent number of rows");
991  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * 1)), "too big number of columns");
992  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + (mat1.numCols() * 1)), "inconsistent number of columns");
993 
994  for (unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
995  for (unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
996  double multiplicativeFactor = mat1(rowId1,colId1);
997  unsigned int targetRowId = rowId1 * vec2.sizeLocal();
998  unsigned int targetColId = colId1 * 1;
999  for (unsigned int rowId2 = 0; rowId2 < vec2.sizeLocal(); ++rowId2) {
1000  for (unsigned int colId2 = 0; colId2 < 1; ++colId2) {
1001  (*this)(initialTargetRowId + targetRowId + rowId2, initialTargetColId + targetColId + colId2) = multiplicativeFactor * vec2[rowId2];
1002  }
1003  }
1004  }
1005  }
1006 
1007 
1008  return;
1009 }
1010 
1011 void
1013  unsigned int initialTargetRowId,
1014  unsigned int initialTargetColId,
1015  const GslMatrix& mat,
1016  bool checkForExactNumRowsMatching,
1017  bool checkForExactNumColsMatching)
1018 {
1019  unsigned int nRows = mat.numRowsLocal();
1020  unsigned int nCols = mat.numCols();
1021  queso_require_greater_equal_msg(this->numRowsLocal(), (initialTargetRowId + nCols), "too big number of rows");
1022  if (checkForExactNumRowsMatching) queso_require_equal_to_msg(this->numRowsLocal(), (initialTargetRowId + nCols), "inconsistent number of rows");
1023  queso_require_greater_equal_msg(this->numCols(), (initialTargetColId + nRows), "too big number of cols");
1024  if (checkForExactNumColsMatching) queso_require_equal_to_msg(this->numCols(), (initialTargetColId + nRows), "inconsistent number of cols");
1025 
1026  for (unsigned int row = 0; row < nRows; ++row) {
1027  for (unsigned int col = 0; col < nCols; ++col) {
1028  (*this)(initialTargetRowId + col, initialTargetColId + row) = mat(row,col);
1029  }
1030  }
1031 
1032  return;
1033 }
1034 
1035 double
1037 {
1038  if (m_determinant == -INFINITY) {
1039  if (m_LU == NULL) {
1040  GslVector tmpB(m_env,m_map);
1041  GslVector tmpX(m_env,m_map);
1042  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1043  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1044  << ": before 'this->invertMultiply()'"
1045  << std::endl;
1046  }
1047  this->invertMultiply(tmpB,tmpX);
1048  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1049  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1050  << ": after 'this->invertMultiply()'"
1051  << std::endl;
1052  }
1053  }
1054  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1055  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1056  << ": before 'gsl_linalg_LU_det()'"
1057  << std::endl;
1058  }
1059  m_determinant = gsl_linalg_LU_det(m_LU,m_signum);
1060  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1061  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1062  << ": after 'gsl_linalg_LU_det()'"
1063  << std::endl;
1064  }
1065  m_lnDeterminant = gsl_linalg_LU_lndet(m_LU);
1066  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1067  *m_env.subDisplayFile() << "In GslMatrix::determinant()"
1068  << ": after 'gsl_linalg_LU_lndet()'"
1069  << std::endl;
1070  }
1071  }
1072 
1073  return m_determinant;
1074 }
1075 
1076 double
1078 {
1079  if (m_lnDeterminant == -INFINITY) {
1080  if (m_LU == NULL) {
1081  GslVector tmpB(m_env,m_map);
1082  GslVector tmpX(m_env,m_map);
1083  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1084  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1085  << ": before 'this->invertMultiply()'"
1086  << std::endl;
1087  }
1088  this->invertMultiply(tmpB,tmpX);
1089  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1090  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1091  << ": after 'this->invertMultiply()'"
1092  << std::endl;
1093  }
1094  }
1095  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1096  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1097  << ": before 'gsl_linalg_LU_det()'"
1098  << std::endl;
1099  }
1100  m_determinant = gsl_linalg_LU_det(m_LU,m_signum);
1101  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1102  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1103  << ": after 'gsl_linalg_LU_det()'"
1104  << std::endl;
1105  }
1106  m_lnDeterminant = gsl_linalg_LU_lndet(m_LU);
1107  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1108  *m_env.subDisplayFile() << "In GslMatrix::lnDeterminant()"
1109  << ": before 'gsl_linalg_LU_lndet()'"
1110  << std::endl;
1111  }
1112  }
1113 
1114  return m_lnDeterminant;
1115 }
1116 
1117 unsigned int
1118 GslMatrix::rank(double absoluteZeroThreshold, double relativeZeroThreshold) const
1119 {
1120  int iRC = 0;
1121  iRC = internalSvd();
1122  if (iRC) {}; // just to remove compiler warning
1123 
1124  GslVector relativeVec(*m_svdSvec);
1125  if (relativeVec[0] > 0.) {
1126  relativeVec = (1./relativeVec[0])*relativeVec;
1127  }
1128 
1129  unsigned int rankValue = 0;
1130  for (unsigned int i = 0; i < relativeVec.sizeLocal(); ++i) {
1131  if (( (*m_svdSvec)[i] >= absoluteZeroThreshold ) &&
1132  ( relativeVec [i] >= relativeZeroThreshold )) {
1133  rankValue += 1;
1134  }
1135  }
1136 
1137  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 3)) {
1138  *m_env.subDisplayFile() << "In GslMatrix::rank()"
1139  << ": this->numRowsLocal() = " << this->numRowsLocal()
1140  << ", this->numCols() = " << this->numCols()
1141  << ", absoluteZeroThreshold = " << absoluteZeroThreshold
1142  << ", relativeZeroThreshold = " << relativeZeroThreshold
1143  << ", rankValue = " << rankValue
1144  << ", m_svdSvec = " << *m_svdSvec
1145  << ", relativeVec = " << relativeVec
1146  << std::endl;
1147  }
1148 
1149  return rankValue;
1150 }
1151 
1152 GslVector
1154  const GslVector& x) const
1155 {
1156  queso_require_equal_to_msg(this->numCols(), x.sizeLocal(), "matrix and vector have incompatible sizes");
1157 
1158  GslVector y(m_env,m_map);
1159  this->multiply(x,y);
1160 
1161  return y;
1162 }
1163 
1164 void
1166  const GslVector& x,
1167  GslVector& y) const
1168 {
1169  queso_require_equal_to_msg(this->numCols(), x.sizeLocal(), "matrix and x have incompatible sizes");
1170 
1171  queso_require_equal_to_msg(this->numRowsLocal(), y.sizeLocal(), "matrix and y have incompatible sizes");
1172 
1173  unsigned int sizeX = this->numCols();
1174  unsigned int sizeY = this->numRowsLocal();
1175  for (unsigned int i = 0; i < sizeY; ++i) {
1176  double value = 0.;
1177  for (unsigned int j = 0; j < sizeX; ++j) {
1178  value += (*this)(i,j)*x[j];
1179  }
1180  y[i] = value;
1181  }
1182 
1183  return;
1184 }
1185 
1186 GslVector
1188  const GslVector& b) const
1189 {
1190  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1191 
1192  GslVector x(m_env,m_map);
1193  this->invertMultiply(b,x);
1194 
1195  return x;
1196 }
1197 
1198 void
1200  const GslVector& b,
1201  GslVector& x) const
1202 {
1203  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1204 
1205  queso_require_equal_to_msg(x.sizeLocal(), b.sizeLocal(), "solution and rhs have incompatible sizes");
1206 
1207  int iRC;
1208  if (m_LU == NULL) {
1209  queso_require_msg(!(m_permutation), "m_permutation should be NULL");
1210 
1211  m_LU = gsl_matrix_calloc(this->numRowsLocal(),this->numCols());
1212  queso_require_msg(m_LU, "gsl_matrix_calloc() failed");
1213 
1214  iRC = gsl_matrix_memcpy(m_LU, m_mat);
1215  queso_require_msg(!(iRC), "gsl_matrix_memcpy() failed");
1216 
1217  m_permutation = gsl_permutation_calloc(numCols());
1218  queso_require_msg(m_permutation, "gsl_permutation_calloc() failed");
1219 
1220  if (m_inDebugMode) {
1221  std::cout << "In GslMatrix::invertMultiply()"
1222  << ": before LU decomposition, m_LU = ";
1223  gsl_matrix_fprintf(stdout, m_LU, "%f");
1224  std::cout << std::endl;
1225  }
1226 
1227  gsl_error_handler_t* oldHandler;
1228  oldHandler = gsl_set_error_handler_off();
1229  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1230  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1231  << ": before 'gsl_linalg_LU_decomp()'"
1232  << std::endl;
1233  }
1234  iRC = gsl_linalg_LU_decomp(m_LU,m_permutation,&m_signum);
1235  if (iRC != 0) {
1236  std::cerr << "In GslMatrix::invertMultiply()"
1237  << ", after gsl_linalg_LU_decomp()"
1238  << ": iRC = " << iRC
1239  << ", gsl error message = " << gsl_strerror(iRC)
1240  << std::endl;
1241  }
1242  gsl_set_error_handler(oldHandler);
1243  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1244  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1245  << ": after 'gsl_linalg_LU_decomp()'"
1246  << ", IRC = " << iRC
1247  << std::endl;
1248  }
1249  queso_require_msg(!(iRC), "gsl_linalg_LU_decomp() failed");
1250 
1251  if (m_inDebugMode) {
1252  std::cout << "In GslMatrix::invertMultiply()"
1253  << ": after LU decomposition, m_LU = ";
1254  gsl_matrix_fprintf(stdout, m_LU, "%f");
1255  std::cout << std::endl;
1256  }
1257  }
1258 
1259  gsl_error_handler_t* oldHandler;
1260  oldHandler = gsl_set_error_handler_off();
1261  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1262  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1263  << ": before 'gsl_linalg_LU_solve()'"
1264  << std::endl;
1265  }
1266  iRC = gsl_linalg_LU_solve(m_LU,m_permutation,b.data(),x.data());
1267  if (iRC != 0) {
1268  m_isSingular = true;
1269  std::cerr << "In GslMatrix::invertMultiply()"
1270  << ", after gsl_linalg_LU_solve()"
1271  << ": iRC = " << iRC
1272  << ", gsl error message = " << gsl_strerror(iRC)
1273  << std::endl;
1274  }
1275  gsl_set_error_handler(oldHandler);
1276  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
1277  *m_env.subDisplayFile() << "In GslMatrix::invertMultiply()"
1278  << ": after 'gsl_linalg_LU_solve()'"
1279  << ", IRC = " << iRC
1280  << std::endl;
1281  }
1282 
1283 
1284  // m_env.worldRank(),
1285  // "GslMatrix::invertMultiply()",
1286  // "gsl_linalg_LU_solve() failed");
1287 
1288  if (m_inDebugMode) {
1289  GslVector tmpVec(b - (*this)*x);
1290  std::cout << "In GslMatrix::invertMultiply()"
1291  << ": ||b - Ax||_2 = " << tmpVec.norm2()
1292  << ": ||b - Ax||_2/||b||_2 = " << tmpVec.norm2()/b.norm2()
1293  << std::endl;
1294  }
1295 
1296  return;
1297 }
1298 
1299 GslMatrix
1301 {
1302  GslMatrix X(m_env,m_map,B.numCols());
1303  this->invertMultiply(B,X);
1304 
1305  return X;
1306 }
1307 
1308 void
1310 {
1311  // Sanity Checks
1313  "Matrices B and X are incompatible");
1315  "Matrices B and X are incompatible");
1317  "This and X matrices are incompatible");
1318 
1319  // Some local variables used within the loop.
1320  GslVector b(m_env, m_map);
1321  GslVector x(m_env, m_map);
1322 
1323  for( unsigned int j = 0; j < B.numCols(); ++j )
1324  {
1325  b = B.getColumn( j );
1326 
1327  //invertMultiply will only do the LU once and store it. So we don't
1328  //need to worry about it doing LU multiple times.
1329  x = this->invertMultiply( b );
1330 
1331  X.setColumn( j, x );
1332  }
1333 
1334  return;
1335 }
1336 
1337 GslVector
1339  const GslVector& b) const
1340 {
1341  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1342 
1343  GslVector x(m_env,m_map);
1344  this->invertMultiplyForceLU(b,x);
1345 
1346  return x;
1347 }
1348 
1349 void
1351  const GslVector& b,
1352  GslVector& x) const
1353 {
1354  queso_require_equal_to_msg(this->numCols(), b.sizeLocal(), "matrix and rhs have incompatible sizes");
1355 
1356  queso_require_equal_to_msg(x.sizeLocal(), b.sizeLocal(), "solution and rhs have incompatible sizes");
1357 
1358  int iRC;
1359 
1360  if ( m_LU == NULL ) {
1361  queso_require_msg(!(m_permutation), "m_permutation should be NULL");
1362  m_LU = gsl_matrix_calloc(this->numRowsLocal(),this->numCols());
1363  }
1364  queso_require_msg(m_LU, "gsl_matrix_calloc() failed");
1365 
1366  iRC = gsl_matrix_memcpy(m_LU, m_mat);
1367  queso_require_msg(!(iRC), "gsl_matrix_memcpy() failed");
1368 
1369  if( m_permutation == NULL ) m_permutation = gsl_permutation_calloc(numCols());
1370  queso_require_msg(m_permutation, "gsl_permutation_calloc() failed");
1371 
1372  iRC = gsl_linalg_LU_decomp(m_LU,m_permutation,&m_signum);
1373  queso_require_msg(!(iRC), "gsl_linalg_LU_decomp() failed");
1374 
1375  iRC = gsl_linalg_LU_solve(m_LU,m_permutation,b.data(),x.data());
1376  if (iRC != 0) {
1377  m_isSingular = true;
1378  }
1379  queso_require_msg(!(iRC), "gsl_linalg_LU_solve() failed");
1380 
1381  return;
1382 }
1383 
1384 void
1385 GslMatrix::eigen(GslVector& eigenValues, GslMatrix* eigenVectors) const
1386 {
1387  unsigned int n = eigenValues.sizeLocal();
1388 
1389  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1390 
1391  if (eigenVectors) {
1392  queso_require_equal_to_msg(eigenValues.sizeLocal(), eigenVectors->numRowsLocal(), "different input vector sizes");
1393  }
1394 
1395  if (eigenVectors == NULL) {
1396  gsl_eigen_symm_workspace* w = gsl_eigen_symm_alloc((size_t) n);
1397  gsl_eigen_symm(m_mat,eigenValues.data(),w);
1398  gsl_eigen_symm_free(w);
1399  }
1400  else {
1401  gsl_eigen_symmv_workspace* w = gsl_eigen_symmv_alloc((size_t) n);
1402  gsl_eigen_symmv(m_mat,eigenValues.data(),eigenVectors->m_mat,w);
1403  gsl_eigen_symmv_sort(eigenValues.data(),eigenVectors->m_mat,GSL_EIGEN_SORT_VAL_ASC);
1404  gsl_eigen_symmv_free(w);
1405  }
1406 
1407  return;
1408 }
1409 
1410 void
1411 GslMatrix::largestEigen(double& eigenValue, GslVector& eigenVector) const
1412 {
1413 
1414  // Sanity Checks
1415  unsigned int n = eigenVector.sizeLocal();
1416 
1417  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1418 
1419  /* The following notation is used:
1420  z = vector used in iteration that ends up being the eigenvector corresponding to the
1421  largest eigenvalue
1422  w = vector used in iteration that we extract the largest eigenvalue from. */
1423 
1424  // Some parameters associated with the algorithm
1425  // TODO: Do we want to add the ability to have these set by the user?
1426  const unsigned int max_num_iterations = 10000;
1427  const double tolerance = 1.0e-13;
1428 
1429  // Create temporary working vectors.
1430  // TODO: We shouldn't have to use these - we ought to be able to work directly
1431  // TODO: with eigenValue and eigenVector. Optimize this once we have regression
1432  // TODO: tests.
1433  GslVector z(m_env, m_map, 1.0 ); // Needs to be initialized to 1.0
1434  GslVector w(m_env, m_map);
1435 
1436  // Some variables we use inside the loop.
1437  int index;
1438  double residual;
1439  double lambda;
1440 
1441  for( unsigned int k = 0; k < max_num_iterations; ++k )
1442  {
1443  w = (*this) * z;
1444 
1445  // For this algorithm, it's crucial to get the maximum in
1446  // absolute value, but then to normalize by the actual value
1447  // and *not* the absolute value.
1448  index = (w.abs()).getMaxValueIndex();
1449 
1450  lambda = w[index];
1451 
1452  z = (1.0/lambda) * w;
1453 
1454  // Here we use the norm of the residual as our convergence check:
1455  // norm( A*x - \lambda*x )
1456  residual = ( (*this)*z - lambda*z ).norm2();
1457 
1458  if( residual < tolerance )
1459  {
1460  eigenValue = lambda;
1461 
1462  // TODO: Do we want to normalize this so eigenVector.norm2() = 1?
1463  eigenVector = z;
1464  return;
1465  }
1466 
1467  }
1468 
1469  // If we reach this point, then we didn't converge. Print error message
1470  // to this effect.
1471  // TODO: We know we failed at this point - need a way to not need a test
1472  // TODO: Just specify the error.
1473  queso_require_less_msg(residual, tolerance, "Maximum num iterations exceeded");
1474 
1475 
1476  return;
1477 }
1478 
1479 void
1480 GslMatrix::smallestEigen(double& eigenValue, GslVector& eigenVector) const
1481 {
1482  // Sanity Checks
1483  unsigned int n = eigenVector.sizeLocal();
1484 
1485  queso_require_not_equal_to_msg(n, 0, "invalid input vector size");
1486 
1487  /* The following notation is used:
1488  z = vector used in iteration that ends up being the eigenvector corresponding to the
1489  largest eigenvalue
1490  w = vector used in iteration that we extract the largest eigenvalue from. */
1491 
1492  // Some parameters associated with the algorithm
1493  // TODO: Do we want to add the ability to have these set by the user?
1494  const unsigned int max_num_iterations = 1000;
1495  const double tolerance = 1.0e-13;
1496 
1497  // Create temporary working vectors.
1498  // TODO: We shouldn't have to use these - we ought to be able to work directly
1499  // TODO: with eigenValue and eigenVector. Optimize this once we have regression
1500  // TODO: tests.
1501  GslVector z(m_env, m_map, 1.0 ); // Needs to be initialized to 1.0
1502  GslVector w(m_env, m_map);
1503 
1504  // Some variables we use inside the loop.
1505  int index;
1506  double residual;
1507  double one_over_lambda;
1508  double lambda;
1509 
1510  for( unsigned int k = 0; k < max_num_iterations; ++k )
1511  {
1512  w = (*this).invertMultiplyForceLU( z );
1513 
1514  // For this algorithm, it's crucial to get the maximum in
1515  // absolute value, but then to normalize by the actual value
1516  // and *not* the absolute value.
1517  index = (w.abs()).getMaxValueIndex();
1518 
1519  // Remember: Inverse power method solves for max 1/lambda ==> lambda smallest
1520  one_over_lambda = w[index];
1521 
1522  lambda = 1.0/one_over_lambda;
1523 
1524  z = lambda * w;
1525 
1526  // Here we use the norm of the residual as our convergence check:
1527  // norm( A*x - \lambda*x )
1528  residual = ( (*this)*z - lambda*z ).norm2();
1529 
1530  if( residual < tolerance )
1531  {
1532  eigenValue = lambda;
1533 
1534  // TODO: Do we want to normalize this so eigenVector.norm2() = 1?
1535  eigenVector = z;
1536  return;
1537  }
1538 
1539  }
1540 
1541  // If we reach this point, then we didn't converge. Print error message
1542  // to this effect.
1543  // TODO: We know we failed at this point - need a way to not need a test
1544  // TODO: Just specify the error.
1545  queso_require_less_msg(residual, tolerance, "Maximum num iterations exceeded");
1546 
1547  return;
1548 }
1549 
1550 void
1551 GslMatrix::getColumn(unsigned int column_num, GslVector& column) const
1552 {
1553  // Sanity checks
1554  queso_require_less_msg(column_num, this->numCols(), "Specified row number not within range");
1555 
1556  queso_require_equal_to_msg(column.sizeLocal(), this->numRowsLocal(), "column vector not same size as this matrix");
1557 
1558  // Temporary working vector
1559  gsl_vector* gsl_column = gsl_vector_alloc( column.sizeLocal() );
1560 
1561  int error_code = gsl_matrix_get_col( gsl_column, m_mat, column_num );
1562  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_get_col failed");
1563 
1564  // Copy column from gsl matrix into our GslVector object
1565  for( unsigned int i = 0; i < column.sizeLocal(); ++i )
1566  {
1567  column[i] = gsl_vector_get( gsl_column, i );
1568  }
1569 
1570  // Clean up gsl temporaries
1571  gsl_vector_free( gsl_column );
1572 
1573  return;
1574 }
1575 
1576 void
1577 GslMatrix::getRow(unsigned int row_num, GslVector& row) const
1578 {
1579  // Sanity checks
1580  queso_require_less_msg(row_num, this->numRowsLocal(), "Specified row number not within range");
1581 
1582  queso_require_equal_to_msg(row.sizeLocal(), this->numCols(), "row vector not same size as this matrix");
1583 
1584  // Temporary working vector
1585  gsl_vector* gsl_row = gsl_vector_alloc( row.sizeLocal() );
1586 
1587  int error_code = gsl_matrix_get_row( gsl_row, m_mat, row_num );
1588  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_get_row failed");
1589 
1590  // Copy row from gsl matrix into our GslVector object
1591  for( unsigned int i = 0; i < row.sizeLocal(); ++i )
1592  {
1593  row[i] = gsl_vector_get( gsl_row, i );
1594  }
1595 
1596  // Clean up gsl temporaries
1597  gsl_vector_free( gsl_row );
1598 
1599  return;
1600 }
1601 
1602 GslVector
1603 GslMatrix::getRow(unsigned int row_num ) const
1604 {
1605  // We rely on the void getRow's to do sanity checks
1606  // So we don't do them here.
1607 
1608  GslVector row(m_env, m_map);
1609 
1610  this->getRow( row_num, row );
1611 
1612  return row;
1613 }
1614 
1615 GslVector
1616 GslMatrix::getColumn(unsigned int column_num ) const
1617 {
1618  // We rely on the void getRow's to do sanity checks
1619  // So we don't do them here.
1620 
1621  GslVector column(m_env, m_map);
1622 
1623  this->getColumn( column_num, column );
1624 
1625  return column;
1626 }
1627 
1628 void
1629 GslMatrix::setRow(unsigned int row_num, const GslVector& row)
1630 {
1631  this->resetLU();
1632  // Sanity checks
1633  queso_require_less_msg(row_num, this->numRowsLocal(), "Specified row number not within range");
1634 
1635  queso_require_equal_to_msg(row.sizeLocal(), this->numCols(), "row vector not same size as this matrix");
1636 
1637  gsl_vector* gsl_row = row.data();
1638 
1639  int error_code = gsl_matrix_set_row( m_mat, row_num, gsl_row );
1640  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_set_row failed");
1641 
1642  return;
1643 }
1644 
1645 void
1646 GslMatrix::setColumn(unsigned int column_num, const GslVector& column)
1647 {
1648  this->resetLU();
1649  // Sanity checks
1650  queso_require_less_msg(column_num, this->numCols(), "Specified column number not within range");
1651 
1652  queso_require_equal_to_msg(column.sizeLocal(), this->numRowsLocal(), "column vector not same size as this matrix");
1653 
1654  gsl_vector* gsl_column = column.data();
1655 
1656  int error_code = gsl_matrix_set_col( m_mat, column_num, gsl_column );
1657  queso_require_equal_to_msg(error_code, 0, "gsl_matrix_set_col failed");
1658 
1659  return;
1660 }
1661 
1662 void
1663 GslMatrix::mpiSum( const MpiComm& comm, GslMatrix& M_global ) const
1664 {
1665  // Sanity Checks
1666  UQ_FATAL_RC_MACRO(((this->numRowsLocal() != M_global.numRowsLocal()) ||
1667  (this->numCols() != M_global.numCols() )),
1668  env().fullRank(),
1669  "GslMatrix::mpiSum()",
1670  "local and global matrices incompatible");
1671 
1672  /* TODO: Probably a better way to handle this unpacking/packing of data */
1673  int size = M_global.numRowsLocal()*M_global.numCols();
1674  std::vector<double> local( size, 0.0 );
1675  std::vector<double> global( size, 0.0 );
1676 
1677  int k;
1678  for( unsigned int i = 0; i < this->numRowsLocal(); i++ )
1679  {
1680  for( unsigned int j = 0; j < this->numCols(); j++ )
1681  {
1682  k = i + j*M_global.numCols();
1683 
1684  local[k] = (*this)(i,j);
1685  }
1686  }
1687 
1688  comm.Allreduce<double>(&local[0], &global[0], size, RawValue_MPI_SUM,
1689  "GslMatrix::mpiSum()",
1690  "failed MPI.Allreduce()");
1691 
1692  for( unsigned int i = 0; i < this->numRowsLocal(); i++ )
1693  {
1694  for( unsigned int j = 0; j < this->numCols(); j++ )
1695  {
1696  k = i + j*M_global.numCols();
1697 
1698  M_global(i,j) = global[k];
1699  }
1700  }
1701 
1702  return;
1703 }
1704 
1705 void
1707  const GslVector& x1Vec,
1708  const GslMatrix& y1Mat,
1709  const GslVector& x2Vec)
1710 {
1711  queso_require_greater_msg(x1Vec.sizeLocal(), 1, "invalid 'x1' size");
1712 
1713  queso_require_equal_to_msg(x1Vec.sizeLocal(), y1Mat.numRowsLocal(), "invalid 'x1' and 'y1' sizes");
1714 
1715  queso_require_equal_to_msg(x2Vec.sizeLocal(), this->numRowsLocal(), "invalid 'x2' and 'this' sizes");
1716 
1717  queso_require_equal_to_msg(y1Mat.numCols(), this->numCols(), "invalid 'y1' and 'this' sizes");
1718 
1719  GslVector y1Vec(x1Vec);
1720  GslVector y2Vec(x2Vec);
1721  for (unsigned int colId = 0; colId < y1Mat.numCols(); ++colId) {
1722  y1Mat.getColumn(colId,y1Vec);
1723  y2Vec.matlabLinearInterpExtrap(x1Vec,y1Vec,x2Vec);
1724  this->setColumn(colId,y2Vec);
1725  }
1726 
1727  return;
1728 }
1729 
1730 gsl_matrix*
1732 {
1733  return m_mat;
1734 }
1735 
1736 void
1737 GslMatrix::print(std::ostream& os) const
1738 {
1739  unsigned int nRows = this->numRowsLocal();
1740  unsigned int nCols = this->numCols();
1741 
1742  if (m_printHorizontally) {
1743  for (unsigned int i = 0; i < nRows; ++i) {
1744  for (unsigned int j = 0; j < nCols; ++j) {
1745  os << (*this)(i,j)
1746  << " ";
1747  }
1748  if (i != (nRows-1)) os << "; ";
1749  }
1750  //os << std::endl;
1751  }
1752  else {
1753  for (unsigned int i = 0; i < nRows; ++i) {
1754  for (unsigned int j = 0; j < nCols; ++j) {
1755  os << (*this)(i,j)
1756  << " ";
1757  }
1758  os << std::endl;
1759  }
1760  }
1761 
1762  return;
1763 }
1764 
1765 void
1767  const std::string& varNamePrefix,
1768  const std::string& fileName,
1769  const std::string& fileType,
1770  const std::set<unsigned int>& allowedSubEnvIds) const
1771 {
1772  queso_require_greater_equal_msg(m_env.subRank(), 0, "unexpected subRank");
1773 
1774  queso_require_less_equal_msg(this->numOfProcsForStorage(), 1, "implemented just for sequential vectors for now");
1775 
1776  FilePtrSetStruct filePtrSet;
1777  if (m_env.openOutputFile(fileName,
1778  fileType, // "m or hdf"
1779  allowedSubEnvIds,
1780  false,
1781  filePtrSet)) {
1782  unsigned int nRows = this->numRowsLocal();
1783  unsigned int nCols = this->numCols();
1784  *filePtrSet.ofsVar << varNamePrefix << "_sub" << m_env.subIdString() << " = zeros(" << nRows
1785  << "," << nCols
1786  << ");"
1787  << std::endl;
1788  *filePtrSet.ofsVar << varNamePrefix << "_sub" << m_env.subIdString() << " = [";
1789 
1790  for (unsigned int i = 0; i < nRows; ++i) {
1791  for (unsigned int j = 0; j < nCols; ++j) {
1792  *filePtrSet.ofsVar << (*this)(i,j)
1793  << " ";
1794  }
1795  *filePtrSet.ofsVar << "\n";
1796  }
1797  *filePtrSet.ofsVar << "];\n";
1798 
1799  m_env.closeFile(filePtrSet,fileType);
1800  }
1801 
1802  return;
1803 }
1804 
1805 void
1807  const std::string& fileName,
1808  const std::string& fileType,
1809  const std::set<unsigned int>& allowedSubEnvIds)
1810 {
1811  queso_require_greater_equal_msg(m_env.subRank(), 0, "unexpected subRank");
1812 
1813  queso_require_less_equal_msg(this->numOfProcsForStorage(), 1, "implemented just for sequential vectors for now");
1814 
1815  FilePtrSetStruct filePtrSet;
1816  if (m_env.openInputFile(fileName,
1817  fileType, // "m or hdf"
1818  allowedSubEnvIds,
1819  filePtrSet)) {
1820 
1821  // palms
1822  unsigned int nRowsLocal = this->numRowsLocal();
1823 
1824  // In the logic below, the id of a line' begins with value 0 (zero)
1825  unsigned int idOfMyFirstLine = 1;
1826  unsigned int idOfMyLastLine = nRowsLocal;
1827  unsigned int nCols = this->numCols();
1828 
1829  // Read number of matrix rows in the file by taking care of the first line,
1830  // which resembles something like 'variable_name = zeros(n_rows,n_cols);'
1831  std::string tmpString;
1832 
1833  // Read 'variable name' string
1834  *filePtrSet.ifsVar >> tmpString;
1835  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1836 
1837  // Read '=' sign
1838  *filePtrSet.ifsVar >> tmpString;
1839  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1840  queso_require_equal_to_msg(tmpString, "=", "string should be the '=' sign");
1841 
1842  // Read 'zeros(n_rows,n_cols)' string
1843  *filePtrSet.ifsVar >> tmpString;
1844  //std::cout << "Just read '" << tmpString << "'" << std::endl;
1845  unsigned int posInTmpString = 6;
1846 
1847  // Isolate 'n_rows' in a string
1848  char nRowsString[tmpString.size()-posInTmpString+1];
1849  unsigned int posInRowsString = 0;
1850  do {
1851  queso_require_less_msg(posInTmpString, tmpString.size(), "symbol ',' not found in first line of file");
1852  nRowsString[posInRowsString++] = tmpString[posInTmpString++];
1853  } while (tmpString[posInTmpString] != ',');
1854  nRowsString[posInRowsString] = '\0';
1855 
1856  // Isolate 'n_cols' in a string
1857  posInTmpString++; // Avoid reading ',' char
1858  char nColsString[tmpString.size()-posInTmpString+1];
1859  unsigned int posInColsString = 0;
1860  do {
1861  queso_require_less_msg(posInTmpString, tmpString.size(), "symbol ')' not found in first line of file");
1862  nColsString[posInColsString++] = tmpString[posInTmpString++];
1863  } while (tmpString[posInTmpString] != ')');
1864  nColsString[posInColsString] = '\0';
1865 
1866  // Convert 'n_rows' and 'n_cols' strings to numbers
1867  unsigned int numRowsInFile = (unsigned int) strtod(nRowsString,NULL);
1868  unsigned int numColsInFile = (unsigned int) strtod(nColsString,NULL);
1869  if (m_env.subDisplayFile()) {
1870  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1871  << ": fullRank " << m_env.fullRank()
1872  << ", numRowsInFile = " << numRowsInFile
1873  << ", numColsInFile = " << numColsInFile
1874  << ", nRowsLocal = " << nRowsLocal
1875  << ", nCols = " << nCols
1876  << std::endl;
1877  }
1878 
1879  // Check if [num of rows in file] == [requested matrix row size]
1880  queso_require_equal_to_msg(numRowsInFile, nRowsLocal, "size of vec in file is not big enough");
1881 
1882  // Check if [num of cols in file] == [num cols in current matrix]
1883  queso_require_equal_to_msg(numColsInFile, nCols, "number of parameters of vec in file is different than number of parameters in this vec object");
1884 
1885  // Code common to any core in a communicator
1886  unsigned int maxCharsPerLine = 64*nCols; // Up to about 60 characters to represent each parameter value
1887 
1888  unsigned int lineId = 0;
1889  while (lineId < idOfMyFirstLine) {
1890  filePtrSet.ifsVar->ignore(maxCharsPerLine,'\n');
1891  lineId++;
1892  };
1893 
1894  if (m_env.subDisplayFile()) {
1895  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1896  << ": beginning to read input actual data"
1897  << std::endl;
1898  }
1899 
1900  // Take care of initial part of the first data line,
1901  // which resembles something like 'variable_name = [value1 value2 ...'
1902  // Read 'variable name' string
1903  *filePtrSet.ifsVar >> tmpString;
1904  //std::cout << "Core 0 just read '" << tmpString << "'" << std::endl;
1905 
1906  // Read '=' sign
1907  *filePtrSet.ifsVar >> tmpString;
1908  //std::cout << "Core 0 just read '" << tmpString << "'" << std::endl;
1909  queso_require_equal_to_msg(tmpString, "=", "in core 0, string should be the '=' sign");
1910 
1911  // Take into account the ' [' portion
1912  std::streampos tmpPos = filePtrSet.ifsVar->tellg();
1913  filePtrSet.ifsVar->seekg(tmpPos+(std::streampos)2);
1914 
1915  if (m_env.subDisplayFile()) {
1916  *m_env.subDisplayFile() << "In GslMatrix::subReadContents()"
1917  << ": beginning to read lines with numbers only"
1918  << ", lineId = " << lineId
1919  << ", idOfMyFirstLine = " << idOfMyFirstLine
1920  << ", idOfMyLastLine = " << idOfMyLastLine
1921  << std::endl;
1922  }
1923 
1924  double tmpRead;
1925  while (lineId <= idOfMyLastLine) {
1926  for (unsigned int j = 0; j < nCols; ++j) {
1927  *filePtrSet.ifsVar >> tmpRead;
1928  (*this)(lineId-idOfMyFirstLine,j) = tmpRead;
1929  }
1930  lineId++;
1931  };
1932 
1933  m_env.closeFile(filePtrSet,fileType);
1934  }
1935 
1936  return;
1937 }
1938 
1939 std::ostream&
1940 operator<<(std::ostream& os, const GslMatrix& obj)
1941 {
1942  obj.print(os);
1943 
1944  return os;
1945 }
1946 
1947 GslMatrix operator*(double a, const GslMatrix& mat)
1948 {
1949  GslMatrix answer(mat);
1950  answer *= a;
1951  return answer;
1952 }
1953 
1954 GslVector operator*(const GslMatrix& mat, const GslVector& vec)
1955 {
1956  return mat.multiply(vec);
1957 }
1958 
1960 {
1961  unsigned int m1Rows = m1.numRowsLocal();
1962  unsigned int m1Cols = m1.numCols();
1963  unsigned int m2Rows = m2.numRowsLocal();
1964  unsigned int m2Cols = m2.numCols();
1965 
1966  queso_require_equal_to_msg(m1Cols, m2Rows, "different sizes m1Cols and m2Rows");
1967 
1968  GslMatrix mat(m1.env(),m1.map(),m2Cols);
1969 
1970  //std::cout << "In GslMatrix(mat * mat): m1Cols = " << m1Cols << std::endl;
1971 
1972  unsigned int commonSize = m1Cols;
1973  for (unsigned int row1 = 0; row1 < m1Rows; ++row1) {
1974  for (unsigned int col2 = 0; col2 < m2Cols; ++col2) {
1975  double result = 0.;
1976  for (unsigned int k = 0; k < commonSize; ++k) {
1977  result += m1(row1,k)*m2(k,col2);
1978  }
1979  mat(row1,col2) = result;
1980  }
1981  //std::cout << "In GslMatrix(mat * mat): ended row " << row1 << std::endl;
1982  }
1983 
1984  return mat;
1985 }
1986 
1988 {
1989  GslMatrix answer(m1);
1990  answer += m2;
1991  return answer;
1992 }
1993 
1995 {
1996  GslMatrix answer(m1);
1997  answer -= m2;
1998  return answer;
1999 }
2000 
2002 {
2003  unsigned int nRows = v1.sizeLocal();
2004  unsigned int nCols = v2.sizeLocal();
2005  GslMatrix answer(v1.env(),v1.map(),nCols);
2006 
2007  for (unsigned int i = 0; i < nRows; ++i) {
2008  double value1 = v1[i];
2009  for (unsigned int j = 0; j < nCols; ++j) {
2010  answer(i,j) = value1*v2[j];
2011  }
2012  }
2013 
2014  return answer;
2015 }
2016 
2018 {
2019  unsigned int vSize = vec.sizeLocal();
2020  unsigned int mRows = mat.numRowsLocal();
2021  unsigned int mCols = mat.numCols();
2022 
2023  queso_require_equal_to_msg(vSize, mRows, "size of vector is different from the number of rows in matrix");
2024 
2025  queso_require_equal_to_msg(mCols, mRows, "routine currently works for square matrices only");
2026 
2027  GslMatrix answer(mat);
2028  for (unsigned int i = 0; i < mRows; ++i) {
2029  double vecValue = vec[i];
2030  for (unsigned int j = 0; j < mCols; ++j) {
2031  answer(i,j) *= vecValue;
2032  }
2033  }
2034 
2035  return answer;
2036 }
2037 
2039 {
2040  unsigned int vSize = vec.sizeLocal();
2041  unsigned int mRows = mat.numRowsLocal();
2042  unsigned int mCols = mat.numCols();
2043 
2044  queso_require_equal_to_msg(vSize, mCols, "size of vector is different from the number of cols in matrix");
2045 
2046  queso_require_equal_to_msg(mCols, mRows, "routine currently works for square matrices only");
2047 
2048  GslMatrix answer(mat);
2049  for (unsigned int j = 0; j < mCols; ++j) {
2050  double vecValue = vec[j];
2051  for (unsigned int i = 0; i < mRows; ++i) {
2052  answer(i,j) *= vecValue;
2053  }
2054  }
2055 
2056  return answer;
2057 }
2058 
2059 } // End namespace QUESO
GslMatrix transpose() const
This function calculated the transpose of this matrix (square).
Definition: GslMatrix.C:693
unsigned int displayVerbosity() const
Definition: Environment.C:400
void cwSet(double value)
Component-wise set all values to this with value.
Definition: GslMatrix.C:347
int chol()
Computes Cholesky factorization of a real symmetric positive definite matrix this.
Definition: GslMatrix.C:408
bool m_printHorizontally
Flag for either or not print this matrix.
Definition: Matrix.h:131
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
double normFrob() const
Returns the Frobenius norm of this matrix.
Definition: GslMatrix.C:293
void mpiSum(const MpiComm &comm, GslMatrix &M_global) const
Definition: GslMatrix.C:1663
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:1629
std::ofstream * ofsVar
Provides a stream interface to write data to files.
Definition: Environment.h:81
GslMatrix & operator-=(const GslMatrix &rhs)
Stores in this the coordinate-wise subtraction of this by rhs.
Definition: GslMatrix.C:207
int subRank() const
Access function for sub-rank.
Definition: Environment.C:245
GslMatrix & operator*=(double a)
Stores in this the coordinate-wise multiplication of this and a.
Definition: GslMatrix.C:177
GslMatrix()
Default Constructor.
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:1646
const int UQ_MATRIX_IS_NOT_POS_DEFINITE_RC
Definition: Defines.h:97
Map * m_svdColMap
Mapping for matrices involved in the singular value decomposition (svd) routine.
Definition: GslMatrix.h:410
int dim
Definition: ann2fig.cpp:81
#define UQ_FATAL_RC_MACRO(macroIRc, givenRank, where, what)
Definition: Defines.h:168
bool m_inDebugMode
Flag for either or not QUESO is in debug mode.
Definition: Matrix.h:134
#define RawValue_MPI_SUM
Definition: MpiComm.h:71
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 m_determinant
The determinant of this matrix.
Definition: GslMatrix.h:438
int k
Definition: ann_sample.cpp:53
const Map & m_map
Mapping variable.
Definition: Matrix.h:126
Class for matrix operations (virtual).
Definition: Matrix.h:46
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:1766
bool m_isSingular
Indicates whether or not this matrix is singular.
Definition: GslMatrix.h:456
A class for partitioning vectors and matrices.
Definition: Map.h:49
void cwExtract(unsigned int rowId, unsigned int colId, GslMatrix &mat) const
Definition: GslMatrix.C:385
#define queso_require_less_msg(expr1, expr2, msg)
Definition: asserts.h:87
unsigned int numCols() const
Returns the column dimension of this matrix.
Definition: GslMatrix.C:287
int fullRank() const
Returns the process full rank.
Definition: Environment.C:226
const Map & map() const
Definition: Matrix.C:54
int m_signum
m_signum stores the sign of the permutation of the LU decomposition PA = LU.
Definition: GslMatrix.h:453
void matlabLinearInterpExtrap(const GslVector &x1Vec, const GslVector &y1Vec, const GslVector &x2Vec)
Definition: GslVector.C:556
void zeroLower(bool includeDiagonal=false)
This function sets all the entries bellow the main diagonal of this matrix to zero.
Definition: GslMatrix.C:591
GslMatrix matrixProduct(const GslVector &v1, const GslVector &v2)
Definition: GslMatrix.C:2001
unsigned int numRowsLocal() const
Returns the local row dimension of this matrix.
Definition: GslMatrix.C:275
#define queso_require_not_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:86
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:887
GslMatrix operator*(double a, const GslMatrix &mat)
Definition: GslMatrix.C:1947
const int UQ_MATRIX_SVD_FAILED_RC
Definition: Defines.h:100
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:1737
#define queso_require_less_equal_msg(expr1, expr2, msg)
Definition: asserts.h:89
double m_lnDeterminant
The natural logarithm of the determinant of this matrix.
Definition: GslMatrix.h:441
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
#define queso_require_msg(asserted, msg)
Definition: asserts.h:69
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:305
#define queso_require_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:85
double lnDeterminant() const
Calculates the ln(determinant) of this matrix.
Definition: GslMatrix.C:1077
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
#define queso_require_greater_equal_msg(expr1, expr2, msg)
Definition: asserts.h:90
void cwSet(double value)
Component-wise sets all values to this with value.
Definition: GslVector.C:326
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:951
void closeFile(FilePtrSetStruct &filePtrSet, const std::string &fileType) const
Closes the file.
Definition: Environment.C:1034
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:429
void matlabLinearInterpExtrap(const GslVector &x1Vec, const GslMatrix &y1Mat, const GslVector &x2Vec)
Definition: GslMatrix.C:1706
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:423
GslMatrix leftDiagScaling(const GslVector &vec, const GslMatrix &mat)
Definition: GslMatrix.C:2017
std::ostream & operator<<(std::ostream &os, const BaseEnvironment &obj)
GslVector abs() const
This function returns absolute value of elements in this.
Definition: GslVector.C:1081
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:1012
GslMatrix rightDiagScaling(const GslMatrix &mat, const GslVector &vec)
Definition: GslMatrix.C:2038
gsl_matrix * m_mat
GSL matrix, also referred to as this matrix.
Definition: GslMatrix.h:401
Class for matrix operations using GSL library.
Definition: GslMatrix.h:49
Struct for handling data input and output from files.
Definition: Environment.h:72
std::ofstream * subDisplayFile() const
Access function for m_subDisplayFile (displays file on stream).
Definition: Environment.C:278
gsl_matrix * m_LU
GSL matrix for the LU decomposition of m_mat.
Definition: GslMatrix.h:404
const Map & map() const
Definition: Vector.C:61
const BaseEnvironment & env() const
Definition: Matrix.C:47
double max() const
Returns the maximum element value of the matrix.
Definition: GslMatrix.C:329
This (virtual) class sets up the environment underlying the use of the QUESO library by an executable...
Definition: Environment.h:193
void filterLargeValues(double thresholdValue)
This function sets to zero (filters) all entries of this matrix which are greater than thresholdValue...
Definition: GslMatrix.C:670
gsl_permutation * m_permutation
The permutation matrix of a LU decomposition.
Definition: GslMatrix.h:447
GslMatrix * m_inverse
Inverse matrix of this.
Definition: GslMatrix.h:407
unsigned int numOfProcsForStorage() const
Definition: Matrix.C:62
void smallestEigen(double &eigenValue, GslVector &eigenVector) const
This function finds smallest eigenvalue, namely eigenValue, of this matrix and its corresponding eige...
Definition: GslMatrix.C:1480
GslVector invertMultiplyForceLU(const GslVector &b) const
This function calculates the inverse of this matrix and multiplies it with vector b...
Definition: GslMatrix.C:1338
unsigned int numRowsGlobal() const
Returns the global row dimension of this matrix.
Definition: GslMatrix.C:281
gsl_vector * data() const
Definition: GslVector.C:969
double normMax() const
Returns the Frobenius norm of this matrix.
Definition: GslMatrix.C:311
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:751
const BaseEnvironment & m_env
QUESO environment variable.
Definition: Matrix.h:116
unsigned int sizeLocal() const
Returns the length of this vector.
Definition: GslVector.C:240
std::ifstream * ifsVar
Provides a stream interface to read data from files.
Definition: Environment.h:84
gsl_matrix * data()
Returns this matrix.
Definition: GslMatrix.C:1731
GslMatrix operator-(const GslMatrix &m1, const GslMatrix &m2)
Definition: GslMatrix.C:1994
GslMatrix inverse() const
This function calculated the inverse of this matrix (square).
Definition: GslMatrix.C:711
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:1806
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 & operator+=(const GslMatrix &rhs)
Stores in this the coordinate-wise addition of this and rhs.
Definition: GslMatrix.C:196
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:1577
GslVector multiply(const GslVector &x) const
This function multiplies this matrix by vector x and returns the resulting vector.
Definition: GslMatrix.C:1153
GslMatrix operator+(const GslMatrix &m1, const GslMatrix &m2)
Definition: GslMatrix.C:1987
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
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:823
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:471
GslMatrix * m_svdUmat
m_svdUmat stores the M-by-N orthogonal matrix U after the singular value decomposition of a matrix...
Definition: GslMatrix.h:416
Class for vector operations using GSL library.
Definition: GslVector.h:49
unsigned int checkingLevel() const
Access function to private attribute m_checkingLevel.
Definition: Environment.C:414
const GslMatrix & svdMatV() const
This function calls private member GslMatrix::internalSvd() to set a N-by-N orthogonal square matrix ...
Definition: GslMatrix.C:522
The QUESO MPI Communicator Class.
Definition: MpiComm.h:203
void copy(const GslMatrix &src)
In this function this matrix receives a copy of matrix src.
Definition: GslMatrix.C:220
GslMatrix & operator=(const GslMatrix &rhs)
Copies values from matrix rhs to this.
Definition: GslMatrix.C:169
int worldRank() const
Returns the process world rank.
Definition: Environment.C:220
const BaseEnvironment & env() const
Definition: Vector.C:54
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 rank(double absoluteZeroThreshold, double relativeZeroThreshold) const
This function returns the number of singular values of this matrix (rank).
Definition: GslMatrix.C:1118
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:1551
#define queso_require_greater_msg(expr1, expr2, msg)
Definition: asserts.h:88
GslVector invertMultiply(const GslVector &b) const
This function calculates the inverse of this matrix and multiplies it with vector b...
Definition: GslMatrix.C:1187
GslMatrix & operator/=(double a)
Stores in this the coordinate-wise division of this by a.
Definition: GslMatrix.C:187
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:435
virtual void base_copy(const Matrix &src)
Copies base data from matrix src to this matrix.
Definition: Matrix.C:99
void largestEigen(double &eigenValue, GslVector &eigenVector) const
This function finds largest eigenvalue, namely eigenValue, of this matrix and its corresponding eigen...
Definition: GslMatrix.C:1411
void eigen(GslVector &eigenValues, GslMatrix *eigenVectors) const
This function computes the eigenvalues of a real symmetric matrix.
Definition: GslMatrix.C:1385
#define UQ_RC_MACRO(macroIRc, givenRank, where, what, retValue)
Definition: Defines.h:137
double norm2() const
Returns the 2-norm (Euclidean norm) of the vector.
Definition: GslVector.C:280
double determinant() const
Calculates the determinant of this matrix.
Definition: GslMatrix.C:1036
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
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:846
~GslMatrix()
Destructor.
Definition: GslMatrix.C:161

Generated on Fri Jun 17 2016 14:17:40 for queso-0.55.0 by  doxygen 1.8.5