def __init__(self, dim, NP=4): """ Takes two initial inputs: dim -- dimensionality of the problem NP -- size of the trial solution population. [requires: NP >= 4] All important class members are inherited from AbstractSolver. """ NP = max(NP, dim, 4) #XXX: raise Error if npop <= 4? AbstractSolver.__init__(self,dim,npop=NP) self.genealogy = [ [] for j in range(NP)] self.scale = 0.8 self.probability = 0.9 ftol = 5e-3 from mystic.termination import VTRChangeOverGeneration self._termination = VTRChangeOverGeneration(ftol)
# - https://github.com/uqfoundation/mystic/blob/master/LICENSE from mystic.models import rosen from mystic.solvers import * from mystic.termination import VTRChangeOverGeneration from mystic.monitors import VerboseMonitor, Monitor from mystic.tools import random_seed random_seed(123) lb, ub = [-100.] * 3, [100] * 3 interval = None if interval: _stepmon = VerboseMonitor(interval) else: _stepmon = Monitor() _term = VTRChangeOverGeneration(generations=200) _solver = DifferentialEvolutionSolver(3, 20) #40) _solver.SetRandomInitialPoints(lb, ub) _solver.SetStrictRanges(lb, ub) _solver.SetTermination(_term) _solver.SetGenerationMonitor(_stepmon) _solver.SetEvaluationLimits(100, 1000) _solver.Solve(rosen) _energy = _solver.bestEnergy _solution = _solver.bestSolution _population = _solver.population _solver.SetEvaluationLimits(10000, 100000) _solver.Solve()
def buckshot(cost,ndim,npts=8,args=(),bounds=None,ftol=1e-4,maxiter=None, \ maxfun=None,full_output=0,disp=1,retall=0,callback=None,**kwds): """Minimize a function using the buckshot ensemble solver. Uses a buckshot ensemble algorithm to find the minimum of a function of one or more variables. Mimics the ``scipy.optimize.fmin`` interface. Starts *npts* solver instances at random points in parameter space. Args: cost (func): the function or method to be minimized: ``y = cost(x)``. ndim (int): dimensionality of the problem. npts (int, default=8): number of solver instances. args (tuple, default=()): extra arguments for cost. bounds (list(tuple), default=None): list of pairs of bounds (min,max), one for each parameter. ftol (float, default=1e-4): acceptable relative error in ``cost(xopt)`` for convergence. gtol (float, default=10): maximum iterations to run without improvement. maxiter (int, default=None): the maximum number of iterations to perform. maxfun (int, default=None): the maximum number of function evaluations. full_output (bool, default=False): True if fval and warnflag are desired. disp (bool, default=True): if True, print convergence messages. retall (bool, default=False): if True, return list of solutions at each iteration. callback (func, default=None): function to call after each iteration. The interface is ``callback(xk)``, with xk the current parameter vector. solver (solver, default=None): override the default nested Solver instance. handler (bool, default=False): if True, enable handling interrupt signals. itermon (monitor, default=None): override the default GenerationMonitor. evalmon (monitor, default=None): override the default EvaluationMonitor. constraints (func, default=None): a function ``xk' = constraints(xk)``, where xk is the current parameter vector, and xk' is a parameter vector that satisfies the encoded constraints. penalty (func, default=None): a function ``y = penalty(xk)``, where xk is the current parameter vector, and ``y' == 0`` when the encoded constraints are satisfied (and ``y' > 0`` otherwise). dist (mystic.math.Distribution, default=None): generate randomness in ensemble starting position using the given distribution. Returns: ``(xopt, {fopt, iter, funcalls, warnflag, allfuncalls}, {allvecs})`` Notes: - xopt (*ndarray*): the minimizer of the cost function - fopt (*float*): value of cost function at minimum: ``fopt = cost(xopt)`` - iter (*int*): number of iterations - funcalls (*int*): number of function calls - warnflag (*int*): warning flag: - ``1 : Maximum number of function evaluations`` - ``2 : Maximum number of iterations`` - allfuncalls (*int*): total function calls (for all solver instances) - allvecs (*list*): a list of solutions at each iteration """ handler = kwds['handler'] if 'handler' in kwds else False from mystic.solvers import NelderMeadSimplexSolver as _solver if 'solver' in kwds: _solver = kwds['solver'] from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() gtol = 10 # termination generations (scipy: 2, default: 10) if 'gtol' in kwds: gtol = kwds['gtol'] if gtol: #if number of generations is provided, use NCOG from mystic.termination import NormalizedChangeOverGeneration termination = NormalizedChangeOverGeneration(ftol, gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = BuckshotSolver(ndim, npts) solver.SetNestedSolver(_solver) #XXX: skip settings for configured solver? solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'dist' in kwds: solver.SetDistribution(kwds['dist']) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb, maxb = unpair(bounds) solver.SetStrictRanges(minb, maxb) if handler: solver.enable_signal_handler() solver.Solve(cost,termination=termination,disp=disp, \ ExtraArgs=args,callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface msg = solver.Terminated(disp=False, info=True) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations all_fcalls = solver._total_evals iterations = solver.generations allvecs = solver._stepmon.x if fcalls >= solver._maxfun: #XXX: check against total or individual? warnflag = 1 elif iterations >= solver._maxiter: #XXX: check against total or individual? warnflag = 2 else: pass if full_output: retlist = x, fval, iterations, fcalls, warnflag, all_fcalls if retall: retlist += (allvecs, ) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def diffev(cost, x0, npop=4, args=(), bounds=None, ftol=5e-3, gtol=None, maxiter=None, maxfun=None, cross=0.9, scale=0.8, full_output=0, disp=1, retall=0, callback=None, **kwds): """Minimize a function using differential evolution. Uses a differential evolution algorithm to find the minimum of a function of one or more variables. Mimics a ``scipy.optimize`` style interface. Args: cost (func): the function or method to be minimized: ``y = cost(x)``. x0 (ndarray): the initial guess parameter vector ``x`` if desired start is a single point, otherwise takes a list of (min,max) bounds that define a region from which random initial points are drawn. npop (int, default=4): size of the trial solution population. args (tuple, default=()): extra arguments for cost. bounds (list(tuple), default=None): list of pairs of bounds (min,max), one for each parameter. ftol (float, default=5e-3): acceptable relative error in ``cost(xopt)`` for convergence. gtol (float, default=None): maximum iterations to run without improvement. maxiter (int, default=None): the maximum number of iterations to perform. maxfun (int, default=None): the maximum number of function evaluations. cross (float, default=0.9): the probability of cross-parameter mutations. scale (float, default=0.8): multiplier for mutations on the trial solution. full_output (bool, default=False): True if fval and warnflag are desired. disp (bool, default=True): if True, print convergence messages. retall (bool, default=False): True if allvecs is desired. callback (func, default=None): function to call after each iteration. The interface is ``callback(xk)``, with xk the current parameter vector. handler (bool, default=False): if True, enable handling interrupt signals. strategy (strategy, default=None): override the default mutation strategy. itermon (monitor, default=None): override the default GenerationMonitor. evalmon (monitor, default=None): override the default EvaluationMonitor. constraints (func, default=None): a function ``xk' = constraints(xk)``, where xk is the current parameter vector, and xk' is a parameter vector that satisfies the encoded constraints. penalty (func, default=None): a function ``y = penalty(xk)``, where xk is the current parameter vector, and ``y' == 0`` when the encoded constraints are satisfied (and ``y' > 0`` otherwise). map (func, default=None): a (parallel) map function ``y = map(f, x)``. Returns: ``(xopt, {fopt, iter, funcalls, warnflag}, {allvecs})`` Notes: - xopt (*ndarray*): the minimizer of the cost function - fopt (*float*): value of cost function at minimum: ``fopt = cost(xopt)`` - iter (*int*): number of iterations - funcalls (*int*): number of function calls - warnflag (*int*): warning flag: - ``1 : Maximum number of function evaluations`` - ``2 : Maximum number of iterations`` - allvecs (*list*): a list of solutions at each iteration """ invariant_current = kwds[ 'invariant_current'] if 'invariant_current' in kwds else False handler = kwds['handler'] if 'handler' in kwds else False from mystic.strategy import Best1Bin strategy = kwds['strategy'] if 'strategy' in kwds else Best1Bin from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() if gtol: #if number of generations provided, use ChangeOverGeneration from mystic.termination import ChangeOverGeneration termination = ChangeOverGeneration(ftol, gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) ND = len(x0) if invariant_current: #use Solver2, not Solver1 solver = DifferentialEvolutionSolver2(ND, npop) else: solver = DifferentialEvolutionSolver(ND, npop) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb, maxb = unpair(bounds) solver.SetStrictRanges(minb, maxb) try: #x0 passed as 1D array of (min,max) pairs minb, maxb = unpair(x0) solver.SetRandomInitialPoints(minb, maxb) except: #x0 passed as 1D array of initial parameter values solver.SetInitialPoints(x0) _map = kwds['map'] if 'map' in kwds else None if _map: solver.SetMapper(_map) if handler: solver.enable_signal_handler() #TODO: allow sigint_callbacks for all minimal interfaces ? solver.Solve(cost, termination=termination, strategy=strategy, \ #sigint_callback=other_callback,\ CrossProbability=cross, ScalingFactor=scale, \ ExtraArgs=args, callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x if fcalls >= solver._maxfun: warnflag = 1 if disp: print("Warning: Maximum number of function evaluations has "\ "been exceeded.") elif iterations >= solver._maxiter: warnflag = 2 if disp: print("Warning: Maximum number of iterations has been exceeded") else: if disp: print("Optimization terminated successfully.") print(" Current function value: %f" % fval) print(" Iterations: %d" % iterations) print(" Function evaluations: %d" % fcalls) if full_output: retlist = x, fval, iterations, fcalls, warnflag if retall: retlist += (allvecs, ) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def buckshot(cost,ndim,npts=8,args=(),bounds=None,ftol=1e-4,maxiter=None, \ maxfun=None,full_output=0,disp=1,retall=0,callback=None,**kwds): """Minimize a function using the buckshot ensemble solver. Description: Uses a buckshot ensemble algorithm to find the minimum of a function of one or more variables. Mimics the scipy.optimize.fmin interface. Starts 'npts' solver instances at random points in parameter space. Inputs: cost -- the Python function or method to be minimized. ndim -- dimensionality of the problem. npts -- number of solver instances. Additional Inputs: args -- extra arguments for cost. bounds -- list - n pairs of bounds (min,max), one pair for each parameter. ftol -- number - acceptable relative error in cost(xopt) for convergence. gtol -- number - maximum number of iterations to run without improvement. maxiter -- number - the maximum number of iterations to perform. maxfun -- number - the maximum number of function evaluations. full_output -- number - non-zero if fval and warnflag outputs are desired. disp -- number - non-zero to print convergence messages. retall -- number - non-zero to return list of solutions at each iteration. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. solver -- solver - override the default nested Solver instance. handler -- boolean - enable/disable handling of interrupt signal. itermon -- monitor - override the default GenerationMonitor. evalmon -- monitor - override the default EvaluationMonitor. constraints -- an optional user-supplied function. It is called as constraints(xk), where xk is the current parameter vector. This function must return xk', a parameter vector that satisfies the encoded constraints. penalty -- an optional user-supplied function. It is called as penalty(xk), where xk is the current parameter vector. This function should return y', with y' == 0 when the encoded constraints are satisfied, and y' > 0 otherwise. dist -- an optional mystic.math.Distribution instance. If provided, this distribution generates randomness in ensemble starting position. Returns: (xopt, {fopt, iter, funcalls, warnflag, allfuncalls}, {allvecs}) xopt -- ndarray - minimizer of function fopt -- number - value of function at minimum: fopt = cost(xopt) iter -- number - number of iterations funcalls -- number - number of function calls warnflag -- number - Integer warning flag: 1 : 'Maximum number of function evaluations.' 2 : 'Maximum number of iterations.' allfuncalls -- number - total function calls (for all solver instances) allvecs -- list - a list of solutions at each iteration """ handler = kwds['handler'] if 'handler' in kwds else False from mystic.solvers import NelderMeadSimplexSolver as _solver if 'solver' in kwds: _solver = kwds['solver'] from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() gtol = 10 # termination generations (scipy: 2, default: 10) if 'gtol' in kwds: gtol = kwds['gtol'] if gtol: #if number of generations is provided, use NCOG from mystic.termination import NormalizedChangeOverGeneration termination = NormalizedChangeOverGeneration(ftol,gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = BuckshotSolver(ndim,npts) solver.SetNestedSolver(_solver) #XXX: skip settings for configured solver? solver.SetEvaluationLimits(maxiter,maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'dist' in kwds: solver.SetDistribution(kwds['dist']) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb,maxb = unpair(bounds) solver.SetStrictRanges(minb,maxb) if handler: solver.enable_signal_handler() solver.Solve(cost,termination=termination,disp=disp, \ ExtraArgs=args,callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface msg = solver.Terminated(disp=False, info=True) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations all_fcalls = solver._total_evals iterations = solver.generations allvecs = solver._stepmon.x if fcalls >= solver._maxfun: #XXX: check against total or individual? warnflag = 1 elif iterations >= solver._maxiter: #XXX: check against total or individual? warnflag = 2 else: pass if full_output: retlist = x, fval, iterations, fcalls, warnflag, all_fcalls if retall: retlist += (allvecs,) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def fmin_powell(cost, x0, args=(), bounds=None, xtol=1e-4, ftol=1e-4, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, direc=None, **kwds): """Minimize a function using modified Powell's method. Uses a modified Powell Directional Search algorithm to find the minimum of a function of one or more variables. This method only uses function values, not derivatives. Mimics the ``scipy.optimize.fmin_powell`` interface. Powell's method is a conjugate direction method that has two loops. The outer loop simply iterates over the inner loop, while the inner loop minimizes over each current direction in the direction set. At the end of the inner loop, if certain conditions are met, the direction that gave the largest decrease is dropped and replaced with the difference between the current estimated x and the estimated x from the beginning of the inner-loop. The conditions for replacing the direction of largest increase is that: (a) no further gain can be made along the direction of greatest increase in the iteration, and (b) the direction of greatest increase accounted for a large sufficient fraction of the decrease in the function value from the current iteration of the inner loop. Args: cost (func): the function or method to be minimized: ``y = cost(x)``. x0 (ndarray): the initial guess parameter vector ``x``. args (tuple, default=()): extra arguments for cost. bounds (list(tuple), default=None): list of pairs of bounds (min,max), one for each parameter. xtol (float, default=1e-4): acceptable relative error in ``xopt`` for convergence. ftol (float, default=1e-4): acceptable relative error in ``cost(xopt)`` for convergence. gtol (float, default=2): maximum iterations to run without improvement. maxiter (int, default=None): the maximum number of iterations to perform. maxfun (int, default=None): the maximum number of function evaluations. full_output (bool, default=False): True if fval and warnflag are desired. disp (bool, default=True): if True, print convergence messages. retall (bool, default=False): True if allvecs is desired. callback (func, default=None): function to call after each iteration. The interface is ``callback(xk)``, with xk the current parameter vector. direc (tuple, default=None): the initial direction set. handler (bool, default=False): if True, enable handling interrupt signals. itermon (monitor, default=None): override the default GenerationMonitor. evalmon (monitor, default=None): override the default EvaluationMonitor. constraints (func, default=None): a function ``xk' = constraints(xk)``, where xk is the current parameter vector, and xk' is a parameter vector that satisfies the encoded constraints. penalty (func, default=None): a function ``y = penalty(xk)``, where xk is the current parameter vector, and ``y' == 0`` when the encoded constraints are satisfied (and ``y' > 0`` otherwise). Returns: ``(xopt, {fopt, iter, funcalls, warnflag, direc}, {allvecs})`` Notes: - xopt (*ndarray*): the minimizer of the cost function - fopt (*float*): value of cost function at minimum: ``fopt = cost(xopt)`` - iter (*int*): number of iterations - funcalls (*int*): number of function calls - warnflag (*int*): warning flag: - ``1 : Maximum number of function evaluations`` - ``2 : Maximum number of iterations`` - direc (*tuple*): the current direction set - allvecs (*list*): a list of solutions at each iteration """ #FIXME: need to resolve "direc" # - should just pass 'direc', and then hands-off ? How return it ? #XXX: enable use of imax? handler = kwds['handler'] if 'handler' in kwds else False from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() gtol = 2 # termination generations (scipy: 2, default: 10) if 'gtol' in kwds: gtol = kwds['gtol'] if gtol: #if number of generations is provided, use NCOG from mystic.termination import NormalizedChangeOverGeneration as NCOG termination = NCOG(ftol, gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = PowellDirectionalSolver(len(x0)) solver.SetInitialPoints(x0) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb, maxb = unpair(bounds) solver.SetStrictRanges(minb, maxb) if handler: solver.enable_signal_handler() solver.Solve(cost, termination=termination, \ xtol=xtol, ExtraArgs=args, callback=callback, \ disp=disp, direc=direc) #XXX: last two lines use **kwds solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin_powell interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x direc = solver._direc if fcalls >= solver._maxfun: warnflag = 1 elif iterations >= solver._maxiter: warnflag = 2 x = squeeze(x) #FIXME: write squeezed x to stepmon instead? if full_output: retlist = x, fval, iterations, fcalls, warnflag, direc if retall: retlist += (allvecs, ) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def fmin(cost, x0, args=(), bounds=None, xtol=1e-4, ftol=1e-4, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, **kwds): """Minimize a function using the downhill simplex algorithm. Uses a Nelder-Mead simplex algorithm to find the minimum of a function of one or more variables. This algorithm only uses function values, not derivatives or second derivatives. Mimics the ``scipy.optimize.fmin`` interface. This algorithm has a long history of successful use in applications. It will usually be slower than an algorithm that uses first or second derivative information. In practice it can have poor performance in high-dimensional problems and is not robust to minimizing complicated functions. Additionally, there currently is no complete theory describing when the algorithm will successfully converge to the minimum, or how fast it will if it does. Both the ftol and xtol criteria must be met for convergence. Args: cost (func): the function or method to be minimized: ``y = cost(x)``. x0 (ndarray): the initial guess parameter vector ``x``. args (tuple, default=()): extra arguments for cost. bounds (list(tuple), default=None): list of pairs of bounds (min,max), one for each parameter. xtol (float, default=1e-4): acceptable absolute error in ``xopt`` for convergence. ftol (float, default=1e-4): acceptable absolute error in ``cost(xopt)`` for convergence. maxiter (int, default=None): the maximum number of iterations to perform. maxfun (int, default=None): the maximum number of function evaluations. full_output (bool, default=False): True if fval and warnflag are desired. disp (bool, default=True): if True, print convergence messages. retall (bool, default=False): True if allvecs is desired. callback (func, default=None): function to call after each iteration. The interface is ``callback(xk)``, with xk the current parameter vector. handler (bool, default=False): if True, enable handling interrupt signals. itermon (monitor, default=None): override the default GenerationMonitor. evalmon (monitor, default=None): override the default EvaluationMonitor. constraints (func, default=None): a function ``xk' = constraints(xk)``, where xk is the current parameter vector, and xk' is a parameter vector that satisfies the encoded constraints. penalty (func, default=None): a function ``y = penalty(xk)``, where xk is the current parameter vector, and ``y' == 0`` when the encoded constraints are satisfied (and ``y' > 0`` otherwise). Returns: ``(xopt, {fopt, iter, funcalls, warnflag}, {allvecs})`` Notes: - xopt (*ndarray*): the minimizer of the cost function - fopt (*float*): value of cost function at minimum: ``fopt = cost(xopt)`` - iter (*int*): number of iterations - funcalls (*int*): number of function calls - warnflag (*int*): warning flag: - ``1 : Maximum number of function evaluations`` - ``2 : Maximum number of iterations`` - allvecs (*list*): a list of solutions at each iteration """ handler = kwds['handler'] if 'handler' in kwds else False from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() if xtol: #if tolerance in x is provided, use CandidateRelativeTolerance from mystic.termination import CandidateRelativeTolerance as CRT termination = CRT(xtol, ftol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = NelderMeadSimplexSolver(len(x0)) solver.SetInitialPoints(x0) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb, maxb = unpair(bounds) solver.SetStrictRanges(minb, maxb) if handler: solver.enable_signal_handler() solver.Solve(cost, termination=termination, \ disp=disp, ExtraArgs=args, callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x if fcalls >= solver._maxfun: warnflag = 1 elif iterations >= solver._maxiter: warnflag = 2 if full_output: retlist = x, fval, iterations, fcalls, warnflag if retall: retlist += (allvecs, ) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def fmin_powell(cost, x0, args=(), bounds=None, xtol=1e-4, ftol=1e-4, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, direc=None, **kwds): """Minimize a function using modified Powell's method. Description: Uses a modified Powell Directional Search algorithm to find the minimum of function of one or more variables. Mimics the scipy.optimize.fmin_powell interface. Inputs: cost -- the Python function or method to be minimized. x0 -- ndarray - the initial guess. Additional Inputs: args -- extra arguments for cost. bounds -- list - n pairs of bounds (min,max), one pair for each parameter. xtol -- number - acceptable relative error in xopt for convergence. ftol -- number - acceptable relative error in cost(xopt) for convergence. gtol -- number - maximum number of iterations to run without improvement. maxiter -- number - the maximum number of iterations to perform. maxfun -- number - the maximum number of function evaluations. full_output -- number - non-zero if fval and warnflag outputs are desired. disp -- number - non-zero to print convergence messages. retall -- number - non-zero to return list of solutions at each iteration. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. direc -- initial direction set. handler -- boolean - enable/disable handling of interrupt signal. itermon -- monitor - override the default GenerationMonitor. evalmon -- monitor - override the default EvaluationMonitor. constraints -- an optional user-supplied function. It is called as constraints(xk), where xk is the current parameter vector. This function must return xk', a parameter vector that satisfies the encoded constraints. penalty -- an optional user-supplied function. It is called as penalty(xk), where xk is the current parameter vector. This function should return y', with y' == 0 when the encoded constraints are satisfied, and y' > 0 otherwise. Returns: (xopt, {fopt, iter, funcalls, warnflag, direc}, {allvecs}) xopt -- ndarray - minimizer of function fopt -- number - value of function at minimum: fopt = cost(xopt) iter -- number - number of iterations funcalls -- number - number of function calls warnflag -- number - Integer warning flag: 1 : 'Maximum number of function evaluations.' 2 : 'Maximum number of iterations.' direc -- current direction set allvecs -- list - a list of solutions at each iteration """ #FIXME: need to resolve "direc" # - should just pass 'direc', and then hands-off ? How return it ? handler = kwds['handler'] if 'handler' in kwds else False from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() gtol = 2 # termination generations (scipy: 2, default: 10) if 'gtol' in kwds: gtol = kwds['gtol'] if gtol: #if number of generations is provided, use NCOG from mystic.termination import NormalizedChangeOverGeneration as NCOG termination = NCOG(ftol,gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = PowellDirectionalSolver(len(x0)) solver.SetInitialPoints(x0) solver.SetEvaluationLimits(maxiter,maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb,maxb = unpair(bounds) solver.SetStrictRanges(minb,maxb) if handler: solver.enable_signal_handler() solver.Solve(cost, termination=termination, \ xtol=xtol, ExtraArgs=args, callback=callback, \ disp=disp, direc=direc) #XXX: last two lines use **kwds solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin_powell interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x direc = solver._direc if fcalls >= solver._maxfun: warnflag = 1 elif iterations >= solver._maxiter: warnflag = 2 x = squeeze(x) #FIXME: write squeezed x to stepmon instead? if full_output: retlist = x, fval, iterations, fcalls, warnflag, direc if retall: retlist += (allvecs,) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def fmin(cost, x0, args=(), bounds=None, xtol=1e-4, ftol=1e-4, maxiter=None, maxfun=None, full_output=0, disp=1, retall=0, callback=None, **kwds): """Minimize a function using the downhill simplex algorithm. Description: Uses a Nelder-Mead simplex algorithm to find the minimum of a function of one or more variables. Mimics the scipy.optimize.fmin interface. Inputs: cost -- the Python function or method to be minimized. x0 -- ndarray - the initial guess. Additional Inputs: args -- extra arguments for cost. bounds -- list - n pairs of bounds (min,max), one pair for each parameter. xtol -- number - acceptable relative error in xopt for convergence. ftol -- number - acceptable relative error in cost(xopt) for convergence. maxiter -- number - the maximum number of iterations to perform. maxfun -- number - the maximum number of function evaluations. full_output -- number - non-zero if fval and warnflag outputs are desired. disp -- number - non-zero to print convergence messages. retall -- number - non-zero to return list of solutions at each iteration. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. handler -- boolean - enable/disable handling of interrupt signal. itermon -- monitor - override the default GenerationMonitor. evalmon -- monitor - override the default EvaluationMonitor. constraints -- an optional user-supplied function. It is called as constraints(xk), where xk is the current parameter vector. This function must return xk', a parameter vector that satisfies the encoded constraints. penalty -- an optional user-supplied function. It is called as penalty(xk), where xk is the current parameter vector. This function should return y', with y' == 0 when the encoded constraints are satisfied, and y' > 0 otherwise. Returns: (xopt, {fopt, iter, funcalls, warnflag}, {allvecs}) xopt -- ndarray - minimizer of function fopt -- number - value of function at minimum: fopt = cost(xopt) iter -- number - number of iterations funcalls -- number - number of function calls warnflag -- number - Integer warning flag: 1 : 'Maximum number of function evaluations.' 2 : 'Maximum number of iterations.' allvecs -- list - a list of solutions at each iteration """ handler = kwds['handler'] if 'handler' in kwds else False from mystic.monitors import Monitor stepmon = kwds['itermon'] if 'itermon' in kwds else Monitor() evalmon = kwds['evalmon'] if 'evalmon' in kwds else Monitor() if xtol: #if tolerance in x is provided, use CandidateRelativeTolerance from mystic.termination import CandidateRelativeTolerance as CRT termination = CRT(xtol,ftol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) solver = NelderMeadSimplexSolver(len(x0)) solver.SetInitialPoints(x0) solver.SetEvaluationLimits(maxiter,maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if 'penalty' in kwds: solver.SetPenalty(kwds['penalty']) if 'constraints' in kwds: solver.SetConstraints(kwds['constraints']) if bounds is not None: minb,maxb = unpair(bounds) solver.SetStrictRanges(minb,maxb) if handler: solver.enable_signal_handler() solver.Solve(cost, termination=termination, \ disp=disp, ExtraArgs=args, callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x if fcalls >= solver._maxfun: warnflag = 1 elif iterations >= solver._maxiter: warnflag = 2 if full_output: retlist = x, fval, iterations, fcalls, warnflag if retall: retlist += (allvecs,) else: retlist = x if retall: retlist = (x, allvecs) return retlist
def diffev(cost,x0,npop=4,args=(),bounds=None,ftol=5e-3,gtol=None, maxiter=None,maxfun=None,cross=0.9,scale=0.8, full_output=0,disp=1,retall=0,callback=None,**kwds): """Minimize a function using differential evolution. Description: Uses a differential evolution algorith to find the minimum of a function of one or more variables. Mimics a scipy.optimize style interface. Inputs: cost -- the Python function or method to be minimized. x0 -- the initial guess (ndarray), if desired to start from a set point; otherwise takes an array of (min,max) bounds, for when random initial points are desired npop -- size of the trial solution population. Additional Inputs: args -- extra arguments for cost. bounds -- list - n pairs of bounds (min,max), one pair for each parameter. ftol -- number - acceptable relative error in cost(xopt) for convergence. gtol -- number - maximum number of iterations to run without improvement. maxiter -- number - the maximum number of iterations to perform. maxfun -- number - the maximum number of function evaluations. cross -- number - the probability of cross-parameter mutations scale -- number - multiplier for impact of mutations on trial solution. full_output -- number - non-zero if fval and warnflag outputs are desired. disp -- number - non-zero to print convergence messages. retall -- number - non-zero to return list of solutions at each iteration. callback -- an optional user-supplied function to call after each iteration. It is called as callback(xk), where xk is the current parameter vector. handler -- boolean - enable/disable handling of interrupt signal strategy -- strategy - override the default mutation strategy itermon -- monitor - override the default GenerationMonitor evalmon -- monitor - override the default EvaluationMonitor constraints -- an optional user-supplied function. It is called as constraints(xk), where xk is the current parameter vector. This function must return xk', a parameter vector that satisfies the encoded constraints. penalty -- an optional user-supplied function. It is called as penalty(xk), where xk is the current parameter vector. This function should return y', with y' == 0 when the encoded constraints are satisfied, and y' > 0 otherwise. Returns: (xopt, {fopt, iter, funcalls, warnflag}, {allvecs}) xopt -- ndarray - minimizer of function fopt -- number - value of function at minimum: fopt = cost(xopt) iter -- number - number of iterations funcalls -- number - number of function calls warnflag -- number - Integer warning flag: 1 : 'Maximum number of function evaluations.' 2 : 'Maximum number of iterations.' allvecs -- list - a list of solutions at each iteration """ invariant_current = False if kwds.has_key('invariant_current'): invariant_current = kwds['invariant_current'] handler = False if kwds.has_key('handler'): handler = kwds['handler'] from mystic.strategy import Best1Bin strategy = Best1Bin if kwds.has_key('strategy'): strategy = kwds['strategy'] from mystic.monitors import Monitor stepmon = Monitor() evalmon = Monitor() if kwds.has_key('itermon'): stepmon = kwds['itermon'] if kwds.has_key('evalmon'): evalmon = kwds['evalmon'] if gtol: #if number of generations provided, use ChangeOverGeneration from mystic.termination import ChangeOverGeneration termination = ChangeOverGeneration(ftol,gtol) else: from mystic.termination import VTRChangeOverGeneration termination = VTRChangeOverGeneration(ftol) ND = len(x0) if invariant_current: #use Solver2, not Solver1 solver = DifferentialEvolutionSolver2(ND,npop) else: solver = DifferentialEvolutionSolver(ND,npop) solver.SetEvaluationLimits(maxiter,maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) if kwds.has_key('penalty'): penalty = kwds['penalty'] solver.SetPenalty(penalty) if kwds.has_key('constraints'): constraints = kwds['constraints'] solver.SetConstraints(constraints) if bounds is not None: minb,maxb = unpair(bounds) solver.SetStrictRanges(minb,maxb) try: #x0 passed as 1D array of (min,max) pairs minb,maxb = unpair(x0) solver.SetRandomInitialPoints(minb,maxb) except: #x0 passed as 1D array of initial parameter values solver.SetInitialPoints(x0) if handler: solver.enable_signal_handler() #TODO: allow sigint_callbacks for all minimal interfaces ? solver.Solve(cost,termination=termination,strategy=strategy,\ #sigint_callback=other_callback,\ CrossProbability=cross,ScalingFactor=scale,\ ExtraArgs=args,callback=callback) solution = solver.Solution() # code below here pushes output to scipy.optimize.fmin interface #x = list(solver.bestSolution) x = solver.bestSolution fval = solver.bestEnergy warnflag = 0 fcalls = solver.evaluations iterations = solver.generations allvecs = stepmon.x if fcalls >= solver._maxfun: warnflag = 1 if disp: print "Warning: Maximum number of function evaluations has "\ "been exceeded." elif iterations >= solver._maxiter: warnflag = 2 if disp: print "Warning: Maximum number of iterations has been exceeded" else: if disp: print "Optimization terminated successfully." print " Current function value: %f" % fval print " Iterations: %d" % iterations print " Function evaluations: %d" % fcalls if full_output: retlist = x, fval, iterations, fcalls, warnflag if retall: retlist += (allvecs,) else: retlist = x if retall: retlist = (x, allvecs) return retlist