queso-0.57.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
GaussianJointPdf.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-2017 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/GaussianJointPdf.h>
26 #include <queso/GslVector.h>
27 #include <queso/GslMatrix.h>
28 
29 namespace QUESO {
30 
31 // Constructor -------------------------------------
32 template<class V,class M>
34  const char* prefix,
35  const VectorSet<V,M>& domainSet,
36  const V& lawExpVector,
37  const V& lawVarVector)
38  :
39  BaseJointPdf<V,M>(((std::string)(prefix)+"gau").c_str(),domainSet),
40  m_lawExpVector (new V(lawExpVector)),
41  m_lawVarVector (new V(lawVarVector)),
42  m_diagonalCovMatrix(true),
43  m_lawCovMatrix (m_domainSet.vectorSpace().newDiagMatrix(lawVarVector))
44 {
45 
46  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
47  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::constructor() [1]"
48  << ": prefix = " << m_prefix
49  << std::endl;
50  }
51 
52  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
53  *m_env.subDisplayFile() << "In GaussianJointPdf<V,M>::constructor()"
54  //<< ", prefix = " << m_prefix
55  << ": meanVector = " << this->lawExpVector()
56  << ", Variances = " << this->lawVarVector()
57  << std::endl;
58  }
59 
60  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
61  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::constructor() [1]"
62  << ": prefix = " << m_prefix
63  << std::endl;
64  }
65 }
66 // Constructor -------------------------------------
67 template<class V,class M>
69  const char* prefix,
70  const VectorSet<V,M>& domainSet,
71  const V& lawExpVector,
72  const M& lawCovMatrix)
73  :
74  BaseJointPdf<V,M>(((std::string)(prefix)+"gau").c_str(),domainSet),
75  m_lawExpVector (new V(lawExpVector)),
76  m_lawVarVector (domainSet.vectorSpace().newVector(INFINITY)), // FIX ME
77  m_diagonalCovMatrix(false),
78  m_lawCovMatrix (new M(lawCovMatrix))
79 {
80  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
81  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::constructor() [2]"
82  << ": prefix = " << m_prefix
83  << std::endl;
84  }
85 
86  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
87  *m_env.subDisplayFile() << "In GaussianJointPdf<V,M>::constructor()"
88  //<< ", prefix = " << m_prefix
89  << ": meanVector = " << this->lawExpVector()
90  << ", Covariance Matrix = " << lawCovMatrix
91  << std::endl;
92  }
93 
94  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
95  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::constructor() [2]"
96  << ": prefix = " << m_prefix
97  << std::endl;
98  }
99 }
100 // Destructor --------------------------------------
101 template<class V,class M>
103 {
104  delete m_lawCovMatrix;
105  delete m_lawVarVector;
106  delete m_lawExpVector;
107 }
108 // Math methods-------------------------------------
109 template <class V, class M>
110 const V&
112 {
113  return *m_lawExpVector;
114 }
115 //--------------------------------------------------
116 template <class V, class M>
117 const V&
119 {
120  return *m_lawVarVector;
121 }
122 
123 template <class V, class M>
124 void
125 GaussianJointPdf<V, M>::print(std::ostream & os) const
126 {
127  // Print m_env?
128 
129  os << "Start printing GaussianJointPdf<V, M>" << std::endl;
130  os << "m_prefix:" << std::endl;
131  os << this->m_prefix << std::endl;
132  os << "m_domainSet:" << std::endl;
133  os << this->m_domainSet << std::endl;
134  os << "m_normalizationStyle:" << std::endl;
135  os << this->m_normalizationStyle << std::endl;
136  os << "m_logOfNormalizationFactor:" << std::endl;
137  os << this->m_logOfNormalizationFactor << std::endl;
138  os << "Mean:" << std::endl;
139  os << this->lawExpVector() << std::endl;
140  os << "Variance vector:" << std::endl;
141  os << this->lawVarVector() << std::endl;
142  os << "Covariance matrix:" << std::endl;
143  os << this->lawCovMatrix() << std::endl;
144  os << "Diagonal covariance?" << std::endl;
145  os << this->m_diagonalCovMatrix << std::endl;
146  os << "End printing GaussianJointPdf<V, M>" << std::endl;
147 }
148 
149 //--------------------------------------------------
150 template<class V, class M>
151 double
153  const V& domainVector,
154  const V* domainDirection,
155  V* gradVector,
156  M* hessianMatrix,
157  V* hessianEffect) const
158 {
159  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
160  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::actualValue()"
161  << ", meanVector = " << *m_lawExpVector
162  << ", lawCovMatrix = " << *m_lawCovMatrix
163  << ": domainVector = " << domainVector
164  << std::endl;
165  }
166 
167  queso_require_equal_to_msg(domainVector.sizeLocal(), this->m_domainSet.vectorSpace().dimLocal(), "invalid input");
168 
169  queso_require_msg(!(hessianMatrix || hessianEffect), "incomplete code for gradVector, hessianMatrix and hessianEffect calculations");
170 
171  double returnValue = 0.;
172 
173  if (this->m_domainSet.contains(domainVector) == false) {
174  // What should the gradient be here?
175  returnValue = 0.;
176  }
177  else {
178  // Already normalised (so the gradient will have the normalisation constant
179  // in it)
180  returnValue = std::exp(this->lnValue(domainVector,domainDirection,gradVector,hessianMatrix,hessianEffect));
181 
182  if (gradVector) {
183  (*gradVector) *= returnValue;
184  }
185  }
186 
187  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
188  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::actualValue()"
189  << ", meanVector = " << *m_lawExpVector
190  << ", lawCovMatrix = " << *m_lawCovMatrix
191  << ": domainVector = " << domainVector
192  << ", returnValue = " << returnValue
193  << std::endl;
194  }
195 
196  return returnValue;
197 }
198 //--------------------------------------------------
199 template<class V, class M>
200 double
202  const V& domainVector,
203  const V* domainDirection,
204  V* gradVector,
205  M* hessianMatrix,
206  V* hessianEffect) const
207 {
208  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
209  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::lnValue()"
210  << ", meanVector = " << *m_lawExpVector
211  << ", lawCovMatrix = " << *m_lawCovMatrix
212  << ": domainVector = " << domainVector
213  << std::endl;
214  }
215 
216  queso_require_msg(!(domainDirection || hessianMatrix || hessianEffect), "incomplete code for gradVector, hessianMatrix and hessianEffect calculations");
217 
218  double returnValue = 0.;
219 
220  double lnDeterminant = 0.;
221  if (this->m_domainSet.contains(domainVector) == false) {
222  // What should the gradient be here?
223  returnValue = -INFINITY;
224  }
225  else {
226  V diffVec(domainVector - this->lawExpVector());
227  if (m_diagonalCovMatrix) {
228  returnValue = ((diffVec*diffVec)/this->lawVarVector()).sumOfComponents();
229 
230  // Compute the gradient of log of the pdf.
231  // The log of a Gaussian pdf is:
232  // f(x) = - 1/2 (x - \mu)^T \Sigma^{-1} (x - \mu)
233  // Therefore
234  // \frac{df}{dx}(x) = - (x - \mu)^T \Sigma^{-1}
235  // = - (\Sigma^{-1}^T (x - \mu))^T
236  // = - (\Sigma^{-1} (x - \mu))^T
237  // = - \Sigma^{-1} (x - \mu) (row/column vector doesn't matter)
238  //
239  // So if \Sigma is diagonal we have a component-wise product of two
240  // vectors (x - \mu) and the diagonal elements of \Sigma^{-1}
241  if (gradVector) {
242  (*gradVector) = diffVec; // Copy
243  (*gradVector) /= this->lawVarVector();
244  (*gradVector) *= -1.0;
245  }
246 
247  if (m_normalizationStyle == 0) {
248  unsigned int iMax = this->lawVarVector().sizeLocal();
249  for (unsigned int i = 0; i < iMax; ++i) {
250  lnDeterminant += std::log(this->lawVarVector()[i]);
251  }
252  }
253  }
254  else {
255  V tmpVec = this->m_lawCovMatrix->invertMultiply(diffVec);
256  returnValue = (diffVec*tmpVec).sumOfComponents();
257 
258  // Compute the gradient of log of the pdf.
259  // The log of a Gaussian pdf is:
260  // f(x) = - 1/2 (x - \mu)^T \Sigma^{-1} (x - \mu)
261  // Therefore
262  // \frac{df}{dx}(x) = - (x - \mu)^T \Sigma^{-1}
263  // = - (\Sigma^{-1}^T (x - \mu))^T
264  // = - (\Sigma^{-1} (x - \mu))^T
265  // = - \Sigma^{-1} (x - \mu) (row/column vector doesn't matter)
266  if (gradVector) {
267  (*gradVector) = tmpVec;
268  (*gradVector) *= -1.0;
269  }
270 
271  if (m_normalizationStyle == 0) {
272  lnDeterminant = this->m_lawCovMatrix->lnDeterminant();
273  }
274  }
275  if (m_normalizationStyle == 0) {
276  returnValue += ((double) this->lawVarVector().sizeLocal()) * std::log(2*M_PI); // normalization of pdf
277  returnValue += lnDeterminant; // normalization of pdf
278  }
279  returnValue *= -0.5;
280  }
281  returnValue += m_logOfNormalizationFactor;
282 
283  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
284  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::lnValue()"
285  << ", m_normalizationStyle = " << m_normalizationStyle
286  << ", m_diagonalCovMatrix = " << m_diagonalCovMatrix
287  << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
288  << ", lnDeterminant = " << lnDeterminant
289  << ", meanVector = " << *m_lawExpVector
290  << ", lawCovMatrix = " << *m_lawCovMatrix
291  << ": domainVector = " << domainVector
292  << ", returnValue = " << returnValue
293  << std::endl;
294  }
295 
296  return returnValue;
297 }
298 //--------------------------------------------------
299 template<class V, class M>
300 void
302 {
303  meanVector = this->lawExpVector();
304 }
305 //--------------------------------------------------
306 template<class V, class M>
307 void
309 {
310  queso_assert_equal_to (covMatrix.numCols(), covMatrix.numRowsGlobal());
311 
312  if (m_diagonalCovMatrix) {
313  covMatrix.zeroLower();
314  covMatrix.zeroUpper();
315 
316  unsigned int n_comp = this->lawVarVector().sizeLocal();
317  queso_assert_equal_to (n_comp, covMatrix.numCols());
318 
319  for (unsigned int i = 0; i < n_comp; ++i) {
320  covMatrix(i,i) = this->lawVarVector()[i];
321  }
322  } else {
323  covMatrix = *this->m_lawCovMatrix;
324  }
325 }
326 //--------------------------------------------------
327 template<class V, class M>
328 double
329 GaussianJointPdf<V,M>::computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
330 {
331  double value = 0.;
332 
333  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
334  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::computeLogOfNormalizationFactor()"
335  << std::endl;
336  }
337  value = BaseJointPdf<V,M>::commonComputeLogOfNormalizationFactor(numSamples, updateFactorInternally);
338  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
339  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::computeLogOfNormalizationFactor()"
340  << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
341  << std::endl;
342  }
343 
344  return value;
345 }
346 //--------------------------------------------------
347 template<class V, class M>
348 void
350 {
351  // delete old expected values (allocated at construction or last call to this function)
352  delete m_lawExpVector;
353  m_lawExpVector = new V(newLawExpVector);
354  return;
355 }
356 
357 template<class V, class M>
358 void
360 {
361  // delete old expected values (allocated at construction or last call to this function)
362  delete m_lawCovMatrix;
363  m_lawCovMatrix = new M(newLawCovMatrix);
364  return;
365 }
366 
367 template<class V, class M>
368 const M&
370 {
371  return *m_lawCovMatrix;
372 }
373 
374 } // End namespace QUESO
375 
virtual void print(std::ostream &os) const
Print method for informational and logging purposes.
const V & lawExpVector() const
Access to the vector of mean values and private attribute: m_lawExpVector.
A class for handling Gaussian joint PDFs.
double computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
Computes the logarithm of the normalization factor.
virtual void distributionMean(V &meanVector) const
Mean value of the underlying random variable.
virtual void distributionVariance(M &covMatrix) const
Covariance matrix of the underlying random variable.
double lnValue(const V &domainVector, const V *domainDirection, V *gradVector, M *hessianMatrix, V *hessianEffect) const
Logarithm of the value of the Gaussian PDF (scalar function).
A templated class for handling sets.
Definition: VectorSet.h:52
~GaussianJointPdf()
Destructor.
void updateLawCovMatrix(const M &newLawCovMatrix)
Updates the lower triangular matrix from Cholesky decomposition of the covariance matrix to the new v...
double commonComputeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
Common method (to the derived classes) to compute the logarithm of the normalization factor...
Definition: JointPdf.C:115
const BaseEnvironment & m_env
double actualValue(const V &domainVector, const V *domainDirection, V *gradVector, M *hessianMatrix, V *hessianEffect) const
Actual value of the Gaussian PDF:
A templated (base) class for handling joint PDFs.
Definition: JointPdf.h:55
GaussianJointPdf(const char *prefix, const VectorSet< V, M > &domainSet, const V &lawExpVector, const V &lawVarVector)
Constructor.
const V & lawVarVector() const
Access to the vector of variance values and private attribute: m_lawVarVector.
const M & lawCovMatrix() const
Returns the covariance matrix; access to protected attribute m_lawCovMatrix.
MonteCarloSGOptions::MonteCarloSGOptions(const BaseEnvironment &env, const char *prefix, const McOptionsValues &alternativeOptionsValues queso_require_equal_to_msg)(m_env.optionsInputFileName(), std::string(""), std::string("this constructor is incompatible with the existence of an options input file"))
void updateLawExpVector(const V &newLawExpVector)
Updates the mean with the new value newLawExpVector.
unsigned int displayVerbosity() const
Definition: Environment.C:450
std::ofstream * subDisplayFile() const
Access function for m_subDisplayFile (displays file on stream).
Definition: Environment.C:320

Generated on Tue Jun 5 2018 19:48:55 for queso-0.57.1 by  doxygen 1.8.5