/[escript]/trunk/downunder/py_src/costfunctions.py
ViewVC logotype

Contents of /trunk/downunder/py_src/costfunctions.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4076 - (show annotations)
Thu Nov 15 03:45:24 2012 UTC (8 years ago) by gross
File MIME type: text/x-python
File size: 9756 byte(s)
    def getDirectionalDerivative(self, m, d, grad_m):
        
1
2 ##############################################################################
3 #
4 # Copyright (c) 2003-2012 by University of Queensland
5 # http://www.uq.edu.au
6 #
7 # Primary Business: Queensland, Australia
8 # Licensed under the Open Software License version 3.0
9 # http://www.opensource.org/licenses/osl-3.0.php
10 #
11 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 # Development since 2012 by School of Earth Sciences
13 #
14 ##############################################################################
15
16 """General cost functions for minimization"""
17
18 __copyright__="""Copyright (c) 2003-2012 by University of Queensland
19 http://www.uq.edu.au
20 Primary Business: Queensland, Australia"""
21 __license__="""Licensed under the Open Software License version 3.0
22 http://www.opensource.org/licenses/osl-3.0.php"""
23 __url__="https://launchpad.net/escript-finley"
24
25 __all__ = ['CostFunction', 'MeteredCostFunction' ]
26
27
28 class CostFunction(object):
29 """
30 A function *f(x)* that can be minimized (base class).
31
32 Example of usage::
33
34 cf=DerivedCostFunction()
35 # ... calculate x ...
36 args=cf.getArguments(x) # this could be potentially expensive!
37 f=cf.getValue(x, *args)
38 # ... it could be required to update x without using the gradient...
39 # ... but then ...
40 gf=cf.getGradient(x, *args)
41
42
43 The class makes a difference for the representation of the solution x (x-type) and
44 the gradients (r-type).
45 """
46
47 def __init__(self):
48 """
49 the base constructor initializes the counters so subclasses should
50 ensure the super class constructor is called.
51 """
52 self.provides_inverse_Hessian_approximation=True
53
54 def getDualProduct(self, x, r):
55 """
56 returns the dual product of ``x`` and ``r``
57
58 :type x: x-type
59 :type r: r-type
60 :rtype: ```float```
61 """
62 raise NotImplementedError
63
64 def getValue(self, x, *args):
65 """
66 returns the value *f(x)* using the precalculated values for *x*.
67
68 :param x: a solution approximation
69 :type x: x-type
70 :rtype: ```float```
71 """
72 raise NotImplementedError
73
74 def __call__(self, x, *args):
75 """
76 short for ``getValue(x, *args)``.
77 """
78 return self.getValue(x, *args)
79
80 def getGradient(self, x, *args):
81 """
82 returns the gradient of *f* at *x* using the precalculated values for
83 *x*.
84
85 :param x: location of derivative
86 :type x: x-type
87 :param args: pre-calculated values for ``x`` from ``getArguments()``
88 :rtype r: r-type
89 """
90 raise NotImplementedError
91
92 def getArguments(self, x):
93 """
94 returns precalculated values that are shared in the calculation of
95 *f(x)* and *grad f(x)* and the Hessian operator
96
97 :param x: location of derivative
98 :type x: x-type
99 """
100 return ()
101
102 def getInverseHessianApproximation(self, x, r, *args):
103 """
104 returns an approximative evaluation *p* of the inverse of the Hessian operator of the costfunction
105 for a given gradient type *r* at a given location *x*: *H(x) p = r*
106
107 :param x: location of Hessian operator to be evaluated.
108 :type x: x-type
109 :param r: a given gradient
110 :type r: r-type
111 :param args: pre-calculated values for ``x`` from ``getArguments()``
112 :rtype x: x-type
113 :note: In general it is assumed that the Hessian *H(x)* needs to be calculate in each call for a new
114 location *x*. However, the solver may suggest that this is not required, typically when the iteration
115 is close to completeness.
116 :note: class attribute provides_inverse_Hessian_approximation need to be set to True to encourage
117 the solver to call this method.
118
119 """
120 raise NotImplementedError
121
122 def updateHessian(self):
123 """
124 notifies the class that the Hessian operator needs to be updated. This method is
125 called by the solver method.
126 """
127 pass
128
129 class MeteredCostFunction(CostFunction):
130 """
131 This an intrumented version of the ``CostFunction`` class. The function calls update statistical information.
132 The actual work is done by the methods with corresponding name and a leading underscore. These functions
133 need to be overwritten for a particular cost function implementation.
134 """
135
136 def __init__(self):
137 """
138 the base constructor initializes the counters so subclasses should
139 ensure the super class constructor is called.
140 """
141 super(MeteredCostFunction, self).__init__()
142 self.resetCounters()
143
144 def resetCounters(self):
145 """
146 resets all statistical counters
147 """
148 self.DualProduct_calls=0
149 self.Value_calls=0
150 self.Gradient_calls=0
151 self.Arguments_calls=0
152 self.InverseHessianApproximation_calls=0
153
154 def getDualProduct(self, x, r):
155 """
156 returns the dual product of ``x`` and ``r``
157
158 :type x: x-type
159 :type r: r-type
160 :rtype: ```float```
161 """
162 self.DualProduct_calls+=1
163 return self._getDualProduct(x, r)
164
165 def _getDualProduct(self, x, r):
166 """
167 returns the dual product of ``x`` and ``r``
168
169 :type x: x-type
170 :type r: r-type
171 :rtype: ```float```
172 :note: This is the worker for `getDualProduct()`, needs to be overwritten.
173 """
174 raise NotImplementedError
175
176 def getValue(self, x, *args):
177 """
178 returns the value *f(x)* using the precalculated values for *x*.
179
180 :param x: a solution approximation
181 :type x: x-type
182 :rtype: ```float```
183 """
184 self.Value_calls+=1
185 return self._getValue(x, *args)
186
187 def _getValue(self, x, *args):
188 """
189 returns the value *f(x)* using the precalculated values for *x*.
190
191 :param x: a solution approximation
192 :type x: x-type
193 :rtype: ```float```
194 :note: This is the worker for ``getValue()`, needs to be overwritten.
195 """
196 raise NotImplementedError
197
198 def getGradient(self, x, *args):
199 """
200 returns the gradient of *f* at *x* using the precalculated values for
201 *x*.
202
203 :param x: location of derivative
204 :type x: x-type
205 :param args: pre-calculated values for ``x`` from ``getArguments()``
206 :rtype r: r-type
207 """
208 self.Gradient_calls+=1
209 return self._getGradient(x, *args)
210 def _getGradient(self, x, *args):
211 """
212 returns the gradient of *f* at *x* using the precalculated values for
213 *x*.
214
215 :param x: location of derivative
216 :type x: x-type
217 :param args: pre-calculated values for ``x`` from ``getArguments()``
218 :rtype r: r-type
219 :note: This is the worker for `getGradient()`, needs to be overwritten.
220 """
221 raise NotImplementedError
222
223
224
225 def getArguments(self, x):
226 """
227 returns precalculated values that are shared in the calculation of
228 *f(x)* and *grad f(x)* and the Hessian operator
229
230 :param x: location of derivative
231 :type x: x-type
232 """
233 self.Arguments_calls+=1
234 return self._getArguments(x)
235
236 def _getArguments(self, x):
237 """
238 returns precalculated values that are shared in the calculation of
239 *f(x)* and *grad f(x)* and the Hessian operator
240
241 :param x: location of derivative
242 :type x: x-type
243 :note: Overwrite this function to implement a specific cost function
244 """
245 return ()
246
247 def getInverseHessianApproximation(self, x, r,*args):
248 """
249 returns an approximative evaluation *p* of the inverse of the Hessian operator of the costfunction
250 for a given gradient type *r* at a given location *x*: *H(x) p = r*
251
252 :param x: location of Hessian operator to be evaluated.
253 :type x: x-type
254 :param r: a given gradient
255 :type r: r-type
256 :param args: pre-calculated values for ``x`` from ``getArguments()``
257 :rtype x: x-type
258 :note: In general it is assumed that the Hessian *H(x)* needs to be calculate in each call for a new
259 location *x*. However, the solver may suggest that this is not required, typically when the iteration
260 ius close to completness.
261 """
262 self.InverseHessianApproximation_calls+=1
263 return self._getInverseHessianApproximation(x, r, *args)
264
265 def _getInverseHessianApproximation(self, x, r, *args):
266 """
267 returns an approximative evaluation *p* of the inverse of the Hessian operator of the costfunction
268 for a given gradient type *r* at a given location *x*: *H(x) p = r*
269
270 :param x: location of Hessian operator to be evaluated.
271 :type x: x-type
272 :param r: a given gradient
273 :type r: r-type
274 :param args: pre-calculated values for ``x`` from ``getArguments()``
275 :rtype x: x-type
276 :note: In general it is assumed that the Hessian *H(x)* needs to be calculate in each call for a new
277 location *x*. However, the solver may suggest that this is not required, typically when the iteration
278 ius close to completness.
279 :note: :note: This is the worker for getInverseHessianApproximation()`, needs to be overwritten.
280 """
281 raise NotImplementedError
282

  ViewVC Help
Powered by ViewVC 1.1.26