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

Generated on Sat Apr 22 2017 14:04:35 for queso-0.57.0 by  doxygen 1.8.5