def func(x, z=None): if not hasattr(mask, '__call__'): _mask = mask else: _mask = mask(x, z) if z is None and hasattr(x, '_x') and hasattr(x, '_y'): from copy import copy m = copy(x) mon = True else: from mystic.monitors import Monitor m = Monitor() m._x, m._y = x, z mon = False ax = True if hasattr(m._x, 'tolist') else False ay = True if hasattr(m._y, 'tolist') else False from numpy import asarray m._x = asarray(m._x)[_mask] m._y = asarray(m._y)[_mask] if not ax: m._x = m._x.tolist() if not ay: m._y = m._y.tolist() if mon: try: ai = True if hasattr(m._id, 'tolist') else False m._id = array(m._id)[_mask] if not ai: m._id = m._id.tolist() except IndexError: pass #XXX: m._id = [] return m return m._x, m._y
def write_monitor(steps, energy, id=[]): from mystic.monitors import Monitor mon = Monitor() mon._x = steps[:] mon._y = energy[:] mon._id = id[:] return mon
def __update_allSolvers(self, results): 'replace allSolvers with solvers found in results' #NOTE: apparently, monitors internal to the solver don't work as well # reconnect monitors; save all solvers fcalls = [getattr(s, '_fcalls', [0])[0] for s in self._allSolvers] from mystic.monitors import Monitor while results: #XXX: option to not save allSolvers? skip this and _copy _solver, _stepmon, _evalmon = results.pop() lr = len(results) sm, em = Monitor(), Monitor() s = self._allSolvers[lr] ls, le = len(s._stepmon), len(s._evalmon) # gather old and new results in monitors _solver._stepmon[:] = s._stepmon sm._x, sm._y, sm._id, sm._info = _stepmon _solver._stepmon[ls:] = sm[ls:] del sm _solver._evalmon[:] = s._evalmon em._x, em._y, em._id, em._info = _evalmon _solver._evalmon[le:] = em[le:] del em if not _solver._fcalls[0]: #FIXME: HACK workaround dropped _fcalls lm = len(_solver._evalmon) # ...but only works if has evalmon _solver._fcalls[0] = fcalls[lr] or \ (lm if _solver.Terminated() else 0) #(le if s.Terminated() else 0) self._allSolvers[lr] = _solver #XXX: update not replace? return
def extrapolate(x, z=None, method=None, mins=None, maxs=None, **kwds): '''extrapolate a bounding-box for the given points Input: x: an array of shape (npts, dim) or (npts,) z: an array of shape (npts,) method: a function f(x) to generate new points; if None, use f(x) = nan mins: a list of floats defining minima of the bounding box, or None maxs: a list of floats defining maxima of the bounding box, or None all: if True, include the initial (x,z) points in the return Output: a tuple of (x,z) containing the requested boundbox points NOTE: if z is None, return a tuple (x,) with the requested boundbox points. NOTE: if mins is None, then use the minima found in x. Similarly for maxs. NOTE: method can take a function, None, a boolean, or a string. If method is True, interpolate a cost function using interpf with method='thin_plate' (or 'rbf' if scipy is not found). If method is False, return the original input. Alternately, method can be any one of ('rbf','linear','cubic', 'nearest','inverse','gaussian','multiquadric','quintic','thin_plate'). ''' kwds.setdefault('all', True) import numpy as np output = True if z is None: z = np.nan * np.ones(len(x)) output = False method = None # ignore method xtype = getattr(x, 'dtype', None) ztype = getattr(z, 'dtype', None) if xtype: x = x.tolist() if ztype: z = z.tolist() if method: if method is True: method = 'thin_plate' if not hasattr(method, '__call__'): method = _to_objective(interpf(x, z, method=method)) from mystic.monitors import Monitor mon = Monitor() mon._x = x mon._y = z if (method is None) or method: mon = _boundbox(mon, fx=method, mins=mins, maxs=maxs, **kwds) x = np.array(mon._x, dtype=xtype) if xtype else mon._x z = np.array(mon._y, dtype=ztype) if ztype else mon._y return (x, z) if output else x
def __update_allSolvers(self, results): 'replace allSolvers with solvers found in results' #NOTE: apparently, monitors internal to the solver don't work as well # reconnect monitors; save all solvers fcalls = [getattr(s, '_fcalls', [0])[0] for s in self._allSolvers] from mystic.monitors import Monitor while results: #XXX: option to not save allSolvers? skip this and _copy _solver, _stepmon, _evalmon = results.pop() lr = len(results) sm, em = Monitor(), Monitor() s = self._allSolvers[lr] ls, le = len(s._stepmon), len(s._evalmon) # gather old and new results in monitors _solver._stepmon[:] = s._stepmon sm._x,sm._y,sm._id,sm._info = _stepmon _solver._stepmon[ls:] = sm[ls:] del sm _solver._evalmon[:] = s._evalmon em._x,em._y,em._id,em._info = _evalmon _solver._evalmon[le:] = em[le:] del em if not _solver._fcalls[0]: _solver._fcalls[0] = fcalls[lr] self._allSolvers[lr] = _solver #XXX: update not replace? return
def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): """Minimize a 'cost' function with given termination conditions. Description: Uses an ensemble of optimizers to find the minimum of a function of one or more variables. Inputs: cost -- the Python function or method to be minimized. Additional Inputs: termination -- callable object providing termination conditions. ExtraArgs -- extra arguments for cost. Further Inputs: sigint_callback -- callback function for signal handler. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. [default = None] disp -- non-zero to print convergence messages. [default = 0] """ # process and activate input settings if 'sigint_callback' in kwds: self.sigint_callback = kwds['sigint_callback'] del kwds['sigint_callback'] else: self.sigint_callback = None settings = self._process_inputs(kwds) disp = settings['disp'] if 'disp' in settings else False echo = settings['callback'] if 'callback' in settings else None # for key in settings: # exec "%s = settings['%s']" % (key,key) if disp in ['verbose', 'all']: verbose = True else: verbose = False #------------------------------------------------------------- from mystic.python_map import python_map if self._map != python_map: #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' from mystic.monitors import Null evalmon = Null() else: evalmon = self._evalmon fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) # set up signal handler #self._EARLYEXIT = False # activate signal_handler #import threading as thread #mainthread = isinstance(thread.current_thread(), thread._MainThread) #if mainthread: #XXX: if not mainthread, signal will raise ValueError import mystic._signal as signal if self._handle_sigint: signal.signal(signal.SIGINT, signal.Handler(self)) # register termination function if termination is not None: self.SetTermination(termination) # get the nested solver instance solver = self._AbstractEnsembleSolver__get_solver_instance() #------------------------------------------------------------- # generate starting points initial_values = self._InitialPoints() # run optimizer for each grid point from copy import deepcopy as _copy op = [_copy(solver) for i in range(len(initial_values))] #cf = [cost for i in range(len(initial_values))] vb = [verbose for i in range(len(initial_values))] cb = [echo for i in range(len(initial_values))] #XXX: remove? at = self.id if self.id else 0 # start at self.id id = range(at,at+len(initial_values)) # generate the local_optimize function def local_optimize(solver, x0, rank=None, disp=False, callback=None): from copy import deepcopy as _copy from mystic.tools import isNull solver.id = rank solver.SetInitialPoints(x0) if solver._useStrictRange: #XXX: always, settable, or sync'd ? solver.SetStrictRanges(min=solver._strictMin, \ max=solver._strictMax) # or lower,upper ? solver.Solve(cost, disp=disp, callback=callback) sm = solver._stepmon em = solver._evalmon if isNull(sm): sm = ([],[],[],[]) else: sm = (_copy(sm._x),_copy(sm._y),_copy(sm._id),_copy(sm._info)) if isNull(em): em = ([],[],[],[]) else: em = (_copy(em._x),_copy(em._y),_copy(em._id),_copy(em._info)) return solver, sm, em # map:: solver = local_optimize(solver, x0, id, verbose) results = list(self._map(local_optimize, op, initial_values, id, \ vb, cb, **self._mapconfig)) # save initial state self._AbstractSolver__save_state() #XXX: HACK TO GET CONTENT OF ALL MONITORS # reconnect monitors; save all solvers from mystic.monitors import Monitor while results: #XXX: option to not save allSolvers? skip this and _copy _solver, _stepmon, _evalmon = results.pop() sm = Monitor() sm._x,sm._y,sm._id,sm._info = _stepmon _solver._stepmon.extend(sm) del sm em = Monitor() em._x,em._y,em._id,em._info = _evalmon _solver._evalmon.extend(em) del em self._allSolvers[len(results)] = _solver del results, _solver, _stepmon, _evalmon #XXX: END HACK # get the results with the lowest energy self._bestSolver = self._allSolvers[0] bestpath = self._bestSolver._stepmon besteval = self._bestSolver._evalmon self._total_evals = self._bestSolver.evaluations for solver in self._allSolvers[1:]: self._total_evals += solver.evaluations # add func evals if solver.bestEnergy < self._bestSolver.bestEnergy: self._bestSolver = solver bestpath = solver._stepmon besteval = solver._evalmon # return results to internals self.population = self._bestSolver.population #XXX: pointer? copy? self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? self.bestEnergy = self._bestSolver.bestEnergy self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? self._maxiter = self._bestSolver._maxiter self._maxfun = self._bestSolver._maxfun # write 'bests' to monitors #XXX: non-best monitors may be useful too self._stepmon = bestpath #XXX: pointer? copy? self._evalmon = besteval #XXX: pointer? copy? self.energy_history = None self.solution_history = None #from mystic.tools import isNull #if isNull(bestpath): # self._stepmon = bestpath #else: # for i in range(len(bestpath.y)): # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) # #XXX: could apply callback here, or in exec'd code #if isNull(besteval): # self._evalmon = besteval #else: # for i in range(len(besteval.y)): # self._evalmon(besteval.x[i], besteval.y[i]) #------------------------------------------------------------- # restore default handler for signal interrupts if self._handle_sigint: signal.signal(signal.SIGINT, signal.default_int_handler) # log any termination messages msg = self.Terminated(disp=disp, info=True) if msg: self._stepmon.info('STOP("%s")' % msg) # save final state self._AbstractSolver__save_state(force=True) return
def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): """Minimize a 'cost' function with given termination conditions. Uses an ensemble of optimizers to find the minimum of a function of one or more variables. Args: cost (func, default=None): the function to be minimized: ``y = cost(x)``. termination (termination, default=None): termination conditions. ExtraArgs (tuple, default=None): extra arguments for cost. sigint_callback (func, default=None): callback function for signal handler. callback (func, default=None): function to call after each iteration. The interface is ``callback(xk)``, with xk the current parameter vector. disp (bool, default=False): if True, print convergence messages. Returns: None """ # process and activate input settings if 'sigint_callback' in kwds: self.sigint_callback = kwds['sigint_callback'] del kwds['sigint_callback'] else: self.sigint_callback = None settings = self._process_inputs(kwds) disp = settings['disp'] if 'disp' in settings else False echo = settings['callback'] if 'callback' in settings else None # for key in settings: # exec "%s = settings['%s']" % (key,key) if disp in ['verbose', 'all']: verbose = True else: verbose = False #------------------------------------------------------------- from mystic.python_map import python_map if self._map != python_map: #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' from mystic.monitors import Null evalmon = Null() else: evalmon = self._evalmon fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) # set up signal handler #self._EARLYEXIT = False # activate signal_handler #import threading as thread #mainthread = isinstance(thread.current_thread(), thread._MainThread) #if mainthread: #XXX: if not mainthread, signal will raise ValueError import mystic._signal as signal if self._handle_sigint: signal.signal(signal.SIGINT, signal.Handler(self)) # register termination function if termination is not None: self.SetTermination(termination) # get the nested solver instance solver = self._AbstractEnsembleSolver__get_solver_instance() #------------------------------------------------------------- # generate starting points initial_values = self._InitialPoints() # run optimizer for each grid point from copy import deepcopy as _copy op = [_copy(solver) for i in range(len(initial_values))] #cf = [cost for i in range(len(initial_values))] vb = [verbose for i in range(len(initial_values))] cb = [echo for i in range(len(initial_values))] #XXX: remove? at = self.id if self.id else 0 # start at self.id id = range(at, at + len(initial_values)) # generate the local_optimize function def local_optimize(solver, x0, rank=None, disp=False, callback=None): from copy import deepcopy as _copy from mystic.tools import isNull solver.id = rank solver.SetInitialPoints(x0) if solver._useStrictRange: #XXX: always, settable, or sync'd ? solver.SetStrictRanges(min=solver._strictMin, \ max=solver._strictMax) # or lower,upper ? solver.Solve(cost, disp=disp, callback=callback) sm = solver._stepmon em = solver._evalmon if isNull(sm): sm = ([], [], [], []) else: sm = (_copy(sm._x), _copy(sm._y), _copy(sm._id), _copy(sm._info)) if isNull(em): em = ([], [], [], []) else: em = (_copy(em._x), _copy(em._y), _copy(em._id), _copy(em._info)) return solver, sm, em # map:: solver = local_optimize(solver, x0, id, verbose) results = list(self._map(local_optimize, op, initial_values, id, \ vb, cb, **self._mapconfig)) # save initial state self._AbstractSolver__save_state() #XXX: HACK TO GET CONTENT OF ALL MONITORS # reconnect monitors; save all solvers from mystic.monitors import Monitor while results: #XXX: option to not save allSolvers? skip this and _copy _solver, _stepmon, _evalmon = results.pop() sm = Monitor() sm._x, sm._y, sm._id, sm._info = _stepmon _solver._stepmon.extend(sm) del sm em = Monitor() em._x, em._y, em._id, em._info = _evalmon _solver._evalmon.extend(em) del em self._allSolvers[len(results)] = _solver del results, _solver, _stepmon, _evalmon #XXX: END HACK # get the results with the lowest energy self._bestSolver = self._allSolvers[0] bestpath = self._bestSolver._stepmon besteval = self._bestSolver._evalmon self._total_evals = self._bestSolver.evaluations for solver in self._allSolvers[1:]: self._total_evals += solver.evaluations # add func evals if solver.bestEnergy < self._bestSolver.bestEnergy: self._bestSolver = solver bestpath = solver._stepmon besteval = solver._evalmon # return results to internals self.population = self._bestSolver.population #XXX: pointer? copy? self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? self.bestEnergy = self._bestSolver.bestEnergy self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? self._maxiter = self._bestSolver._maxiter self._maxfun = self._bestSolver._maxfun # write 'bests' to monitors #XXX: non-best monitors may be useful too self._stepmon = bestpath #XXX: pointer? copy? self._evalmon = besteval #XXX: pointer? copy? self.energy_history = None self.solution_history = None #from mystic.tools import isNull #if isNull(bestpath): # self._stepmon = bestpath #else: # for i in range(len(bestpath.y)): # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) # #XXX: could apply callback here, or in exec'd code #if isNull(besteval): # self._evalmon = besteval #else: # for i in range(len(besteval.y)): # self._evalmon(besteval.x[i], besteval.y[i]) #------------------------------------------------------------- # restore default handler for signal interrupts if self._handle_sigint: signal.signal(signal.SIGINT, signal.default_int_handler) # log any termination messages msg = self.Terminated(disp=disp, info=True) if msg: self._stepmon.info('STOP("%s")' % msg) # save final state self._AbstractSolver__save_state(force=True) return
# build train/test data xx = np.array(x) yy = np.array(y) if test_size is None: return xx, xx, yy, yy from sklearn.model_selection import train_test_split as split return split(xx, yy, test_size=test_size, random_state=random_state) if __name__ == '__main__': # get access to data in archive import dataset as ds from mystic.monitors import Monitor m = Monitor() m._x, m._y = ds.read_archive('demo') if not len(m._x): msg = "the 'demo' archive is empty." raise ValueError(msg) xtrain, xtest, ytrain, ytest = traintest(m._x, m._y, test_size=.2, random_state=42) import sklearn.preprocessing as pre import sklearn.neural_network as nn # build dicts of hyperparameters for ANN instance args = dict(hidden_layer_sizes=(100, 75, 50, 25), max_iter=1000, n_iter_no_change=5)
def Solve(self, cost, termination=None, ExtraArgs=(), **kwds): """Minimize a function using batch grid optimization. Description: Uses parallel mapping of solvers on a regular grid to find the minimum of a function of one or more variables. Inputs: cost -- the Python function or method to be minimized. Additional Inputs: termination -- callable object providing termination conditions. ExtraArgs -- extra arguments for cost. Further Inputs: sigint_callback -- callback function for signal handler. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. [default = None] disp -- non-zero to print convergence messages. [default = 0] """ # process and activate input settings sigint_callback = kwds.pop('sigint_callback', None) settings = self._process_inputs(kwds) disp = settings['disp'] if 'disp' in settings else False echo = settings['callback'] if 'callback' in settings else None # for key in settings: # exec "%s = settings['%s']" % (key,key) if disp in ['verbose', 'all']: verbose = True else: verbose = False #------------------------------------------------------------- from python_map import python_map if self._map != python_map: #FIXME: EvaluationMonitor fails for MPI, throws error for 'pp' from mystic.monitors import Null evalmon = Null() else: evalmon = self._evalmon fcalls, cost = wrap_function(cost, ExtraArgs, evalmon) # set up signal handler #self._EARLYEXIT = False self._generateHandler(sigint_callback) # activate signal_handler import signal if self._handle_sigint: signal.signal(signal.SIGINT, self.signal_handler) # register termination function if termination is not None: self.SetTermination(termination) # get the nested solver instance solver = self._AbstractEnsembleSolver__get_solver_instance() #------------------------------------------------------------- nbins = self._nbins if len(self._strictMax): upper = list(self._strictMax) else: upper = list(self._defaultMax) if len(self._strictMin): lower = list(self._strictMin) else: lower = list(self._defaultMin) # generate arrays of points defining a grid in parameter space grid_dimensions = self.nDim bins = [] for i in range(grid_dimensions): step = abs(upper[i] - lower[i]) / nbins[i] bins.append([lower[i] + (j + 0.5) * step for j in range(nbins[i])]) # build a grid of starting points from mystic.math import gridpts initial_values = gridpts(bins) # run optimizer for each grid point from copy import deepcopy as _copy op = [_copy(solver) for i in range(len(initial_values))] #cf = [cost for i in range(len(initial_values))] vb = [verbose for i in range(len(initial_values))] cb = [echo for i in range(len(initial_values))] #XXX: remove? at = self.id if self.id else 0 # start at self.id id = range(at, at + len(initial_values)) # generate the local_optimize function def local_optimize(solver, x0, rank=None, disp=False, callback=None): from copy import deepcopy as _copy from mystic.tools import isNull solver.id = rank solver.SetInitialPoints(x0) if solver._useStrictRange: #XXX: always, settable, or sync'd ? solver.SetStrictRanges(min=solver._strictMin, \ max=solver._strictMax) # or lower,upper ? solver.Solve(cost, disp=disp, callback=callback) sm = solver._stepmon em = solver._evalmon if isNull(sm): sm = ([], [], [], []) else: sm = (_copy(sm._x), _copy(sm._y), _copy(sm._id), _copy(sm._info)) if isNull(em): em = ([], [], [], []) else: em = (_copy(em._x), _copy(em._y), _copy(em._id), _copy(em._info)) return solver, sm, em # map:: solver = local_optimize(solver, x0, id, verbose) results = self._map(local_optimize, op, initial_values, id, \ vb, cb, **self._mapconfig) # save initial state self._AbstractSolver__save_state() #XXX: HACK TO GET CONTENT OF ALL MONITORS # reconnect monitors; save all solvers from mystic.monitors import Monitor while results: #XXX: option to not save allSolvers? skip this and _copy _solver, _stepmon, _evalmon = results.pop() sm = Monitor() sm._x, sm._y, sm._id, sm._info = _stepmon _solver._stepmon.extend(sm) del sm em = Monitor() em._x, em._y, em._id, em._info = _evalmon _solver._evalmon.extend(em) del em self._allSolvers[len(results)] = _solver del results, _solver, _stepmon, _evalmon #XXX: END HACK # get the results with the lowest energy self._bestSolver = self._allSolvers[0] bestpath = self._bestSolver._stepmon besteval = self._bestSolver._evalmon self._total_evals = self._bestSolver.evaluations for solver in self._allSolvers[1:]: self._total_evals += solver.evaluations # add func evals if solver.bestEnergy < self._bestSolver.bestEnergy: self._bestSolver = solver bestpath = solver._stepmon besteval = solver._evalmon # return results to internals self.population = self._bestSolver.population #XXX: pointer? copy? self.popEnergy = self._bestSolver.popEnergy #XXX: pointer? copy? self.bestSolution = self._bestSolver.bestSolution #XXX: pointer? copy? self.bestEnergy = self._bestSolver.bestEnergy self.trialSolution = self._bestSolver.trialSolution #XXX: pointer? copy? self._fcalls = self._bestSolver._fcalls #XXX: pointer? copy? self._maxiter = self._bestSolver._maxiter self._maxfun = self._bestSolver._maxfun # write 'bests' to monitors #XXX: non-best monitors may be useful too self._stepmon = bestpath #XXX: pointer? copy? self._evalmon = besteval #XXX: pointer? copy? self.energy_history = None self.solution_history = None #from mystic.tools import isNull #if isNull(bestpath): # self._stepmon = bestpath #else: # for i in range(len(bestpath.y)): # self._stepmon(bestpath.x[i], bestpath.y[i], self.id) # #XXX: could apply callback here, or in exec'd code #if isNull(besteval): # self._evalmon = besteval #else: # for i in range(len(besteval.y)): # self._evalmon(besteval.x[i], besteval.y[i]) #------------------------------------------------------------- # restore default handler for signal interrupts signal.signal(signal.SIGINT, signal.default_int_handler) # log any termination messages msg = self.Terminated(disp=disp, info=True) if msg: self._stepmon.info('STOP("%s")' % msg) # save final state self._AbstractSolver__save_state(force=True) return