queso-0.57.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
ScalarFunction.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/config_queso.h>
26 #include <queso/ScalarFunction.h>
27 #include <queso/VectorSet.h>
28 #include <queso/VectorSpace.h>
29 #include <queso/GslVector.h>
30 #include <queso/GslMatrix.h>
31 
32 #ifndef QUESO_DISABLE_BOOST_PROGRAM_OPTIONS
33 #include <queso/BoostInputOptionsParser.h>
34 #else
35 #include <queso/getpot.h>
36 #endif
37 
38 #include <cstdlib>
39 
40 #define QUESO_BASESCALARFN_FD_STEPSIZE_ODV "1e-6"
41 
42 namespace QUESO {
43 
44 // Default constructor
45 template<class V, class M>
47  const VectorSet<V, M> & domainSet)
48  : m_env(domainSet.env()),
49  m_prefix((std::string)(prefix) + "func_"),
50  m_domainSet(domainSet),
51 #ifndef QUESO_DISABLE_BOOST_PROGRAM_OPTIONS
52  m_parser(new BoostInputOptionsParser(m_env.optionsInputFileName())),
53 #endif
54  m_fdStepSize(1, std::atof(QUESO_BASESCALARFN_FD_STEPSIZE_ODV))
55 {
56  unsigned int dim = m_domainSet.vectorSpace().dimLocal();
57 
58  // Snarf fd step size from input file.
59 #ifndef QUESO_DISABLE_BOOST_PROGRAM_OPTIONS
60  m_parser->registerOption<std::string>(m_prefix + "fdStepSize",
61  QUESO_BASESCALARFN_FD_STEPSIZE_ODV,
62  "step size for finite difference");
63  m_parser->scanInputFile();
64  m_parser->getOption<std::vector<double> >(m_prefix + "fdStepSize",
65  m_fdStepSize);
66 
67  // Check size of finite difference vector the user provided.
68  queso_require_msg((m_fdStepSize.size() == 1) || (m_fdStepSize.size() == dim),
69  "Finite difference vector is not the correct size");
70 
71  // If the user provided a scalar for a multi-dimensional function...
72  if (dim > 1 && m_fdStepSize.size() == 1) {
73  // ...get the only element
74  double stepSize = m_fdStepSize[0];
75 
76  // and use it to fill a vector of length dim
77  m_fdStepSize.resize(dim, stepSize);
78  }
79 #else
80  unsigned int size = m_env.input().vector_variable_size(m_prefix + "fdStepSize");
81 
82  if (size == 0) {
83  m_fdStepSize.resize(dim, std::atof(QUESO_BASESCALARFN_FD_STEPSIZE_ODV));
84  }
85  else if (size == 1) {
86  double value = m_env.input()(m_prefix + "fdStepSize",
87  std::atof(QUESO_BASESCALARFN_FD_STEPSIZE_ODV),
88  0);
89 
90  m_fdStepSize.resize(dim, value);
91  }
92  else if (size == dim) {
93  for (unsigned int i = 0; i < size; i++) {
94  m_fdStepSize[i] = m_env.input()(m_prefix + "fdStepSize",
95  std::atof(QUESO_BASESCALARFN_FD_STEPSIZE_ODV),
96  i);
97  }
98  }
99  else {
100  // Either the user provides nothing, a scalar, or the whole vector.
101  // Any other possiblities are not allowed so we error in this case.
102  queso_error_msg("Finite difference vector must be a scalar or a vector of length parameter dimension");
103  }
104 #endif
105 
106  // Check all the elements of the finite difference vector are positive
107  for (unsigned int i = 0; i < dim; i++) {
108  queso_require_greater_msg(m_fdStepSize[i],
109  0.0,
110  "Finite difference step sizes must be positive");
111  }
112 }
113 
114 // Destructor
115 template<class V, class M>
117 {
118 }
119 
120 // Math methods
121 template<class V, class M>
123 {
124  return m_domainSet;
125 }
126 
127 template <class V, class M>
128 double
129 BaseScalarFunction<V, M>::lnValue(const V & domainVector,
130  const V * domainDirection,
131  V * gradVector,
132  M * hessianMatrix,
133  V * hessianEffect) const
134 {
135  std::string msg;
136 
137  msg += "Implementation of all lnValue methods is missing. Please implement";
138  msg += " at least lnValue(const V &).";
139 
140  queso_error_msg(msg);
141 }
142 
143 template <class V, class M>
144 double
145 BaseScalarFunction<V, M>::lnValue(const V & domainVector) const
146 {
147  return this->lnValue(domainVector, NULL, NULL, NULL, NULL);
148 }
149 
150 template <class V, class M>
151 double
152 BaseScalarFunction<V, M>::lnValue(const V & domainVector, V & gradVector) const
153 {
154  double value = this->lnValue(domainVector);
155 
156  // Create perturbed version of domainVector to use in finite difference
157  V perturbedVector(domainVector);
158 
159  // Fill up gradVector with a finite difference approximation
160  for (unsigned int i = 0; i < domainVector.sizeLocal(); ++i) {
161  // Store the old value of the perturbed element so we can undo it later
162  double tmp = perturbedVector[i];
163 
164  perturbedVector[i] += m_fdStepSize[i];
165  gradVector[i] = (this->lnValue(perturbedVector) - value) / m_fdStepSize[i];
166 
167  // Restore the old value of the perturbedVector element
168  perturbedVector[i] = tmp;
169  }
170 
171  return value;
172 }
173 
174 template <class V, class M>
175 double
176 BaseScalarFunction<V, M>::lnValue(const V & domainVector,
177  V & gradVector,
178  const V & domainDirection,
179  V & hessianEffect) const
180 {
181  std::string msg;
182 
183  msg += "QUESO asked for Hessian information from an lnValue method, but the";
184  msg += " implementation of is missing. Please implement";
185  msg += " lnValue(const V &, V &, const V &, V &).";
186 
187  queso_error_msg(msg);
188 }
189 
190 template <class V, class M>
191 void
193 {
194  queso_require_greater_msg(fdStepSize, 0.0,
195  "Must provide a finite difference step > 0");
196 
197  for (unsigned int i = 0; i < this->m_fdStepSize.size(); i++) {
198  this->m_fdStepSize[i] = fdStepSize;
199  }
200 }
201 
202 template <class V, class M>
203 void
205  double fdStepSize)
206 {
207  queso_require_greater_msg(fdStepSize, 0.0,
208  "Must provide a finite difference step > 0");
209 
210  queso_require_greater_equal_msg(i, 0, "Must provide a nonnegative index");
211 
212  unsigned int size = this->m_fdStepSize.size();
213  queso_require_less_msg(i, size, "Must provide an index less than size of parameter dimension");
214 
215  this->m_fdStepSize[i] = fdStepSize;
216 }
217 
218 } // End namespace QUESO
219 
BaseScalarFunction(const char *prefix, const VectorSet< V, M > &domainSet)
Default constructor.
const GetPot & input() const
The GetPot input file parser.
Definition: Environment.C:1149
virtual ~BaseScalarFunction()
Destructor.
void setFiniteDifferenceStepSize(double fdStepSize)
Sets the step size for finite differencing gradients.
A templated class for handling sets.
Definition: VectorSet.h:52
ScopedPtr< BoostInputOptionsParser >::Type m_parser
Input parser.
const VectorSet< V, M > & domainSet() const
Access to the protected attribute m_domainSet: domain set of the scalar function. ...
const BaseEnvironment & m_env
virtual double lnValue(const V &domainVector, const V *domainDirection, V *gradVector, M *hessianMatrix, V *hessianEffect) const
Logarithm of the value of the scalar function. Deprecated.
std::vector< double > m_fdStepSize
Finite different step size.
int dim
Definition: ann_test.cpp:472
const VectorSet< V, M > & m_domainSet
Domain set of the scalar function.

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