Changeset 860


Ignore:
Timestamp:
04/01/16 20:27:31 (7 weeks ago)
Author:
mmckerns
Message:

refactor ensemble solvers so Solve in abstract class; new _InitialPoints method

Location:
mystic/mystic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/abstract_ensemble_solver.py

    r859 r860  
    8080from mystic.monitors import Null 
    8181from mystic.abstract_map_solver import AbstractMapSolver 
     82from mystic.tools import wrap_function 
    8283 
    8384 
     
    116117 
    117118        # default settings for nested optimization 
     119        #XXX: move nbins and npts to _InitialPoints? 
    118120        nbins = kwds['nbins'] if 'nbins' in kwds else [1]*dim 
    119121        if isinstance(nbins, int): 
     
    270272        return 
    271273 
     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 
     284Description: 
     285 
     286    Uses an ensemble of optimizers to find the minimum of 
     287    a function of one or more variables. 
     288 
     289Inputs: 
     290 
     291    cost -- the Python function or method to be minimized. 
     292 
     293Additional Inputs: 
     294 
     295    termination -- callable object providing termination conditions. 
     296    ExtraArgs -- extra arguments for cost. 
     297 
     298Further 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 
    272449 
    273450if __name__=='__main__': 
  • mystic/mystic/ensemble.py

    r855 r860  
    3131__all__ = ['LatticeSolver','BuckshotSolver'] 
    3232 
    33 from mystic.tools import wrap_function, unpair 
     33from mystic.tools import unpair 
    3434 
    3535from mystic.abstract_ensemble_solver import AbstractEnsembleSolver 
     
    5353        self._termination = NormalizedChangeOverGeneration(convergence_tol) 
    5454 
    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""" 
    12357        nbins = self._nbins 
    12458        if len(self._strictMax): upper = list(self._strictMax) 
     
    13872        # build a grid of starting points 
    13973        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 
    24376 
    24477class BuckshotSolver(AbstractEnsembleSolver): 
     
    25992        self._termination = NormalizedChangeOverGeneration(convergence_tol) 
    26093 
    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""" 
    32596        npts = self._npts 
    32697        if len(self._strictMax): upper = list(self._strictMax) 
     
    331102            lower = list(self._defaultMin) 
    332103 
    333         # generate a set of starting points 
     104        # build a grid of starting points 
    334105        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) 
    438107 
    439108 
Note: See TracChangeset for help on using the changeset viewer.