Changeset 860
- Timestamp:
- 04/01/16 20:27:31 (7 weeks ago)
- Location:
- mystic/mystic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
mystic/mystic/abstract_ensemble_solver.py
r859 r860 80 80 from mystic.monitors import Null 81 81 from mystic.abstract_map_solver import AbstractMapSolver 82 from mystic.tools import wrap_function 82 83 83 84 … … 116 117 117 118 # default settings for nested optimization 119 #XXX: move nbins and npts to _InitialPoints? 118 120 nbins = kwds['nbins'] if 'nbins' in kwds else [1]*dim 119 121 if isinstance(nbins, int): … … 270 272 return 271 273 274 def _InitialPoints(self): 275 """Generate a grid of starting points for the ensemble of optimizers 276 277 *** this method must be overwritten ***""" 278 raise NotImplementedError, "a sampling algorithm was not provided" 279 280 #FIXME: should take cost=None, ExtraArgs=None... and utilize Step 281 def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): 282 """Minimize a 'cost' function with given termination conditions. 283 284 Description: 285 286 Uses an ensemble of optimizers to find the minimum of 287 a function of one or more variables. 288 289 Inputs: 290 291 cost -- the Python function or method to be minimized. 292 293 Additional Inputs: 294 295 termination -- callable object providing termination conditions. 296 ExtraArgs -- extra arguments for cost. 297 298 Further Inputs: 299 300 sigint_callback -- callback function for signal handler. 301 callback -- an optional user-supplied function to call after each 302 iteration. It is called as callback(xk), where xk is the 303 current parameter vector. [default = None] 304 disp -- non-zero to print convergence messages. [default = 0] 305 """ 306 # process and activate input settings 307 sigint_callback = kwds.pop('sigint_callback', None) 308 settings = self._process_inputs(kwds) 309 disp = settings['disp'] if 'disp' in settings else False 310 echo = settings['callback'] if 'callback' in settings else None 311 # for key in settings: 312 # exec "%s = settings['%s']" % (key,key) 313 if disp in ['verbose', 'all']: verbose = True 314 else: verbose = False 315 #------------------------------------------------------------- 316 317 from python_map import python_map 318 if self._map != python_map: 319 #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' 320 from mystic.monitors import Null 321 evalmon = Null() 322 else: evalmon = self._evalmon 323 fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) 324 325 # set up signal handler 326 #self._EARLYEXIT = False 327 self._generateHandler(sigint_callback) 328 329 # activate signal_handler 330 #import threading as thread 331 #mainthread = isinstance(thread.current_thread(), thread._MainThread) 332 #if mainthread: #XXX: if not mainthread, signal will raise ValueError 333 import signal 334 if self._handle_sigint: 335 signal.signal(signal.SIGINT,self.signal_handler) 336 337 # register termination function 338 if termination is not None: self.SetTermination(termination) 339 340 # get the nested solver instance 341 solver = self._AbstractEnsembleSolver__get_solver_instance() 342 #------------------------------------------------------------- 343 344 # generate starting points 345 initial_values = self._InitialPoints() 346 347 # run optimizer for each grid point 348 from copy import deepcopy as _copy 349 op = [_copy(solver) for i in range(len(initial_values))] 350 #cf = [cost for i in range(len(initial_values))] 351 vb = [verbose for i in range(len(initial_values))] 352 cb = [echo for i in range(len(initial_values))] #XXX: remove? 353 at = self.id if self.id else 0 # start at self.id 354 id = range(at,at+len(initial_values)) 355 356 # generate the local_optimize function 357 def local_optimize(solver, x0, rank=None, disp=False, callback=None): 358 from copy import deepcopy as _copy 359 from mystic.tools import isNull 360 solver.id = rank 361 solver.SetInitialPoints(x0) 362 if solver._useStrictRange: #XXX: always, settable, or sync'd ? 363 solver.SetStrictRanges(min=solver._strictMin, \ 364 max=solver._strictMax) # or lower,upper ? 365 solver.Solve(cost, disp=disp, callback=callback) 366 sm = solver._stepmon 367 em = solver._evalmon 368 if isNull(sm): sm = ([],[],[],[]) 369 else: sm = (_copy(sm._x),_copy(sm._y),_copy(sm._id),_copy(sm._info)) 370 if isNull(em): em = ([],[],[],[]) 371 else: em = (_copy(em._x),_copy(em._y),_copy(em._id),_copy(em._info)) 372 return solver, sm, em 373 374 # map:: solver = local_optimize(solver, x0, id, verbose) 375 results = self._map(local_optimize, op, initial_values, id, \ 376 vb, cb, **self._mapconfig) 377 378 # save initial state 379 self._AbstractSolver__save_state() 380 #XXX: HACK TO GET CONTENT OF ALL MONITORS 381 # reconnect monitors; save all solvers 382 from mystic.monitors import Monitor 383 while results: #XXX: option to not save allSolvers? skip this and _copy 384 _solver, _stepmon, _evalmon = results.pop() 385 sm = Monitor() 386 sm._x,sm._y,sm._id,sm._info = _stepmon 387 _solver._stepmon.extend(sm) 388 del sm 389 em = Monitor() 390 em._x,em._y,em._id,em._info = _evalmon 391 _solver._evalmon.extend(em) 392 del em 393 self._allSolvers[len(results)] = _solver 394 del results, _solver, _stepmon, _evalmon 395 #XXX: END HACK 396 397 # get the results with the lowest energy 398 self._bestSolver = self._allSolvers[0] 399 bestpath = self._bestSolver._stepmon 400 besteval = self._bestSolver._evalmon 401 self._total_evals = self._bestSolver.evaluations 402 for solver in self._allSolvers[1:]: 403 self._total_evals += solver.evaluations # add func evals 404 if solver.bestEnergy < self._bestSolver.bestEnergy: 405 self._bestSolver = solver 406 bestpath = solver._stepmon 407 besteval = solver._evalmon 408 409 # return results to internals 410 self.population = self._bestSolver.population #XXX: pointer? copy? 411 self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? 412 self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? 413 self.bestEnergy = self._bestSolver.bestEnergy 414 self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? 415 self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? 416 self._maxiter = self._bestSolver._maxiter 417 self._maxfun = self._bestSolver._maxfun 418 419 # write 'bests' to monitors #XXX: non-best monitors may be useful too 420 self._stepmon = bestpath #XXX: pointer? copy? 421 self._evalmon = besteval #XXX: pointer? copy? 422 self.energy_history = None 423 self.solution_history = None 424 #from mystic.tools import isNull 425 #if isNull(bestpath): 426 # self._stepmon = bestpath 427 #else: 428 # for i in range(len(bestpath.y)): 429 # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) 430 # #XXX: could apply callback here, or in exec'd code 431 #if isNull(besteval): 432 # self._evalmon = besteval 433 #else: 434 # for i in range(len(besteval.y)): 435 # self._evalmon(besteval.x[i], besteval.y[i]) 436 #------------------------------------------------------------- 437 438 # restore default handler for signal interrupts 439 if self._handle_sigint: 440 signal.signal(signal.SIGINT,signal.default_int_handler) 441 442 # log any termination messages 443 msg = self.Terminated(disp=disp, info=True) 444 if msg: self._stepmon.info('STOP("%s")' % msg) 445 # save final state 446 self._AbstractSolver__save_state(force=True) 447 return 448 272 449 273 450 if __name__=='__main__': -
mystic/mystic/ensemble.py
r855 r860 31 31 __all__ = ['LatticeSolver','BuckshotSolver'] 32 32 33 from mystic.tools import wrap_function,unpair33 from mystic.tools import unpair 34 34 35 35 from mystic.abstract_ensemble_solver import AbstractEnsembleSolver … … 53 53 self._termination = NormalizedChangeOverGeneration(convergence_tol) 54 54 55 # def SetGridBins(self, nbins): 56 # return 57 58 #FIXME: should take cost=None, ExtraArgs=None... and utilize Step 59 def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): 60 """Minimize a function using batch grid optimization. 61 62 Description: 63 64 Uses parallel mapping of solvers on a regular grid to find the 65 minimum of a function of one or more variables. 66 67 Inputs: 68 69 cost -- the Python function or method to be minimized. 70 71 Additional Inputs: 72 73 termination -- callable object providing termination conditions. 74 ExtraArgs -- extra arguments for cost. 75 76 Further Inputs: 77 78 sigint_callback -- callback function for signal handler. 79 callback -- an optional user-supplied function to call after each 80 iteration. It is called as callback(xk), where xk is the 81 current parameter vector. [default = None] 82 disp -- non-zero to print convergence messages. [default = 0] 83 """ 84 # process and activate input settings 85 sigint_callback = kwds.pop('sigint_callback', None) 86 settings = self._process_inputs(kwds) 87 disp = settings['disp'] if 'disp' in settings else False 88 echo = settings['callback'] if 'callback' in settings else None 89 # for key in settings: 90 # exec "%s = settings['%s']" % (key,key) 91 if disp in ['verbose', 'all']: verbose = True 92 else: verbose = False 93 #------------------------------------------------------------- 94 95 from python_map import python_map 96 if self._map != python_map: 97 #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' 98 from mystic.monitors import Null 99 evalmon = Null() 100 else: evalmon = self._evalmon 101 fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) 102 103 # set up signal handler 104 #self._EARLYEXIT = False 105 self._generateHandler(sigint_callback) 106 107 # activate signal_handler 108 #import threading as thread 109 #mainthread = isinstance(thread.current_thread(), thread._MainThread) 110 #if mainthread: #XXX: if not mainthread, signal will raise ValueError 111 import signal 112 if self._handle_sigint: 113 signal.signal(signal.SIGINT,self.signal_handler) 114 115 # register termination function 116 if termination is not None: 117 self.SetTermination(termination) 118 119 # get the nested solver instance 120 solver = self._AbstractEnsembleSolver__get_solver_instance() 121 #------------------------------------------------------------- 122 55 def _InitialPoints(self): 56 """Generate a grid of starting points for the ensemble of optimizers""" 123 57 nbins = self._nbins 124 58 if len(self._strictMax): upper = list(self._strictMax) … … 138 72 # build a grid of starting points 139 73 from mystic.math import gridpts 140 initial_values = gridpts(bins) 141 142 # run optimizer for each grid point 143 from copy import deepcopy as _copy 144 op = [_copy(solver) for i in range(len(initial_values))] 145 #cf = [cost for i in range(len(initial_values))] 146 vb = [verbose for i in range(len(initial_values))] 147 cb = [echo for i in range(len(initial_values))] #XXX: remove? 148 at = self.id if self.id else 0 # start at self.id 149 id = range(at,at+len(initial_values)) 150 151 # generate the local_optimize function 152 def local_optimize(solver, x0, rank=None, disp=False, callback=None): 153 from copy import deepcopy as _copy 154 from mystic.tools import isNull 155 solver.id = rank 156 solver.SetInitialPoints(x0) 157 if solver._useStrictRange: #XXX: always, settable, or sync'd ? 158 solver.SetStrictRanges(min=solver._strictMin, \ 159 max=solver._strictMax) # or lower,upper ? 160 solver.Solve(cost, disp=disp, callback=callback) 161 sm = solver._stepmon 162 em = solver._evalmon 163 if isNull(sm): sm = ([],[],[],[]) 164 else: sm = (_copy(sm._x),_copy(sm._y),_copy(sm._id),_copy(sm._info)) 165 if isNull(em): em = ([],[],[],[]) 166 else: em = (_copy(em._x),_copy(em._y),_copy(em._id),_copy(em._info)) 167 return solver, sm, em 168 169 # map:: solver = local_optimize(solver, x0, id, verbose) 170 results = self._map(local_optimize, op, initial_values, id, \ 171 vb, cb, **self._mapconfig) 172 173 # save initial state 174 self._AbstractSolver__save_state() 175 #XXX: HACK TO GET CONTENT OF ALL MONITORS 176 # reconnect monitors; save all solvers 177 from mystic.monitors import Monitor 178 while results: #XXX: option to not save allSolvers? skip this and _copy 179 _solver, _stepmon, _evalmon = results.pop() 180 sm = Monitor() 181 sm._x,sm._y,sm._id,sm._info = _stepmon 182 _solver._stepmon.extend(sm) 183 del sm 184 em = Monitor() 185 em._x,em._y,em._id,em._info = _evalmon 186 _solver._evalmon.extend(em) 187 del em 188 self._allSolvers[len(results)] = _solver 189 del results, _solver, _stepmon, _evalmon 190 #XXX: END HACK 191 192 # get the results with the lowest energy 193 self._bestSolver = self._allSolvers[0] 194 bestpath = self._bestSolver._stepmon 195 besteval = self._bestSolver._evalmon 196 self._total_evals = self._bestSolver.evaluations 197 for solver in self._allSolvers[1:]: 198 self._total_evals += solver.evaluations # add func evals 199 if solver.bestEnergy < self._bestSolver.bestEnergy: 200 self._bestSolver = solver 201 bestpath = solver._stepmon 202 besteval = solver._evalmon 203 204 # return results to internals 205 self.population = self._bestSolver.population #XXX: pointer? copy? 206 self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? 207 self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? 208 self.bestEnergy = self._bestSolver.bestEnergy 209 self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? 210 self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? 211 self._maxiter = self._bestSolver._maxiter 212 self._maxfun = self._bestSolver._maxfun 213 214 # write 'bests' to monitors #XXX: non-best monitors may be useful too 215 self._stepmon = bestpath #XXX: pointer? copy? 216 self._evalmon = besteval #XXX: pointer? copy? 217 self.energy_history = None 218 self.solution_history = None 219 #from mystic.tools import isNull 220 #if isNull(bestpath): 221 # self._stepmon = bestpath 222 #else: 223 # for i in range(len(bestpath.y)): 224 # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) 225 # #XXX: could apply callback here, or in exec'd code 226 #if isNull(besteval): 227 # self._evalmon = besteval 228 #else: 229 # for i in range(len(besteval.y)): 230 # self._evalmon(besteval.x[i], besteval.y[i]) 231 #------------------------------------------------------------- 232 233 # restore default handler for signal interrupts 234 if self._handle_sigint: 235 signal.signal(signal.SIGINT,signal.default_int_handler) 236 237 # log any termination messages 238 msg = self.Terminated(disp=disp, info=True) 239 if msg: self._stepmon.info('STOP("%s")' % msg) 240 # save final state 241 self._AbstractSolver__save_state(force=True) 242 return 74 return gridpts(bins) 75 243 76 244 77 class BuckshotSolver(AbstractEnsembleSolver): … … 259 92 self._termination = NormalizedChangeOverGeneration(convergence_tol) 260 93 261 def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): 262 """Minimize a function using buckshot optimization. 263 264 Description: 265 266 Uses parallel mapping of solvers on randomly selected points 267 to find the minimum of a function of one or more variables. 268 269 Inputs: 270 271 cost -- the Python function or method to be minimized. 272 273 Additional Inputs: 274 275 termination -- callable object providing termination conditions. 276 ExtraArgs -- extra arguments for cost. 277 278 Further Inputs: 279 280 sigint_callback -- callback function for signal handler. 281 callback -- an optional user-supplied function to call after each 282 iteration. It is called as callback(xk), where xk is the 283 current parameter vector. [default = None] 284 disp -- non-zero to print convergence messages. [default = 0] 285 """ 286 # process and activate input settings 287 sigint_callback = kwds.pop('sigint_callback', None) 288 settings = self._process_inputs(kwds) 289 disp = settings['disp'] if 'disp' in settings else False 290 echo = settings['callback'] if 'callback' in settings else None 291 # for key in settings: 292 # exec "%s = settings['%s']" % (key,key) 293 if disp in ['verbose', 'all']: verbose = True 294 else: verbose = False 295 #------------------------------------------------------------- 296 297 from python_map import python_map 298 if self._map != python_map: 299 #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' 300 from mystic.monitors import Null 301 evalmon = Null() 302 else: evalmon = self._evalmon 303 fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) 304 305 # set up signal handler 306 #self._EARLYEXIT = False 307 self._generateHandler(sigint_callback) 308 309 # activate signal_handler 310 #import threading as thread 311 #mainthread = isinstance(thread.current_thread(), thread._MainThread) 312 #if mainthread: #XXX: if not mainthread, signal will raise ValueError 313 import signal 314 if self._handle_sigint: 315 signal.signal(signal.SIGINT,self.signal_handler) 316 317 # register termination function 318 if termination is not None: 319 self.SetTermination(termination) 320 321 # get the nested solver instance 322 solver = self._AbstractEnsembleSolver__get_solver_instance() 323 #------------------------------------------------------------- 324 94 def _InitialPoints(self): 95 """Generate a grid of starting points for the ensemble of optimizers""" 325 96 npts = self._npts 326 97 if len(self._strictMax): upper = list(self._strictMax) … … 331 102 lower = list(self._defaultMin) 332 103 333 # generate a setof starting points104 # build a grid of starting points 334 105 from mystic.math import samplepts 335 initial_values = samplepts(lower,upper,npts) 336 337 # run optimizer for each grid point 338 from copy import deepcopy as _copy 339 op = [_copy(solver) for i in range(len(initial_values))] 340 #cf = [cost for i in range(len(initial_values))] 341 vb = [verbose for i in range(len(initial_values))] 342 cb = [echo for i in range(len(initial_values))] #XXX: remove? 343 at = self.id if self.id else 0 # start at self.id 344 id = range(at,at+len(initial_values)) 345 346 # generate the local_optimize function 347 def local_optimize(solver, x0, rank=None, disp=False, callback=None): 348 from copy import deepcopy as _copy 349 from mystic.tools import isNull 350 solver.id = rank 351 solver.SetInitialPoints(x0) 352 if solver._useStrictRange: #XXX: always, settable, or sync'd ? 353 solver.SetStrictRanges(min=solver._strictMin, \ 354 max=solver._strictMax) # or lower,upper ? 355 solver.Solve(cost, disp=disp, callback=callback) 356 sm = solver._stepmon 357 em = solver._evalmon 358 if isNull(sm): sm = ([],[],[],[]) 359 else: sm = (_copy(sm._x),_copy(sm._y),_copy(sm._id),_copy(sm._info)) 360 if isNull(em): em = ([],[],[],[]) 361 else: em = (_copy(em._x),_copy(em._y),_copy(em._id),_copy(em._info)) 362 return solver, sm, em 363 364 # map:: solver = local_optimize(solver, x0, id, verbose) 365 results = self._map(local_optimize, op, initial_values, id, \ 366 vb, cb, **self._mapconfig) 367 368 # save initial state 369 self._AbstractSolver__save_state() 370 #XXX: HACK TO GET CONTENT OF ALL MONITORS 371 # reconnect monitors; save all solvers 372 from mystic.monitors import Monitor 373 while results: #XXX: option to not store allSolvers? skip this & _copy 374 _solver, _stepmon, _evalmon = results.pop() 375 sm = Monitor() 376 sm._x,sm._y,sm._id,sm._info = _stepmon 377 _solver._stepmon.extend(sm) 378 del sm 379 em = Monitor() 380 em._x,em._y,em._id,em._info = _evalmon 381 _solver._evalmon.extend(em) 382 del em 383 self._allSolvers[len(results)] = _solver 384 del results, _solver, _stepmon, _evalmon 385 #XXX: END HACK 386 387 # get the results with the lowest energy 388 self._bestSolver = self._allSolvers[0] 389 bestpath = self._bestSolver._stepmon 390 besteval = self._bestSolver._evalmon 391 self._total_evals = self._bestSolver.evaluations 392 for solver in self._allSolvers[1:]: 393 self._total_evals += solver.evaluations # add func evals 394 if solver.bestEnergy < self._bestSolver.bestEnergy: 395 self._bestSolver = solver 396 bestpath = solver._stepmon 397 besteval = solver._evalmon 398 399 # return results to internals 400 self.population = self._bestSolver.population #XXX: pointer? copy? 401 self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? 402 self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? 403 self.bestEnergy = self._bestSolver.bestEnergy 404 self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? 405 self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? 406 self._maxiter = self._bestSolver._maxiter 407 self._maxfun = self._bestSolver._maxfun 408 409 # write 'bests' to monitors #XXX: non-best monitors may be useful too 410 self._stepmon = bestpath #XXX: pointer? copy? 411 self._evalmon = besteval #XXX: pointer? copy? 412 self.energy_history = None 413 self.solution_history = None 414 #from mystic.tools import isNull 415 #if isNull(bestpath): 416 # self._stepmon = bestpath 417 #else: 418 # for i in range(len(bestpath.y)): 419 # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) 420 # #XXX: could apply callback here, or in exec'd code 421 #if isNull(besteval): 422 # self._evalmon = besteval 423 #else: 424 # for i in range(len(besteval.y)): 425 # self._evalmon(besteval.x[i], besteval.y[i]) 426 #------------------------------------------------------------- 427 428 # restore default handler for signal interrupts 429 if self._handle_sigint: 430 signal.signal(signal.SIGINT,signal.default_int_handler) 431 432 # log any termination messages 433 msg = self.Terminated(disp=disp, info=True) 434 if msg: self._stepmon.info('STOP("%s")' % msg) 435 # save final state 436 self._AbstractSolver__save_state(force=True) 437 return 106 return samplepts(lower,upper,npts) 438 107 439 108
Note: See TracChangeset
for help on using the changeset viewer.