queso-0.51.1
Miscellaneous.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,2009,2010,2011,2012,2013 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/Defines.h>
26 #include <queso/Miscellaneous.h>
27 #include <queso/GslVector.h>
28 #include <queso/GslMatrix.h>
29 #include <sys/time.h>
30 #include <iostream>
31 #include <fstream>
32 #include <libgen.h>
33 #include <sys/stat.h>
34 #include <cmath>
35 
36 namespace QUESO {
37 
38 void
40  const std::string& inputString,
41  std::vector<double>& outputDoubles)
42 {
43  //std::cout << "In MiscReadDoublesFromString()"
44  // << ": inputString = " << inputString
45  // << std::endl;
46  outputDoubles.clear();
47  bool aDoubleIsBeingRead = false;
48  std::string::size_type positionOfFirstChar = 0;
49  std::string::size_type numberOfChars = 0;
50  for (std::string::size_type i = 0; i < inputString.size(); ++i) {
51  UQ_FATAL_TEST_MACRO((inputString[i] == '\0'),
53  "MiscReadDoublesFromString()",
54  "character '\0' should not be found!");
55  if (inputString[i] == ' ') {
56  if (aDoubleIsBeingRead == true) {
57  // We just finished reading the current string/double. Convert string to double now.
58  char tmpVar[numberOfChars+1];
59  for (std::string::size_type j = 0; j < numberOfChars; ++j) {
60  tmpVar[j] = inputString[positionOfFirstChar+j];
61  }
62  tmpVar[numberOfChars] = '\0';
63  outputDoubles.push_back(strtod(tmpVar,NULL));
64 
65  // Continue loop
66  aDoubleIsBeingRead = false;
67  positionOfFirstChar = 0;
68  numberOfChars = 0;
69  }
70  }
71  else {
72  if (aDoubleIsBeingRead == false) {
73  aDoubleIsBeingRead = true;
74  positionOfFirstChar = i;
75  }
76  numberOfChars++;
77  }
78  } // for
79  if (aDoubleIsBeingRead == true) {
80  // We just finished reading the current string/double. Convert string to double now.
81  char tmpVar[numberOfChars+1];
82  for (std::string::size_type j = 0; j < numberOfChars; ++j) {
83  tmpVar[j] = inputString[positionOfFirstChar+j];
84  }
85  tmpVar[numberOfChars] = '\0';
86  outputDoubles.push_back(strtod(tmpVar,NULL));
87  }
88  std::vector<double>(outputDoubles).swap(outputDoubles);
89 
90  return;
91 }
92 
93 void
95  const std::string& inputString,
96  std::vector<std::string>& outputWords)
97 {
98  //std::cout << "In MiscReadWordsFromString()"
99  // << ": inputString = " << inputString
100  // << std::endl;
101  outputWords.clear();
102  bool aWordIsBeingRead = false;
103  std::string::size_type positionOfFirstChar = 0;
104  std::string::size_type numberOfChars = 0;
105  for (std::string::size_type i = 0; i < inputString.size(); ++i) {
106  UQ_FATAL_TEST_MACRO((inputString[i] == '\0'),
108  "MiscReadWordsFromString()",
109  "character '\0' should not be found!");
110  if (inputString[i] == ' ') {
111  if (aWordIsBeingRead == true) {
112  // We just finished reading the current string/word.
113  char tmpVar[numberOfChars+1];
114  for (std::string::size_type j = 0; j < numberOfChars; ++j) {
115  tmpVar[j] = inputString[positionOfFirstChar+j];
116  }
117  tmpVar[numberOfChars] = '\0';
118  outputWords.push_back(tmpVar);
119 
120  // Continue loop
121  aWordIsBeingRead = false;
122  positionOfFirstChar = 0;
123  numberOfChars = 0;
124  }
125  }
126  else {
127  if (aWordIsBeingRead == false) {
128  aWordIsBeingRead = true;
129  positionOfFirstChar = i;
130  }
131  numberOfChars++;
132  }
133  } // for
134  if (aWordIsBeingRead == true) {
135  // We just finished reading the current string/word.
136  char tmpVar[numberOfChars+1];
137  for (std::string::size_type j = 0; j < numberOfChars; ++j) {
138  tmpVar[j] = inputString[positionOfFirstChar+j];
139  }
140  tmpVar[numberOfChars] = '\0';
141  outputWords.push_back(tmpVar);
142  }
143  std::vector<std::string>(outputWords).swap(outputWords);
144 
145  return;
146 }
147 
148 //void
149 //MiscExtractDoubleFromString(
150 // std::string& inputString,
151 // double& outputDouble)
152 //{
153 // return;
154 //}
155 
156 //void
157 //MiscExtractWordFromString(
158 // std::string& inputString,
159 // std::string& outputWord)
160 //{
161 // return;
162 //}
163 
164 int
166  std::ifstream& ifs,
167  std::string& termString,
168  double* termValue)
169 {
170  int iRC = UQ_OK_RC;
171 
172  ifs >> termString;
173  if ((ifs.rdstate() & std::ifstream::failbit)) {
175  }
176  else if (termValue) {
177  if (termString == std::string("inf")) {
178  *termValue = INFINITY;
179  }
180  else if (termString == std::string("-inf")) {
181  *termValue = -INFINITY;
182  }
183  else if (termString == std::string("nan")) {
184  *termValue = nan("");
185  }
186  else {
187  *termValue = strtod(termString.c_str(),NULL);
188  }
189  }
190  //if (!iRC) std::cout << "Read termString = " << termString << std::endl;
191 
192  return iRC;
193 }
194 
195 int
197  std::ifstream& ifs,
198  std::string& termString,
199  double* termValue,
200  bool& endOfLineAchieved)
201 {
202  int iRC = UQ_OK_RC;
203  endOfLineAchieved = false;
204 
205  char c = ' ';
206  while (c == ' ') {
207  ifs.get(c);
208  if ((ifs.rdstate() & std::ifstream::failbit)) {
210  break;
211  }
212  };
213 
214  char term[512];
215  unsigned int pos = 0;
216 
217  if (!iRC) {
218  while ((pos < 512) && (c != '\n') && (c != '\0') && (c != ' ')) {
219  term[pos++] = c;
220  if ((ifs.rdstate() & std::ifstream::failbit)) {
222  break;
223  }
224  ifs.get(c);
225  };
226  }
227 
228  if (!iRC) {
229  if (c == '\n') endOfLineAchieved = true;
230  term[pos] = '\0';
231  termString = term;
232  //std::cout << "Read chars = " << termString << std::endl;
233  if (termValue) {
234  if (termString == std::string("inf")) {
235  *termValue = INFINITY;
236  }
237  else if (termString == std::string("-inf")) {
238  *termValue = -INFINITY;
239  }
240  else if (termString == std::string("nan")) {
241  *termValue = nan("");
242  }
243  else {
244  *termValue = strtod(termString.c_str(),NULL);
245  }
246  }
247  }
248 
249  return iRC;
250 }
251 
252 double
254  double a,
255  double b,
256  const RngBase* rngObject)
257 {
258  double result = 0.;
259  if (a < 1.) {
260  result = MiscGammar(1.+a,b,rngObject)*std::pow( rngObject->uniformSample(),1./a );
261  }
262  else {
263  double d = a-1./3.;
264  double c = 1./std::sqrt(9.*d);
265  double x = 0.;
266  double w = 0.;
267  while (1) {
268  while (1) {
269  x = rngObject->gaussianSample(1.);
270  w = 1.+c*x;
271  if (w > 0.) break;
272  }
273  w = std::pow(w,3.);
274  double u = rngObject->uniformSample();
275  double compValue = 1.-0.0331*std::pow(x,4.);
276  if (u < compValue) break;
277  compValue = 0.5*std::pow(x,2.)+d*(1.-w+log(w));
278  if (log(u) < compValue) break;
279  }
280  result = b*d*w;
281  }
282 
283  return result;
284 }
285 
286 double
287 MiscGetEllapsedSeconds(struct timeval *timeval0)
288 {
289  double result = 0.;
290 
291  struct timeval timevalNow;
292  /*int iRC;*/
293  /*iRC = */gettimeofday(&timevalNow, NULL);
294 
295  result = (double) (timevalNow.tv_sec - timeval0->tv_sec );
296  result *= 1.e+6;
297  result += (double) (timevalNow.tv_usec - timeval0->tv_usec);
298  result *= 1.e-6;
299 
300  return result;
301 }
302 
303 double MiscHammingWindow(unsigned int N, unsigned int j)
304 {
305  double angle = 2.*M_PI*((double) j)/((double) N);
306  double result = 0.53836 - 0.46164*cos(angle);
307 
308  return result;
309 }
310 
311 double MiscGaussianDensity(double x, double mu, double sigma)
312 {
313  double sigma2 = sigma*sigma;
314  double diff = x-mu;
315 
316  return (1./std::sqrt(2*M_PI*sigma2))*std::exp(-.5*diff*diff/sigma2);
317 }
318 
319 unsigned int MiscUintDebugMessage(
320  unsigned int value,
321  const char* message)
322 {
323  if (message) {
324  std::cout << "Passing in MiscUintDebugMessage(), value = " << value << ", message = " << message << std::endl;
325  }
326  return value;
327 }
328 
330  int value,
331  const char* message)
332 {
333  if (message) {
334  std::cout << "Passing in MiscIntDebugMessage(), value = " << value << ", message = " << message << std::endl;
335  }
336  return value;
337 }
338 
340  double value,
341  const char* message)
342 {
343  if (message) {
344  std::cout << "Passing in MiscDoubleDebugMessage(), value = " << value << ", message = " << message << std::endl;
345  }
346  return value;
347 }
348 
362 
363 // ------------------------------------------
364 // Following routines borrowed from libGRVY
365 // ------------------------------------------
366 
367 int CheckFilePath(const char *pathname)
368  {
369 
370  // verify parent directories in path exist (and create if not).
371 
372 #ifdef HAVE_GRVY
373  return(grvy_check_file_path(pathname));
374 #else
375 
376  const int MAX_DEPTH = 50;
377 
378  char *pathlocal;
379  char *parents;
380  char *dirstring;
381  char *token;
382  int depth = 0;
383 
384  // Save a copy of pathname and look for the parent directories.
385 
386  pathlocal = strdup(pathname);
387  dirstring = strdup(pathname);
388  parents = dirname(pathlocal);
389 
390  if(strcmp(parents,".") == 0)
391  {
392  free(pathlocal);
393  free(dirstring);
394  return 0;
395  }
396 
397  // Deal with the possibility of an absolute path being provided
398 
399  bool abs_path = false;
400 
401  std::string leading_char("");
402  std::string path_to_check;
403 
404  if(strncmp(parents,"/",1) == 0)
405  {
406  leading_char = "/";
407  abs_path = true;
408  }
409 
410  // Verify existence of top-level directory
411 
412  if( (token = strtok(parents,"/")) != NULL )
413  {
414  path_to_check += leading_char + token;
415 
416  if ( GRVY_CheckDir(path_to_check.c_str()) )
417  {
418  free(pathlocal);
419  free(dirstring);
420  return -1;
421  }
422 
423  // Now, search for any remaining parent directories.
424 
425  if(abs_path)
426  sprintf(dirstring,"/%s",token);
427  else
428  sprintf(dirstring,"%s",token);
429 
430  while ( (token = strtok(0,"/")) && (depth < MAX_DEPTH) )
431  {
432  dirstring = strcat(dirstring,"/");
433 
434  if(GRVY_CheckDir(strcat(dirstring,token)))
435  {
436  free(pathlocal);
437  free(dirstring);
438  return -1;
439  }
440  depth++;
441  };
442 
443  if(depth >= MAX_DEPTH )
444  {
445  std::cerr << __func__ << ": error - Max directory depth exceeded, limit = " << MAX_DEPTH << std::endl;
446  free(pathlocal);
447  free(dirstring);
448  return -1;
449  }
450  }
451 
452  // Clean Up
453  free(pathlocal);
454  free(dirstring);
455 
456  return 0;
457 #endif
458  }
459 
460 
461 int GRVY_CheckDir(const char *dirname)
462 {
463  struct stat st;
464 
465  if(stat(dirname,&st) != 0)
466  {
467  if( mkdir(dirname,0700) != 0 )
468  {
469  std::cerr << __func__ << ": error - unable to create directory " << dirname << std::endl;
470  return -1;
471  }
472  }
473  else if (!S_ISDIR(st.st_mode))
474  {
475  std::cerr << __func__ << ": error - entry exists, but is not a directory " << dirname << std::endl;
476  return -1;
477  }
478 
479  return 0;
480 }
481 
482 template <class T>
483 bool
484 MiscCheckForSameValueInAllNodes(T& inputValue, // Yes, 'not' const
485  double acceptableTreshold,
486  const MpiComm& comm,
487  const char* whereString)
488 {
489  // Filter out those nodes that should not participate
490  if (comm.MyPID() < 0) return true;
491 
492  double localValue = (double) inputValue;
493  double sumValue = 0.;
494  comm.Allreduce((void *) &localValue, (void *) &sumValue, (int) 1, RawValue_MPI_DOUBLE, RawValue_MPI_SUM,
495  whereString,
496  "failed MPI on 'sumValue' inside MiscCheckForSameValueInAllNodes()");
497 
498  double totalNumNodes = (double) comm.NumProc();
499  double testValue = fabs(1. - localValue/(sumValue/totalNumNodes));
500  unsigned int boolSum = 0;
501 #if 1
502  unsigned int boolResult = 0;
503  if (testValue > acceptableTreshold) boolResult = 1;
504  comm.Allreduce((void *) &boolResult, (void *) &boolSum, (int) 1, RawValue_MPI_UNSIGNED, RawValue_MPI_SUM,
505  whereString,
506  "failed MPI on 'boolSum' inside MiscCheckForSameValueInAllNodes()");
507 
508  if (boolSum > 0) {
509  comm.Barrier();
510  for (int i = 0; i < comm.NumProc(); ++i) {
511  if (i == comm.MyPID()) {
512  std::cerr << "WARNING, "
513  << whereString
514  << ", inside MiscCheckForSameValueInAllNodes()"
515  << ", rank (in this communicator) = " << i
516  << ": boolSum = " << boolSum
517  << ", localValue = " << localValue
518  << ", sumValue = " << sumValue
519  << ", totalNumNodes = " << totalNumNodes
520  << ", avgValue = " << (sumValue/totalNumNodes)
521  << ", relativeTest = " << testValue
522  << std::endl;
523  }
524  comm.Barrier();
525  }
526  comm.Barrier();
527 
528  comm.Bcast((void *) &localValue, (int) 1, RawValue_MPI_DOUBLE, 0,
529  whereString,
530  "failed MPI on 'boolSum' inside MiscCheckForSameValueInAllNodes()");
531  inputValue = localValue; // IMPORTANT
532  }
533 #else
534  UQ_FATAL_TEST_MACRO(testValue > acceptableTreshold,
536  whereString,
537  "not all nodes have the same value inside MiscCheckForSameValueInAllNodes()");
538 #endif
539 
540  return (boolSum == 0);
541 }
542 
543 template <class V>
544 void
546  V maxValues,
547  std::vector<V*>& positions)
548 {
549  double factor = 0.5;
550  switch (positions.size()) {
551  case 0:
552  // Do nothing
553  break;
554 
555  case 1:
556  positions[0] = new V((1. - factor) * minValues + factor * maxValues);
557  break;
558 
559  default:
560  for (unsigned int i = 0; i < positions.size(); ++i) {
561  factor = ((double) i)/(((double) positions.size()) - 1.);
562  positions[i] = new V((1. - factor) * minValues + factor * maxValues);
563  }
564  break;
565  }
566 
567  return;
568 }
569 
570 template <class V1,class V2>
571 void
572 MiscCheckTheParallelEnvironment(const V1& vec1, const V2& vec2)
573 {
574  const BaseEnvironment& env = vec1.env();
575 
576  if (env.numSubEnvironments() == (unsigned int) env.fullComm().NumProc()) {
577  UQ_FATAL_TEST_MACRO(env.subRank() != 0,
578  env.worldRank(),
579  "MiscCheckTheParallelEnvironment<V1,V2>()",
580  "there should exist only one processor per sub environment");
581  UQ_FATAL_TEST_MACRO((vec1.numOfProcsForStorage() != 1) ||
582  (vec2.numOfProcsForStorage() != 1),
583  env.worldRank(),
584  "MiscCheckTheParallelEnvironment<V1,V2>()",
585  "only 1 processor (per sub environment) should be necessary for the storage of a parameter vector");
586  }
587  else if (env.numSubEnvironments() < (unsigned int) env.fullComm().NumProc()) {
589  env.worldRank(),
590  "MiscCheckTheParallelEnvironment<V1,V2>()",
591  "total number of processors should be a multiple of the number of sub environments");
592  unsigned int numProcsPerSubEnvironment = env.fullComm().NumProc()/env.numSubEnvironments();
593  UQ_FATAL_TEST_MACRO(env.subComm().NumProc() != (int) numProcsPerSubEnvironment,
594  env.worldRank(),
595  "MiscCheckTheParallelEnvironment<V1,V2>()",
596  "inconsistent number of processors per sub environment");
597  if ((vec1.numOfProcsForStorage() == 1) &&
598  (vec2.numOfProcsForStorage() == 1)) {
599  // Ok
600  }
601  else if ((vec1.numOfProcsForStorage() == numProcsPerSubEnvironment) &&
602  (vec2.numOfProcsForStorage() == numProcsPerSubEnvironment)) {
603  UQ_FATAL_TEST_MACRO(true,
604  env.worldRank(),
605  "MiscCheckTheParallelEnvironment<V1,V2>()",
606  "parallel vectors are not supported yet");
607  }
608  else {
609  UQ_FATAL_TEST_MACRO(true,
610  env.worldRank(),
611  "MiscCheckTheParallelEnvironment<V1,V2>()",
612  "number of processors required for a vector storage should be equal to either 1 or to the number of processors in the sub environment");
613  }
614  }
615  else {
616  UQ_FATAL_TEST_MACRO(true,
617  env.worldRank(),
618  "MiscCheckTheParallelEnvironment<V1,V2>()",
619  "number of processors per sub environment is less than 1!");
620  }
621 
622  return;
623 }
624 
625 } // End namespace QUESO
626 
627 template void QUESO::MiscCheckTheParallelEnvironment<QUESO::GslVector, QUESO::GslVector>(QUESO::GslVector const&, QUESO::GslVector const&);
628 template bool QUESO::MiscCheckForSameValueInAllNodes<bool>(bool&, double, QUESO::MpiComm const&, char const*);
629 template bool QUESO::MiscCheckForSameValueInAllNodes<double>(double&, double, QUESO::MpiComm const&, char const*);
void Bcast(void *buffer, int count, RawType_MPI_Datatype datatype, int root, const char *whereMsg, const char *whatMsg) const
Broadcast values from the root process to the slave processes.
Definition: MpiComm.C:157
The QUESO MPI Communicator Class.
Definition: MpiComm.h:75
double MiscDoubleDebugMessage(double value, const char *message)
int subRank() const
Access function for sub-rank.
Definition: Environment.C:263
unsigned int MiscUintDebugMessage(unsigned int value, const char *message)
int MiscReadStringAndDoubleFromFile(std::ifstream &ifs, std::string &termString, double *termValue)
int worldRank() const
Returns the process world rank.
Definition: Environment.C:235
#define RawValue_MPI_DOUBLE
Definition: MpiComm.h:48
const MpiComm & subComm() const
Access function for MpiComm sub communicator.
Definition: Environment.C:269
int NumProc() const
Returns total number of processes.
Definition: MpiComm.C:121
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:131
const MpiComm & fullComm() const
Access function for MpiComm full communicator.
Definition: Environment.C:247
int GRVY_CheckDir(const char *dirname)
int MiscReadCharsAndDoubleFromFile(std::ifstream &ifs, std::string &termString, double *termValue, bool &endOfLineAchieved)
const int UQ_UNAVAILABLE_RANK
Definition: Defines.h:74
#define RawValue_MPI_UNSIGNED
Definition: MpiComm.h:49
This (virtual) class sets up the environment underlying the use of the QUESO library by an executable...
Definition: Environment.h:187
Class for vector operations using GSL library.
Definition: GslVector.h:48
void MiscReadWordsFromString(const std::string &inputString, std::vector< std::string > &outputWords)
Definition: Miscellaneous.C:94
#define RawValue_MPI_SUM
Definition: MpiComm.h:52
void MiscReadDoublesFromString(const std::string &inputString, std::vector< double > &outputDoubles)
Definition: Miscellaneous.C:39
void Barrier() const
Pause every process in *this communicator until all the processes reach this point.
Definition: MpiComm.C:143
bool MiscCheckForSameValueInAllNodes(T &inputValue, double acceptableTreshold, const MpiComm &comm, const char *whereString)
const int UQ_FAILED_READING_FILE_RC
Definition: Defines.h:85
virtual double uniformSample() const =0
Samples a value from a uniform distribution.
double MiscGaussianDensity(double x, double mu, double sigma)
double MiscGammar(double a, double b, const RngBase *rngObject)
unsigned int numSubEnvironments() const
Access function to the number of sub-environments.
Definition: Environment.C:319
int MyPID() const
Return my process ID.
Definition: MpiComm.C:112
int CheckFilePath(const char *path)
Class for random number generation (base class for either GSL or Boost RNG).
Definition: RngBase.h:45
virtual double gaussianSample(double stdDev) const =0
Samples a value from a Gaussian distribution with standard deviation given by stdDev.
const int UQ_OK_RC
Definition: Defines.h:76
#define UQ_FATAL_TEST_MACRO(test, givenRank, where, what)
Definition: Defines.h:223
int MiscIntDebugMessage(int value, const char *message)
double MiscGetEllapsedSeconds(struct timeval *timeval0)
double MiscHammingWindow(unsigned int N, unsigned int j)
void MiscCheckTheParallelEnvironment(const V1 &vec1, const V2 &vec2)
void MiscComputePositionsBetweenMinMax(V minValues, V maxValues, std::vector< V * > &positions)

Generated on Thu Apr 23 2015 19:26:15 for queso-0.51.1 by  doxygen 1.8.5