queso-0.55.0
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 double
126  const V& domainVector,
127  const V* domainDirection,
128  V* gradVector,
129  M* hessianMatrix,
130  V* hessianEffect) const
131 {
132  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
133  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::actualValue()"
134  << ", meanVector = " << *m_lawExpVector
135  << ", lawCovMatrix = " << *m_lawCovMatrix
136  << ": domainVector = " << domainVector
137  << std::endl;
138  }
139 
140  queso_require_equal_to_msg(domainVector.sizeLocal(), this->m_domainSet.vectorSpace().dimLocal(), "invalid input");
141 
142  queso_require_msg(!(hessianMatrix || hessianEffect), "incomplete code for gradVector, hessianMatrix and hessianEffect calculations");
143 
144  double returnValue = 0.;
145 
146  if (this->m_domainSet.contains(domainVector) == false) {
147  // What should the gradient be here?
148  returnValue = 0.;
149  }
150  else {
151  // Already normalised (so the gradient will have the normalisation constant
152  // in it)
153  returnValue = std::exp(this->lnValue(domainVector,domainDirection,gradVector,hessianMatrix,hessianEffect));
154 
155  if (gradVector) {
156  (*gradVector) *= returnValue;
157  }
158  }
159 
160  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
161  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::actualValue()"
162  << ", meanVector = " << *m_lawExpVector
163  << ", lawCovMatrix = " << *m_lawCovMatrix
164  << ": domainVector = " << domainVector
165  << ", returnValue = " << returnValue
166  << std::endl;
167  }
168 
169  return returnValue;
170 }
171 //--------------------------------------------------
172 template<class V, class M>
173 double
175  const V& domainVector,
176  const V* domainDirection,
177  V* gradVector,
178  M* hessianMatrix,
179  V* hessianEffect) const
180 {
181  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 55)) {
182  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::lnValue()"
183  << ", meanVector = " << *m_lawExpVector
184  << ", lawCovMatrix = " << *m_lawCovMatrix
185  << ": domainVector = " << domainVector
186  << std::endl;
187  }
188 
189  queso_require_msg(!(domainDirection || hessianMatrix || hessianEffect), "incomplete code for gradVector, hessianMatrix and hessianEffect calculations");
190 
191  double returnValue = 0.;
192 
193  double lnDeterminant = 0.;
194  if (this->m_domainSet.contains(domainVector) == false) {
195  // What should the gradient be here?
196  returnValue = -INFINITY;
197  }
198  else {
199  V diffVec(domainVector - this->lawExpVector());
200  if (m_diagonalCovMatrix) {
201  returnValue = ((diffVec*diffVec)/this->lawVarVector()).sumOfComponents();
202 
203  // Compute the gradient of log of the pdf.
204  // The log of a Gaussian pdf is:
205  // f(x) = - 1/2 (x - \mu)^T \Sigma^{-1} (x - \mu)
206  // Therefore
207  // \frac{df}{dx}(x) = - (x - \mu)^T \Sigma^{-1}
208  // = - (\Sigma^{-1}^T (x - \mu))^T
209  // = - (\Sigma^{-1} (x - \mu))^T
210  // = - \Sigma^{-1} (x - \mu) (row/column vector doesn't matter)
211  //
212  // So if \Sigma is diagonal we have a component-wise product of two
213  // vectors (x - \mu) and the diagonal elements of \Sigma^{-1}
214  if (gradVector) {
215  (*gradVector) = diffVec; // Copy
216  (*gradVector) /= this->lawVarVector();
217  (*gradVector) *= -1.0;
218  }
219 
220  if (m_normalizationStyle == 0) {
221  unsigned int iMax = this->lawVarVector().sizeLocal();
222  for (unsigned int i = 0; i < iMax; ++i) {
223  lnDeterminant += std::log(this->lawVarVector()[i]);
224  }
225  }
226  }
227  else {
228  V tmpVec = this->m_lawCovMatrix->invertMultiply(diffVec);
229  returnValue = (diffVec*tmpVec).sumOfComponents();
230 
231  // Compute the gradient of log of the pdf.
232  // The log of a Gaussian pdf is:
233  // f(x) = - 1/2 (x - \mu)^T \Sigma^{-1} (x - \mu)
234  // Therefore
235  // \frac{df}{dx}(x) = - (x - \mu)^T \Sigma^{-1}
236  // = - (\Sigma^{-1}^T (x - \mu))^T
237  // = - (\Sigma^{-1} (x - \mu))^T
238  // = - \Sigma^{-1} (x - \mu) (row/column vector doesn't matter)
239  if (gradVector) {
240  (*gradVector) = tmpVec;
241  (*gradVector) *= -1.0;
242  }
243 
244  if (m_normalizationStyle == 0) {
245  lnDeterminant = this->m_lawCovMatrix->lnDeterminant();
246  }
247  }
248  if (m_normalizationStyle == 0) {
249  returnValue += ((double) this->lawVarVector().sizeLocal()) * std::log(2*M_PI); // normalization of pdf
250  returnValue += lnDeterminant; // normalization of pdf
251  }
252  returnValue *= -0.5;
253  }
254  returnValue += m_logOfNormalizationFactor;
255 
256  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
257  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::lnValue()"
258  << ", m_normalizationStyle = " << m_normalizationStyle
259  << ", m_diagonalCovMatrix = " << m_diagonalCovMatrix
260  << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
261  << ", lnDeterminant = " << lnDeterminant
262  << ", meanVector = " << *m_lawExpVector
263  << ", lawCovMatrix = " << *m_lawCovMatrix
264  << ": domainVector = " << domainVector
265  << ", returnValue = " << returnValue
266  << std::endl;
267  }
268 
269  return returnValue;
270 }
271 //--------------------------------------------------
272 template<class V, class M>
273 double
274 GaussianJointPdf<V,M>::computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
275 {
276  double value = 0.;
277 
278  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
279  *m_env.subDisplayFile() << "Entering GaussianJointPdf<V,M>::computeLogOfNormalizationFactor()"
280  << std::endl;
281  }
282  value = BaseJointPdf<V,M>::commonComputeLogOfNormalizationFactor(numSamples, updateFactorInternally);
283  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
284  *m_env.subDisplayFile() << "Leaving GaussianJointPdf<V,M>::computeLogOfNormalizationFactor()"
285  << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
286  << std::endl;
287  }
288 
289  return value;
290 }
291 //--------------------------------------------------
292 template<class V, class M>
293 void
295 {
296  // delete old expected values (allocated at construction or last call to this function)
297  delete m_lawExpVector;
298  m_lawExpVector = new V(newLawExpVector);
299  return;
300 }
301 
302 template<class V, class M>
303 void
305 {
306  // delete old expected values (allocated at construction or last call to this function)
307  delete m_lawCovMatrix;
308  m_lawCovMatrix = new M(newLawCovMatrix);
309  return;
310 }
311 
312 template<class V, class M>
313 const M&
315 {
316  return *m_lawCovMatrix;
317 }
318 
319 } // End namespace QUESO
320 
unsigned int displayVerbosity() const
Definition: Environment.C:400
const V & lawVarVector() const
Access to the vector of variance values and private attribute: m_lawVarVector.
~GaussianJointPdf()
Destructor.
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
A templated (base) class for handling joint PDFs.
Definition: JointPdf.h:56
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:77
const M & lawCovMatrix() const
Returns the covariance matrix; access to protected attribute m_lawCovMatrix.
GaussianJointPdf(const char *prefix, const VectorSet< V, M > &domainSet, const V &lawExpVector, const V &lawVarVector)
Constructor.
#define queso_require_msg(asserted, msg)
Definition: asserts.h:69
#define queso_require_equal_to_msg(expr1, expr2, msg)
Definition: asserts.h:85
const V & lawExpVector() const
Access to the vector of mean values and private attribute: m_lawExpVector.
const BaseEnvironment & m_env
std::ofstream * subDisplayFile() const
Access function for m_subDisplayFile (displays file on stream).
Definition: Environment.C:278
double computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
Computes the logarithm of the normalization factor.
void updateLawCovMatrix(const M &newLawCovMatrix)
Updates the lower triangular matrix from Cholesky decomposition of the covariance matrix to the new v...
double actualValue(const V &domainVector, const V *domainDirection, V *gradVector, M *hessianMatrix, V *hessianEffect) const
Actual value of the Gaussian PDF:
A class for handling Gaussian joint PDFs.
void updateLawExpVector(const V &newLawExpVector)
Updates the mean with the new value newLawExpVector.

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