queso-0.56.1
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-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/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 
void updateLawExpVector(const V &newLawExpVector)
Updates the mean with the new value newLawExpVector.
std::ofstream * subDisplayFile() const
Access function for m_subDisplayFile (displays file on stream).
Definition: Environment.C:320
virtual void distributionMean(V &meanVector) const
Mean value 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).
const V & lawExpVector() const
Access to the vector of mean values and private attribute: m_lawExpVector.
#define queso_require_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:73
A templated (base) class for handling joint PDFs.
Definition: JointPdf.h:55
double computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
Computes the logarithm of the normalization factor.
#define queso_assert_equal_to(expr1, expr2)
Definition: asserts.h:135
virtual void print(std::ostream &os) const
Print method for informational and logging purposes.
A templated class for handling sets.
Definition: VectorSet.h:52
virtual void distributionVariance(M &covMatrix) const
Covariance matrix of the underlying random variable.
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
unsigned int displayVerbosity() const
Definition: Environment.C:449
A class for handling Gaussian joint PDFs.
#define queso_require_msg(asserted, msg)
Definition: asserts.h:69
const BaseEnvironment & m_env
~GaussianJointPdf()
Destructor.
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.
double actualValue(const V &domainVector, const V *domainDirection, V *gradVector, M *hessianMatrix, V *hessianEffect) const
Actual value of the Gaussian PDF:
void updateLawCovMatrix(const M &newLawCovMatrix)
Updates the lower triangular matrix from Cholesky decomposition of the covariance matrix to the new v...
const M & lawCovMatrix() const
Returns the covariance matrix; access to protected attribute m_lawCovMatrix.

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