1
2
3
4
5 from __future__ import division
6 import numpy
7
8 from park.optim import pmap, fitutil
9 from park.fitting import fitresult
10
11 __all__ = ['fitmc', 'FitMCJob']
12
14 """
15 Abstract interface for a local minimizer
16
17 See `park.fitmc.FitSimplex` for a concrete implementation.
18 """
19 - def fit(self, objective, x0):
20 """
21 Minimize the value of a fitness function.
22
23 See `park.fitmc.Fitness` for the definition of the goodness of fit
24 object. x0 is a vector containing the initial value for the fit.
25 """
27 """
28 Cancel the fit. This will be called from a separate execution
29 thread. The fit should terminate as soon as possible after this
30 function has been called. Ideally this would interrupt the
31 cur
32 """
33
35 """
36 Local minimizer using Nelder-Mead simplex algorithm.
37
38 Simplex is robust and derivative free, though not very efficient.
39
40 This class wraps the bounds contrained Nelder-Mead simplex
41 implementation for `park.simplex.simplex`.
42 """
43 radius = 0.05
44 """Size of the initial simplex; this is a portion between 0 and 1"""
45 xtol = 1e-4
46 """Stop when simplex vertices are within xtol of each other"""
47 ftol = 1e-4
48 """Stop when vertex values are within ftol of each other"""
49 maxiter = None
50 """Maximum number of iterations before fit terminates"""
51 - def fit(self, fitness, x0):
52 """Run the fit"""
53 import simplex
54
55 self.cancel = False
56 pars = fitness.fit_parameters()
57 bounds = numpy.array([p.range for p in pars]).T
58 result = simplex.simplex(fitness, x0, bounds=bounds,
59 radius=self.radius, xtol=self.xtol,
60 ftol=self.ftol, maxiter=self.maxiter,
61 abort_test=self._iscancelled)
62
63
64
65 fitpars = [fitresult.FitParameter(pars[i].name,pars[i].range,v)
66 for i,v in enumerate(result.x)]
67 res = fitresult.FitResult(fitpars, result.calls, result.fx)
68
69 res.calc_cov(fitness)
70 return res
71
73 """Cancel the fit in progress from another thread of execution"""
74
75 self.cancel = True
76
77 if hasattr(fitness,'abort'): self.fitness.abort()
78
80
82 """
83 Local minimizer using Nelder-Mead simplex algorithm.
84
85 Simplex is robust and derivative free, though not very efficient.
86
87 This class wraps the bounds contrained Nelder-Mead simplex
88 implementation for `park.simplex.simplex`.
89 """
90 radius = 0.05
91 """Size of the initial simplex; this is a portion between 0 and 1"""
92 xtol = 1e-4
93 """Stop when simplex vertices are within xtol of each other"""
94 ftol = 1e-4
95 """Stop when vertex values are within ftol of each other"""
96 maxiter = None
97 """Maximum number of iterations before fit terminates"""
98 - def fit(self, fitness, x0):
99 """Run the fit"""
100 from scipy.optimize import fmin_cobyla as cobyla
101
102 self.cancel = False
103 pars = fitness.fit_parameters()
104 bounds = numpy.array([p.range for p in pars]).T
105 result = simplex.simplex(fitness, x0, bounds=bounds,
106 radius=self.radius, xtol=self.xtol,
107 ftol=self.ftol, maxiter=self.maxiter,
108 abort_test=self._iscancelled)
109
110
111
112 fitpars = [fitresult.FitParameter(pars[i].name,pars[i].range,v)
113 for i,v in enumerate(result.x)]
114 res = fitresult.FitResult(fitpars, result.calls, result.fx)
115
116 res.calc_cov(fitness)
117 return res
118
120 """Cancel the fit in progress from another thread of execution"""
121
122 self.cancel = True
123
124 if hasattr(fitness,'abort'): self.fitness.abort()
125
127
129 """
130 Evaluate a local fit at a particular start point.
131
132 This is the function to be mapped across a set of start points for the
133 monte carlo map-reduce implementation.
134
135 See `park.pmap.Mapper` for required interface.
136 """
137 - def __init__(self, minimizer, fitness):
138 self.minimizer, self.fitness = minimizer, fitness
140 return self.minimizer.fit(self.fitness,x0)
142 self.minimizer.abort()
143
145 """
146 Collect the results from multiple start points in a Monte Carlo fit engine.
147
148 See `park.pmap.Collector` for required interface.
149 """
150 - def __init__(self, number_expected, handler):
151 self.number_expected = number_expected
152 """Number of starting points to check with local optimizer"""
153 self.iterations = 0
154 self.best = None
155 self.calls = 0
156 self.handler = handler
157 self.handler.done = False
159
160 self.iterations += 1
161 self.calls += result.calls
162 if self.best is None or result.fitness < self.best.fitness:
163 self.best = result
164 self.handler.result = result
165 self.handler.improvement()
166
167
168 self.handler.progress(self.iterations, self.number_expected)
170
171 self.handler.done = True
172 self.handler.abort()
174
175 self.handler.done = True
176 self.handler.finalize()
178
179 self.handler.done = True
180 self.handler.error(msg)
181
182 -def fitmc(fitness,localfit,n,handler):
183 """
184 Run a monte carlo fit.
185
186 This procedure maps a local optimizer across a set of n initial points.
187 The initial parameter value defined by the fitness parameters defines
188 one initial point. The remainder are randomly generated within the
189 bounds of the problem.
190
191 localfit is the local optimizer to use. It should be a bounded
192 optimizer following the `park.fitmc.LocalFit` interface.
193
194 handler accepts updates to the current best set of fit parameters.
195 See `park.fitresult.FitHandler` for details.
196 """
197 P = fitutil.populate(n, fitness.fit_parameters(), radius=100, elitism=True)
198 pmap.pmapreduce(MapMC(localfit,fitness),
199 CollectMC(n,handler),
200 P)
201
203 """
204 Monte Carlo optimizer.
205
206 This implements `park.fit.Fitter`.
207 """
208
209 - def __init__(self,
210 localfit=FitSimplex(),
211 start_points=10):
212 """
213 Parameters are defined by `park.fitmc.fitmc`.
214 """
215 self.localfit = localfit
216 self.start_points = start_points
217
218 - def fit(self, objective, handler):
219 """
220 Run a monte carlo fit.
221
222 This procedure maps a local optimizer across a set of initial points.
223 """
224 fitmc(objective, self.localfit, self.start_points, handler)
225
227 """Multiple minima example"""
228 import time, math
229 class MultiMin(object):
230 def fit_parameters(self):
231 return [fitresult.FitParameter('x1',[-5,5],1)]
232 def __call__(self, p):
233 x=p[0]
234 fx = x**2 + math.sin(2*math.pi*x+3*math.pi/2)
235 return fx
236 handler = fitresult.ConsoleUpdate()
237 handler.progress_delta = 1
238 handler.improvement_delta = 0.1
239 fitmc(MultiMin(), FitSimplex(), 5000, handler)
240 while not handler.done: time.sleep(1)
241
251
252 if __name__ == "__main__":
253
254 assembly_example()
255