Changeset 785
- Timestamp:
- 02/19/15 20:39:03 (15 months ago)
- Location:
- mystic/mystic
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
mystic/mystic/abstract_ensemble_solver.py
r784 r785 207 207 raise NotImplementedError, "must be overwritten..." 208 208 209 def CheckTermination(self, disp=False, info=False, termination=None):209 def Terminated(self, disp=False, info=False, termination=None): 210 210 """check if the solver meets the given termination conditions 211 211 -
mystic/mystic/abstract_solver.py
r784 r785 540 540 return 541 541 542 def CheckTermination(self, disp=False, info=False, termination=None):542 def Terminated(self, disp=False, info=False, termination=None): 543 543 """check if the solver meets the given termination conditions 544 544 … … 592 592 return 593 593 594 def _RegisterObjective(self, cost, ExtraArgs=None): 594 def SetObjective(self, cost, ExtraArgs=None, fetch=False): 595 """set the objective, decorated with bounds, penalties, monitors, etc""" 596 cost = self._bootstrap_objective(cost, ExtraArgs=None) 597 return cost if fetch else None 598 599 def _decorate_objective(self, cost, ExtraArgs=None): 595 600 """decorate cost function with bounds, penalties, monitors, etc""" 596 601 if ExtraArgs is None: ExtraArgs = () … … 610 615 611 616 def _bootstrap_objective(self, cost=None, ExtraArgs=None): 612 """HACK to enable not explicitly calling _ RegisterObjective"""617 """HACK to enable not explicitly calling _decorate_objective""" 613 618 args = None 614 619 if cost is None: # 'use existing cost' 615 620 cost,args = self._cost # use args, unless override with ExtraArgs 616 621 if ExtraArgs is not None: args = ExtraArgs 617 if self._cost[0] is None: # '_ RegisterObjective not yet called'622 if self._cost[0] is None: # '_decorate_objective not yet called' 618 623 if args is None: args = () 619 cost = self._ RegisterObjective(cost, args)624 cost = self._decorate_objective(cost, args) 620 625 return cost 621 626 622 def Step(self, cost=None, ExtraArgs=None, **kwds):627 def _Step(self, cost=None, ExtraArgs=None, **kwds): 623 628 """perform a single optimization iteration 624 629 … … 666 671 return 667 672 668 def _ exitMain(self, **kwds):673 def _Finalize(self, **kwds): 669 674 """cleanup upon exiting the main optimization loop""" 670 675 pass … … 673 678 """process and activate input settings""" 674 679 #allow for inputs that don't conform to AbstractSolver interface 680 #NOTE: not sticky: callback, disp 681 #NOTE: sticky: EvaluationMonitor, StepMonitor, penalty, constraints 675 682 settings = \ 676 683 {'callback':None, #user-supplied function, called after each step … … 688 695 return settings 689 696 697 def Step(self, cost=None, termination=None, ExtraArgs=None, **kwds): 698 """Take a single optimiztion step using the given 'cost' function. 699 700 Description: 701 702 Uses an optimization algorithm to take one 'step' toward 703 the minimum of a function of one or more variables. 704 705 Inputs: 706 707 cost -- the Python function or method to be minimized. 708 709 Additional Inputs: 710 711 termination -- callable object providing termination conditions. 712 ExtraArgs -- extra arguments for cost. 713 714 Further Inputs: 715 716 callback -- an optional user-supplied function to call after each 717 iteration. It is called as callback(xk), where xk is 718 the current parameter vector. [default = None] 719 disp -- non-zero to print convergence messages. 720 721 Notes: 722 If the algorithm does not meet the given termination conditions after 723 the call to "Step", the solver may be left in an "out-of-sync" state. 724 When abandoning an non-terminated solver, one should call "_Finalize" 725 to make sure the solver is fully returned to a "synchronized" state. 726 727 To run the solver until termination, call "Solve()". Alternately, use 728 Terminated()" as the condition in a while loop over "Step". 729 """ 730 disp = kwds.pop('disp', False) 731 732 # register: cost, termination, ExtraArgs 733 cost = self._bootstrap_objective(cost, ExtraArgs) 734 if termination is not None: self.SetTermination(termination) 735 736 # check termination before 'stepping' 737 if len(self._stepmon): 738 msg = self.Terminated(disp=disp, info=True) or None 739 else: msg = None 740 741 # if not terminated, then take a step 742 if msg is None: 743 self._Step(**kwds) #FIXME: not all kwds are given in __doc__ 744 if self.Terminated(): # then cleanup/finalize 745 self._Finalize() 746 747 # get termination message and log state 748 msg = self.Terminated(disp=disp, info=True) or None 749 if msg: 750 self._stepmon.info('STOP("%s")' % msg) 751 self.__save_state(force=True) 752 return msg 753 690 754 def Solve(self, cost=None, termination=None, ExtraArgs=None, **kwds): 691 755 """Minimize a 'cost' function with given termination conditions. … … 693 757 Description: 694 758 695 Uses an optimization algorith to find the minimum of759 Uses an optimization algorithm to find the minimum of 696 760 a function of one or more variables. 697 761 … … 713 777 disp -- non-zero to print convergence messages. 714 778 """ 715 # HACK to enable not explicitly calling _RegisterObjective716 cost = self._bootstrap_objective(cost, ExtraArgs)717 779 # process and activate input settings 718 780 sigint_callback = kwds.pop('sigint_callback', None) 719 781 settings = self._process_inputs(kwds) 720 for key in settings:721 exec "%s = settings['%s']" % (key,key)722 782 723 783 # set up signal handler … … 729 789 if self._handle_sigint: signal.signal(signal.SIGINT,self.signal_handler) 730 790 731 ## decorate cost function with bounds, penalties, monitors, etc 732 #self._RegisterObjective(cost, ExtraArgs) #XXX: SetObjective ? 733 # register termination function 734 if termination is not None: 735 self.SetTermination(termination) 736 737 # the initital optimization iteration 738 if not len(self._stepmon): # do generation = 0 739 self.Step(**settings) # includes settings['callback'] 791 # register: cost, termination, ExtraArgs 792 cost = self._bootstrap_objective(cost, ExtraArgs) 793 if termination is not None: self.SetTermination(termination) 794 #XXX: self.Step(cost, termination, ExtraArgs, **settings) ? 740 795 741 796 # the main optimization loop 742 while not self.CheckTermination(): 743 self.Step(**settings) # includes settings['callback'] 744 else: self._exitMain() 797 while not self.Step(**settings): #XXX: remove need to pass settings? 798 continue 745 799 746 800 # restore default handler for signal interrupts 747 801 signal.signal(signal.SIGINT,signal.default_int_handler) 748 749 # log any termination messages750 msg = self.CheckTermination(disp=disp, info=True)751 if msg: self._stepmon.info('STOP("%s")' % msg)752 # save final state753 self.__save_state(force=True)754 802 return 755 803 -
mystic/mystic/differential_evolution.py
r784 r785 58 58 - EvaluationMonitor = Monitor() 59 59 - StepMonitor = Monitor() 60 - strategy = Best1 Exp60 - strategy = Best1Bin 61 61 - termination = ChangeOverGeneration(ftol,gtol), if gtol provided 62 62 '' = VTRChangeOverGenerations(ftol), otherwise … … 171 171 self.scale = 0.8 172 172 self.probability = 0.9 173 self.strategy = 'Best1Bin' 173 174 ftol = 5e-3 174 175 from mystic.termination import VTRChangeOverGeneration … … 200 201 return 201 202 202 def _ RegisterObjective(self, cost, ExtraArgs=None):203 def _decorate_objective(self, cost, ExtraArgs=None): 203 204 """decorate cost function with bounds, penalties, monitors, etc""" 204 205 if ExtraArgs is None: ExtraArgs = () … … 216 217 return cost 217 218 218 def Step(self, cost=None, ExtraArgs=None, **kwds):219 def _Step(self, cost=None, ExtraArgs=None, **kwds): 219 220 """perform a single optimization iteration 220 221 Note that ExtraArgs should be a *tuple* of extra arguments""" 221 # HACK to enable not explicitly calling _ RegisterObjective222 # HACK to enable not explicitly calling _decorate_objective 222 223 cost = self._bootstrap_objective(cost, ExtraArgs) 223 224 # process and activate input settings … … 275 276 # initialize termination conditions, if needed 276 277 if init: self._termination(self) #XXX: at generation 0 or always? 277 return #XXX: call CheckTermination?278 return #XXX: call Terminated ? 278 279 279 280 def _process_inputs(self, kwds): 280 281 """process and activate input settings""" 281 282 #allow for inputs that don't conform to AbstractSolver interface 283 #NOTE: not sticky: callback, disp 284 #NOTE: sticky: EvaluationMonitor, StepMonitor, penalty, constraints 285 #NOTE: sticky: strategy, CrossProbability, ScalingFactor 282 286 settings = super(DifferentialEvolutionSolver, self)._process_inputs(kwds) 283 from mystic.strategy import Best1Bin 287 from mystic import strategy 288 strategy = getattr(strategy,self.strategy,strategy.Best1Bin) #XXX: None? 284 289 settings.update({\ 285 'strategy': Best1Bin})#mutation strategy (see mystic.strategy)286 probability= 0.9#potential for parameter cross-mutation287 scale= 0.8#multiplier for mutation impact290 'strategy': strategy}) #mutation strategy (see mystic.strategy) 291 probability=self.probability #potential for parameter cross-mutation 292 scale=self.scale #multiplier for mutation impact 288 293 [settings.update({i:j}) for (i,j) in kwds.items() if i in settings] 289 294 self.probability = kwds.get('CrossProbability', probability) 290 295 self.scale = kwds.get('ScalingFactor', scale) 296 self.strategy = getattr(settings['strategy'],'__name__','Best1Bin') 291 297 return settings 292 298 … … 345 351 All important class members are inherited from AbstractSolver. 346 352 """ 347 #XXX: raise Error if npop <= 4?353 NP = max(NP, dim, 4) #XXX: raise Error if npop <= 4? 348 354 super(DifferentialEvolutionSolver2, self).__init__(dim, npop=NP) 349 355 self.genealogy = [ [] for j in range(NP)] 350 356 self.scale = 0.8 351 357 self.probability = 0.9 358 self.strategy = 'Best1Bin' 359 ftol = 5e-3 360 from mystic.termination import VTRChangeOverGeneration 361 self._termination = VTRChangeOverGeneration(ftol) 352 362 353 363 def UpdateGenealogyRecords(self, id, newchild): … … 359 369 return 360 370 361 def _ RegisterObjective(self, cost, ExtraArgs=None):371 def _decorate_objective(self, cost, ExtraArgs=None): 362 372 """decorate cost function with bounds, penalties, monitors, etc""" 363 373 if ExtraArgs is None: ExtraArgs = () … … 380 390 return cost 381 391 382 def Step(self, cost=None, ExtraArgs=None, **kwds):392 def _Step(self, cost=None, ExtraArgs=None, **kwds): 383 393 """perform a single optimization iteration 384 394 Note that ExtraArgs should be a *tuple* of extra arguments""" 385 # HACK to enable not explicitly calling _ RegisterObjective395 # HACK to enable not explicitly calling _decorate_objective 386 396 cost = self._bootstrap_objective(cost, ExtraArgs) 387 397 # process and activate input settings … … 444 454 # initialize termination conditions, if needed 445 455 if init: self._termination(self) #XXX: at generation 0 or always? 446 return #XXX: call CheckTermination?456 return #XXX: call Terminated ? 447 457 448 458 def _process_inputs(self, kwds): 449 459 """process and activate input settings""" 450 460 #allow for inputs that don't conform to AbstractSolver interface 461 #NOTE: not sticky: callback, disp 462 #NOTE: sticky: EvaluationMonitor, StepMonitor, penalty, constraints 463 #NOTE: sticky: strategy, CrossProbability, ScalingFactor 451 464 settings = super(DifferentialEvolutionSolver2, self)._process_inputs(kwds) 452 from mystic.strategy import Best1Bin 465 from mystic import strategy 466 strategy = getattr(strategy,self.strategy,strategy.Best1Bin) #XXX: None? 453 467 settings.update({\ 454 'strategy': Best1Bin})#mutation strategy (see mystic.strategy)455 probability= 0.9#potential for parameter cross-mutation456 scale= 0.8#multiplier for mutation impact468 'strategy': strategy}) #mutation strategy (see mystic.strategy) 469 probability=self.probability #potential for parameter cross-mutation 470 scale=self.scale #multiplier for mutation impact 457 471 [settings.update({i:j}) for (i,j) in kwds.items() if i in settings] 458 472 self.probability = kwds.get('CrossProbability', probability) 459 473 self.scale = kwds.get('ScalingFactor', scale) 474 self.strategy = getattr(settings['strategy'],'__name__','Best1Bin') 460 475 return settings 461 476 -
mystic/mystic/ensemble.py
r784 r785 227 227 228 228 # log any termination messages 229 msg = self. CheckTermination(disp=disp, info=True)229 msg = self.Terminated(disp=disp, info=True) 230 230 if msg: self._stepmon.info('STOP("%s")' % msg) 231 231 # save final state … … 413 413 414 414 # log any termination messages 415 msg = self. CheckTermination(disp=disp, info=True)415 msg = self.Terminated(disp=disp, info=True) 416 416 if msg: self._stepmon.info('STOP("%s")' % msg) 417 417 # save final state … … 523 523 524 524 # code below here pushes output to scipy.optimize.fmin interface 525 msg = solver. CheckTermination(disp=False, info=True)525 msg = solver.Terminated(disp=False, info=True) 526 526 527 527 x = solver.bestSolution … … 654 654 655 655 # code below here pushes output to scipy.optimize.fmin interface 656 msg = solver. CheckTermination(disp=False, info=True)656 msg = solver.Terminated(disp=False, info=True) 657 657 658 658 x = solver.bestSolution -
mystic/mystic/scipy_optimize.py
r784 r785 92 92 self.popEnergy.append(self._init_popEnergy) 93 93 self.population.append([0.0 for i in range(dim)]) 94 self.radius= 0.05 #percentage change for initial simplex values 94 95 xtol, ftol = 1e-4, 1e-4 95 96 from mystic.termination import CandidateRelativeTolerance as CRT … … 141 142 return 142 143 143 def Step(self, cost=None, ExtraArgs=None, **kwds):144 def _Step(self, cost=None, ExtraArgs=None, **kwds): 144 145 """perform a single optimization iteration 145 146 Note that ExtraArgs should be a *tuple* of extra arguments""" 146 # HACK to enable not explicitly calling _ RegisterObjective147 # HACK to enable not explicitly calling _decorate_objective 147 148 cost = self._bootstrap_objective(cost, ExtraArgs) 148 149 # process and activate input settings … … 259 260 # initialize termination conditions, if needed 260 261 if init: self._termination(self) #XXX: at generation 0 or always? 261 return #XXX: call CheckTermination?262 return #XXX: call Terminated ? 262 263 263 264 def _process_inputs(self, kwds): 264 265 """process and activate input settings""" 265 266 #allow for inputs that don't conform to AbstractSolver interface 267 #NOTE: not sticky: callback, disp 268 #NOTE: sticky: EvaluationMonitor, StepMonitor, penalty, constraints 269 #NOTE: sticky: radius 266 270 settings = super(NelderMeadSimplexSolver, self)._process_inputs(kwds) 267 271 settings.update({\ 268 'radius': 0.05})#percentage change for initial simplex values272 'radius':self.radius}) #percentage change for initial simplex values 269 273 [settings.update({i:j}) for (i,j) in kwds.items() if i in settings] 274 self.radius = settings['radius'] 270 275 return settings 271 276 … … 453 458 # [x1, fx, bigind, delta] 454 459 self.__internals = [x1, fx, 0, 0.0] 460 self.xtol = 1e-4 #line-search error tolerance 455 461 ftol, gtol = 1e-4, 2 456 462 from mystic.termination import NormalizedChangeOverGeneration as NCOG … … 461 467 return 462 468 463 def Step(self, cost=None, ExtraArgs=None, **kwds):469 def _Step(self, cost=None, ExtraArgs=None, **kwds): 464 470 """perform a single optimization iteration 465 471 Note that ExtraArgs should be a *tuple* of extra arguments""" 466 # HACK to enable not explicitly calling _ RegisterObjective472 # HACK to enable not explicitly calling _decorate_objective 467 473 cost = self._bootstrap_objective(cost, ExtraArgs) 468 474 # process and activate input settings … … 471 477 exec "%s = settings['%s']" % (key,key) 472 478 473 direc = self._direc 479 direc = self._direc #XXX: throws Error if direc=None after generation=0 474 480 x = self.population[0] # bestSolution 475 481 fval = self.popEnergy[0] # bestEnergy … … 571 577 # initialize termination conditions, if needed 572 578 if init: self._termination(self) #XXX: at generation 0 or always? 573 return #XXX: call CheckTermination?574 575 def _ exitMain(self, **kwds):579 return #XXX: call Terminated ? 580 581 def _Finalize(self, **kwds): 576 582 """cleanup upon exiting the main optimization loop""" 577 583 self.energy_history = None # resync with 'best' energy … … 584 590 """process and activate input settings""" 585 591 #allow for inputs that don't conform to AbstractSolver interface 592 #NOTE: not sticky: callback, disp 593 #NOTE: sticky: EvaluationMonitor, StepMonitor, penalty, constraints 594 #NOTE: sticky: xtol, direc 586 595 settings = super(PowellDirectionalSolver, self)._process_inputs(kwds) 587 596 settings.update({\ 588 'xtol': 1e-4})#line-search error tolerance597 'xtol':self.xtol}) #line-search error tolerance 589 598 direc=self._direc #initial direction set 590 599 [settings.update({i:j}) for (i,j) in kwds.items() if i in settings] 591 600 self._direc = kwds.get('direc', direc) 601 self.xtol = settings['xtol'] 592 602 return settings 593 603
Note: See TracChangeset
for help on using the changeset viewer.