def mystic_optimize2(point): from mystic.monitors import Monitor, VerboseMonitor from mystic.tools import getch, random_seed random_seed(123) from mystic.solvers import DifferentialEvolutionSolver as de from mystic.termination import ChangeOverGeneration as COG NPOP = 50 simplex, esow = VerboseMonitor(50), Monitor() solver = de(len(point),NPOP) solver.SetInitialPoints(point) solver.SetEvaluationMonitor(esow) solver.SetGenerationMonitor(simplex) solver.Solve(cost_function, COG(generations=100), \ CrossProbability=0.5, ScalingFactor=0.5) solution = solver.Solution() return solution
def optimizeDE(cost, xmin, xmax, npop=40, maxiter=1000, maxfun=1e+6, convergence_tol=1e-5, ngen=100, crossover=0.9, percent_change=0.9, MINMAX=1, x0=[], radius=0.2, parallel=False, nodes=16): from mystic.solvers import DifferentialEvolutionSolver2 from mystic.termination import ChangeOverGeneration as COG from mystic.strategy import Best1Exp from mystic.monitors import VerboseMonitor, Monitor from pathos.helpers import freeze_support freeze_support() # help Windows use multiprocessing stepmon = VerboseMonitor(20) # step for showing live update evalmon = Monitor() ndim = len(xmin) solver = DifferentialEvolutionSolver2(ndim, npop) if parallel: solver.SetMapper(Pool(nodes).map) if x0 == []: solver.SetRandomInitialPoints(xmin, xmax) else: solver.SetInitialPoints(x0, radius) solver.SetStrictRanges(xmin, xmax) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) tol = convergence_tol solver.Solve(cost, termination=COG(tolerance=tol, generations=ngen), strategy=Best1Exp, CrossProbability=crossover, ScalingFactor=percent_change) solved = solver.bestSolution func_max = MINMAX * solver.bestEnergy func_evals = solver.evaluations return solved, func_max, func_evals
def test2(monitor, diffenv=None): if diffenv == True: #from mystic.solvers import DifferentialEvolutionSolver as DE from mystic.solvers import DifferentialEvolutionSolver2 as DE elif diffenv == False: from mystic.solvers import NelderMeadSimplexSolver as noDE else: from mystic.solvers import PowellDirectionalSolver as noDE from mystic.termination import ChangeOverGeneration as COG from mystic.tools import getch, random_seed random_seed(123) lb = [-100, -100, -100] ub = [1000, 1000, 1000] ndim = len(lb) npop = 5 maxiter = 10 maxfun = 1e+6 convergence_tol = 1e-10 ngen = 100 crossover = 0.9 percent_change = 0.9 def cost(x): ax, bx, c = x return (ax)**2 - bx + c if diffenv == True: solver = DE(ndim, npop) else: solver = noDE(ndim) solver.SetRandomInitialPoints(min=lb, max=ub) solver.SetStrictRanges(min=lb, max=ub) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(monitor) #solver.SetGenerationMonitor(monitor) tol = convergence_tol solver.Solve(cost, termination=COG(tol, ngen)) solved = solver.Solution() monitor.info("solved: %s" % solved) func_max = -solver.bestEnergy return solved, func_max
def optimize(cost,_bounds,_constraints): from mystic.solvers import DifferentialEvolutionSolver2 from mystic.termination import ChangeOverGeneration as COG from mystic.strategy import Best1Exp from mystic.monitors import VerboseMonitor, Monitor from mystic.tools import random_seed from mystic.termination import Or, CollapseWeight, CollapsePosition, state if debug: random_seed(123) # or 666 to force impose_unweighted reweighting stepmon = VerboseMonitor(1,1) else: stepmon = VerboseMonitor(10) if verbose else Monitor() stepmon._npts = npts evalmon = Monitor() lb,ub = _bounds ndim = len(lb) solver = DifferentialEvolutionSolver2(ndim,npop) solver.SetRandomInitialPoints(min=lb,max=ub) solver.SetStrictRanges(min=lb,max=ub) solver.SetEvaluationLimits(maxiter,maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) solver.SetConstraints(_constraints) tol = convergence_tol term = Or(COG(tol,ngen), CollapseWeight(), CollapsePosition()) solver.Solve(cost,termination=term,strategy=Best1Exp, disp=verbose, \ CrossProbability=crossover,ScalingFactor=percent_change) #while collapse and solver.Collapse(verbose): #XXX: total_evaluations? # if debug: print(state(solver._termination).keys()) # solver.Solve() #XXX: cost, term, strategy, cross, scale ? # if debug: solver.SaveSolver('debug.pkl') solved = solver.bestSolution #print("solved: %s" % solver.Solution()) func_max = MINMAX * solver.bestEnergy #NOTE: -solution assumes -Max #func_max = 1.0 + MINMAX*solver.bestEnergy #NOTE: 1-sol => 1-success = fail func_evals = solver.evaluations from mystic.munge import write_support_file write_support_file(stepmon, npts=npts) return solved, func_max, func_evals
def optimize(cost, _bounds, _constraints): from mystic.solvers import DifferentialEvolutionSolver2 from mystic.termination import ChangeOverGeneration as COG from mystic.strategy import Best1Exp from mystic.monitors import VerboseMonitor, Monitor from mystic.tools import random_seed #random_seed(123) stepmon = VerboseMonitor(2) #stepmon = Monitor() evalmon = Monitor() lb, ub = _bounds ndim = len(lb) solver = DifferentialEvolutionSolver2(ndim, npop) solver.SetRandomInitialPoints(min=lb, max=ub) solver.SetStrictRanges(min=lb, max=ub) solver.SetEvaluationLimits(maxiter, maxfun) solver.SetEvaluationMonitor(evalmon) solver.SetGenerationMonitor(stepmon) solver.SetConstraints(_constraints) tol = convergence_tol solver.Solve(cost,termination=COG(tol,ngen),strategy=Best1Exp, \ CrossProbability=crossover,ScalingFactor=percent_change) solved = solver.bestSolution #print("solved: %s" % solver.Solution()) func_max = MINMAX * solver.bestEnergy #NOTE: -solution assumes -Max #func_max = 1.0 + MINMAX*solver.bestEnergy #NOTE: 1-sol => 1-success = fail func_evals = solver.evaluations from mystic.munge import write_support_file write_support_file(stepmon, npts=npts) return solved, func_max, func_evals
def test_DifferentialEvolutionSolver2_COG(self): # Default for this solver from mystic.solvers import DifferentialEvolutionSolver2 from mystic.termination import ChangeOverGeneration as COG self.solver = DifferentialEvolutionSolver2(self.ND, self.NP) self.term = COG() self._run_solver()
def test_rosenbrock(): """Test the 2-dimensional Rosenbrock function. Testing 2-D Rosenbrock: Expected: x=[1., 1.] and f=0 Using DifferentialEvolutionSolver: Solution: [ 1.00000037 1.0000007 ] f value: 2.29478683682e-13 Iterations: 99 Function evaluations: 3996 Time elapsed: 0.582273006439 seconds Using DifferentialEvolutionSolver2: Solution: [ 0.99999999 0.99999999] f value: 3.84824937598e-15 Iterations: 100 Function evaluations: 4040 Time elapsed: 0.577210903168 seconds Using NelderMeadSimplexSolver: Solution: [ 0.99999921 1.00000171] f value: 1.08732211477e-09 Iterations: 70 Function evaluations: 130 Time elapsed: 0.0190329551697 seconds Using PowellDirectionalSolver: Solution: [ 1. 1.] f value: 0.0 Iterations: 28 Function evaluations: 859 Time elapsed: 0.113857030869 seconds """ print "Testing 2-D Rosenbrock:" print "Expected: x=[1., 1.] and f=0" from mystic.models import rosen as costfunc ndim = 2 lb = [-5.]*ndim ub = [5.]*ndim x0 = [2., 3.] maxiter = 10000 # DifferentialEvolutionSolver print "\nUsing DifferentialEvolutionSolver:" npop = 40 from mystic.solvers import DifferentialEvolutionSolver from mystic.termination import ChangeOverGeneration as COG from mystic.strategy import Rand1Bin esow = Monitor() ssow = Monitor() solver = DifferentialEvolutionSolver(ndim, npop) solver.SetInitialPoints(x0) solver.SetStrictRanges(lb, ub) solver.SetEvaluationLimits(generations=maxiter) solver.SetEvaluationMonitor(esow) solver.SetGenerationMonitor(ssow) term = COG(1e-10) time1 = time.time() # Is this an ok way of timing? solver.Solve(costfunc, term, strategy=Rand1Bin) sol = solver.Solution() time_elapsed = time.time() - time1 fx = solver.bestEnergy print "Solution: ", sol print "f value: ", fx print "Iterations: ", solver.generations print "Function evaluations: ", len(esow.x) print "Time elapsed: ", time_elapsed, " seconds" assert almostEqual(fx, 2.29478683682e-13, tol=3e-3) # DifferentialEvolutionSolver2 print "\nUsing DifferentialEvolutionSolver2:" npop = 40 from mystic.solvers import DifferentialEvolutionSolver2 from mystic.termination import ChangeOverGeneration as COG from mystic.strategy import Rand1Bin esow = Monitor() ssow = Monitor() solver = DifferentialEvolutionSolver2(ndim, npop) solver.SetInitialPoints(x0) solver.SetStrictRanges(lb, ub) solver.SetEvaluationLimits(generations=maxiter) solver.SetEvaluationMonitor(esow) solver.SetGenerationMonitor(ssow) term = COG(1e-10) time1 = time.time() # Is this an ok way of timing? solver.Solve(costfunc, term, strategy=Rand1Bin) sol = solver.Solution() time_elapsed = time.time() - time1 fx = solver.bestEnergy print "Solution: ", sol print "f value: ", fx print "Iterations: ", solver.generations print "Function evaluations: ", len(esow.x) print "Time elapsed: ", time_elapsed, " seconds" assert almostEqual(fx, 3.84824937598e-15, tol=3e-3) # NelderMeadSimplexSolver print "\nUsing NelderMeadSimplexSolver:" from mystic.solvers import NelderMeadSimplexSolver from mystic.termination import CandidateRelativeTolerance as CRT esow = Monitor() ssow = Monitor() solver = NelderMeadSimplexSolver(ndim) solver.SetInitialPoints(x0) solver.SetStrictRanges(lb, ub) solver.SetEvaluationLimits(generations=maxiter) solver.SetEvaluationMonitor(esow) solver.SetGenerationMonitor(ssow) term = CRT() time1 = time.time() # Is this an ok way of timing? solver.Solve(costfunc, term) sol = solver.Solution() time_elapsed = time.time() - time1 fx = solver.bestEnergy print "Solution: ", sol print "f value: ", fx print "Iterations: ", solver.generations print "Function evaluations: ", len(esow.x) print "Time elapsed: ", time_elapsed, " seconds" assert almostEqual(fx, 1.08732211477e-09, tol=3e-3) # PowellDirectionalSolver print "\nUsing PowellDirectionalSolver:" from mystic.solvers import PowellDirectionalSolver from mystic.termination import NormalizedChangeOverGeneration as NCOG esow = Monitor() ssow = Monitor() solver = PowellDirectionalSolver(ndim) solver.SetInitialPoints(x0) solver.SetStrictRanges(lb, ub) solver.SetEvaluationLimits(generations=maxiter) solver.SetEvaluationMonitor(esow) solver.SetGenerationMonitor(ssow) term = NCOG(1e-10) time1 = time.time() # Is this an ok way of timing? solver.Solve(costfunc, term) sol = solver.Solution() time_elapsed = time.time() - time1 fx = solver.bestEnergy print "Solution: ", sol print "f value: ", fx print "Iterations: ", solver.generations print "Function evaluations: ", len(esow.x) print "Time elapsed: ", time_elapsed, " seconds" assert almostEqual(fx, 0.0, tol=3e-3)
#from toys import function5x3 as toy; nx = 5; ny = 3 #from toys import cost5x1 as toy; nx = 5; ny = 1 #from toys import function5x1 as toy; nx = 5; ny = 1 #from toys import cost5 as toy; nx = 5; ny = None from toys import function5 as toy nx = 5 ny = None # update optimization parameters from misc import param, npts, wlb, wub, is_cons, scons from ouq import ExpectedValue from mystic.bounds import MeasureBounds from mystic.monitors import VerboseLoggingMonitor, Monitor, VerboseMonitor from mystic.termination import VTRChangeOverGeneration as VTRCOG from mystic.termination import Or, VTR, ChangeOverGeneration as COG param['opts']['termination'] = COG(1e-10, 100) #NOTE: short stop? param['npop'] = 80 #NOTE: increase if poor convergence param['stepmon'] = VerboseLoggingMonitor(1, 20, filename='log.txt', label='lower') # build bounds bnd = MeasureBounds((0, 1, 0, 0, 0)[:nx], (1, 10, 10, 10, 10)[:nx], n=npts[:nx], wlb=wlb[:nx], wub=wub[:nx]) # build a model representing 'truth', and generate some data #print("building truth F'(x|a')...") true = dict(mu=.01, sigma=0., zmu=-.01, zsigma=0.)
#!/usr/bin/env python # # Author: Mike McKerns (mmckerns @caltech and @uqfoundation) # Copyright (c) 2018-2022 The Uncertainty Quantification Foundation. # License: 3-clause BSD. The full license text is available at: # - https://github.com/uqfoundation/mystic/blob/master/LICENSE from mystic.solvers import DifferentialEvolutionSolver from mystic.models import rosen from mystic.tools import solver_bounds from mystic.termination import ChangeOverGeneration as COG, Or, CollapseCost from mystic.monitors import VerboseLoggingMonitor as Monitor solver = DifferentialEvolutionSolver(3, 40) solver.SetRandomInitialPoints([-100] * 3, [100] * 3) mon = Monitor(1) options = dict(limit=1.95, samples=50, clip=False) mask = {} #solver_bounds(solver) stop = Or(CollapseCost(mask=mask, **options), COG(generations=50)) solver.SetGenerationMonitor(mon) solver.SetTermination(stop) solver.SetObjective(rosen) solver.Solve() print(solver.Terminated(info=True)) print('%s @' % solver.bestEnergy) print(solver.bestSolution)
#!/usr/bin/env python # # Author: Mike McKerns (mmckerns @uqfoundation) # Copyright (c) 2020-2022 The Uncertainty Quantification Foundation. # License: 3-clause BSD. The full license text is available at: # - https://github.com/uqfoundation/mystic/blob/master/LICENSE """ misc user-defined items (solver configuration, moment constraints) """ from mystic.solvers import DifferentialEvolutionSolver2 from mystic.monitors import VerboseMonitor, Monitor from mystic.termination import ChangeOverGeneration as COG # kwds for solver opts = dict(termination=COG(1e-10, 100)) param = dict( solver=DifferentialEvolutionSolver2, npop=80, maxiter=1500, maxfun=1e+6, x0=None, # use RandomInitialPoints nested=None, # don't use SetNested pool=None, # don't use SetMapper stepmon=VerboseMonitor(1, label='output'), # monitor config evalmon=Monitor(), # monitor config (re-initialized in solve) # kwds to pass directly to Solve(objective, **opt) opts=opts, ) from mystic.math.discrete import product_measure from mystic.math import almostEqual as almost
#!/usr/bin/env python # # Author: Mike McKerns (mmckerns @uqfoundation) # Copyright (c) 2020-2022 The Uncertainty Quantification Foundation. # License: 3-clause BSD. The full license text is available at: # - https://github.com/uqfoundation/mystic/blob/master/LICENSE """ misc user-defined items (solver configuration, moment constraints) """ from mystic.solvers import DifferentialEvolutionSolver2 from mystic.monitors import VerboseMonitor, Monitor from mystic.termination import ChangeOverGeneration as COG # kwds for solver opts = dict(termination=COG(1e-6, 40), CrossProbability=0.9, ScalingFactor=0.9) param = dict( solver=DifferentialEvolutionSolver2, npop=10, #XXX:npop maxiter=1000, maxfun=1e+6, x0=None, # use RandomInitialPoints nested=None, # don't use SetNested pool=None, # don't use SetMapper stepmon=VerboseMonitor(1, label='output'), # monitor config evalmon=Monitor(), # monitor config (re-initialized in solve) # kwds to pass directly to Solve(objective, **opt) opts=opts, ) from mystic.math.discrete import product_measure from mystic.math import almostEqual as almost
def solve(measurements, method): """Find reasonable marker positions based on a set of measurements.""" print(method) marker_measurements = measurements if np.size(measurements) == 21: marker_measurements = measurements[(21 - 15) :] # m0 has known positions (0, 0, 0) # m1 has unknown x-position # All others have unknown xy-positions num_params = 0 + 1 + 2 + 2 + 2 + 2 bound = 400.0 lower_bound = [ 0.0, 0.0, 0.0, 0.0, 0.0, -bound, 0.0, -bound, 0.0, ] upper_bound = [ bound, bound, bound, bound, bound, bound, bound, bound, bound, ] def costx_no_nozzle(posvec): """Identical to cost_no_nozzle, except the shape of inputs""" positions = posvec2matrix_no_nozzle(posvec) return cost_no_nozzle(positions, marker_measurements) guess_0 = [0.0] * num_params intermediate_cost = 0.0 intermediate_solution = [] if method == "SLSQP": sol = scipy.optimize.minimize( costx_no_nozzle, guess_0, method="SLSQP", bounds=list(zip(lower_bound, upper_bound)), tol=1e-20, options={"disp": True, "ftol": 1e-40, "eps": 1e-10, "maxiter": 500}, ) intermediate_cost = sol.fun intermediate_solution = sol.x elif method == "L-BFGS-B": sol = scipy.optimize.minimize( costx_no_nozzle, guess_0, method="L-BFGS-B", bounds=list(zip(lower_bound, upper_bound)), options={"disp": True, "ftol": 1e-12, "gtol": 1e-12, "maxiter": 50000, "maxfun": 1000000}, ) intermediate_cost = sol.fun intermediate_solution = sol.x elif method == "PowellDirectionalSolver": from mystic.solvers import PowellDirectionalSolver from mystic.termination import Or, CollapseAt, CollapseAs from mystic.termination import ChangeOverGeneration as COG from mystic.monitors import VerboseMonitor from mystic.termination import VTR, And, Or solver = PowellDirectionalSolver(num_params) solver.SetRandomInitialPoints(lower_bound, upper_bound) solver.SetEvaluationLimits(evaluations=3200000, generations=100000) solver.SetTermination(Or(VTR(1e-25), COG(1e-10, 20))) solver.SetStrictRanges(lower_bound, upper_bound) solver.SetGenerationMonitor(VerboseMonitor(5)) solver.Solve(costx_no_nozzle) intermediate_cost = solver.bestEnergy intermediate_solution = solver.bestSolution elif method == "differentialEvolutionSolver": from mystic.solvers import DifferentialEvolutionSolver2 from mystic.monitors import VerboseMonitor from mystic.termination import VTR, ChangeOverGeneration, And, Or from mystic.strategy import Best1Exp, Best1Bin stop = Or(VTR(1e-18), ChangeOverGeneration(1e-9, 500)) npop = 3 stepmon = VerboseMonitor(100) solver = DifferentialEvolutionSolver2(num_params, npop) solver.SetEvaluationLimits(evaluations=3200000, generations=100000) solver.SetRandomInitialPoints(lower_bound, upper_bound) solver.SetStrictRanges(lower_bound, upper_bound) solver.SetGenerationMonitor(stepmon) solver.Solve( costx_no_nozzle, termination=stop, strategy=Best1Bin, ) intermediate_cost = solver.bestEnergy intermediate_solution = solver.bestSolution else: print("Method %s is not supported!" % method) sys.exit(1) print("Best intermediate cost: ", intermediate_cost) print("Best intermediate positions: \n%s" % posvec2matrix_no_nozzle(intermediate_solution)) if np.size(measurements) == 15: print("Got only 15 samples, so will not try to find nozzle position\n") return nozzle_measurements = measurements[: (21 - 15)] # Look for nozzle's xyz-offset relative to marker 0 num_params = 3 lower_bound = [ 0.0, 0.0, -bound, ] upper_bound = [bound, bound, 0.0] def costx_nozzle(posvec): """Identical to cost_nozzle, except the shape of inputs""" positions = posvec2matrix_nozzle(posvec, intermediate_solution) return cost_nozzle(positions, measurements) guess_0 = [0.0, 0.0, 0.0] final_cost = 0.0 final_solution = [] if method == "SLSQP": sol = scipy.optimize.minimize( costx_nozzle, guess_0, method="SLSQP", bounds=list(zip(lower_bound, upper_bound)), tol=1e-20, options={"disp": True, "ftol": 1e-40, "eps": 1e-10, "maxiter": 500}, ) final_cost = sol.fun final_solution = sol.x elif method == "L-BFGS-B": sol = scipy.optimize.minimize( costx_nozzle, guess_0, method="L-BFGS-B", bounds=list(zip(lower_bound, upper_bound)), options={"disp": True, "ftol": 1e-12, "gtol": 1e-12, "maxiter": 50000, "maxfun": 1000000}, ) final_cost = sol.fun final_solution = sol.x elif method == "PowellDirectionalSolver": from mystic.solvers import PowellDirectionalSolver from mystic.termination import Or, CollapseAt, CollapseAs from mystic.termination import ChangeOverGeneration as COG from mystic.monitors import VerboseMonitor from mystic.termination import VTR, And, Or solver = PowellDirectionalSolver(num_params) solver.SetRandomInitialPoints(lower_bound, upper_bound) solver.SetEvaluationLimits(evaluations=3200000, generations=100000) solver.SetTermination(Or(VTR(1e-25), COG(1e-10, 20))) solver.SetStrictRanges(lower_bound, upper_bound) solver.SetGenerationMonitor(VerboseMonitor(5)) solver.Solve(costx_nozzle) final_cost = solver.bestEnergy final_solution = solver.bestSolution elif method == "differentialEvolutionSolver": from mystic.solvers import DifferentialEvolutionSolver2 from mystic.monitors import VerboseMonitor from mystic.termination import VTR, ChangeOverGeneration, And, Or from mystic.strategy import Best1Exp, Best1Bin stop = Or(VTR(1e-18), ChangeOverGeneration(1e-9, 500)) npop = 3 stepmon = VerboseMonitor(100) solver = DifferentialEvolutionSolver2(num_params, npop) solver.SetEvaluationLimits(evaluations=3200000, generations=100000) solver.SetRandomInitialPoints(lower_bound, upper_bound) solver.SetStrictRanges(lower_bound, upper_bound) solver.SetGenerationMonitor(stepmon) solver.Solve( costx_nozzle, termination=stop, strategy=Best1Bin, ) final_cost = solver.bestEnergy final_solution = solver.bestSolution print("Best final cost: ", final_cost) print("Best final positions:") final = posvec2matrix_nozzle(final_solution, intermediate_solution)[1:] for num in range(0, 6): print( "{0: 8.3f} {1: 8.3f} {2: 8.3f} <!-- Marker {3} -->".format(final[num][0], final[num][1], final[num][2], num) )
def solve(constraints, guess=None, nvars=None, solver=None, \ lower_bounds=None, upper_bounds=None, termination=None): """Use optimization to find a solution to a set of constraints. Inputs: constraints -- a constraints solver function or a penalty function Additional Inputs: guess -- list of parameter values proposed to solve the constraints. lower_bounds -- list of lower bounds on solution values. upper_bounds -- list of upper bounds on solution values. nvars -- number of parameter values. solver -- the mystic solver to use in the optimization termination -- the mystic termination to use in the optimization NOTE: The resulting constraints will likely be more expensive to evaluate and less accurate than writing the constraints solver from scratch. NOTE: The ensemble solvers are available, using the default NestedSolver, where the keyword 'guess' can be used to set the number of solvers. NOTE: The default solver is 'diffev', with npop=min(40, ndim*5). The default termination is ChangeOverGeneration(), and the default guess is randomly selected points between the upper and lower bounds. """ npts = 8 if type(guess) is int: npts, guess = guess, None ndim = 1 #XXX: better, increase in while loop catching IndexError ? if nvars is not None: ndim = nvars elif guess is not None: ndim = len(guess) elif lower_bounds is not None: ndim = len(lower_bounds) elif upper_bounds is not None: ndim = len(upper_bounds) def cost(x): return 1. #XXX: don't allow solver string as a short-cut? #FIXME: add ensemble solvers ensemble = False if solver is None or solver == 'diffev': from mystic.solvers import DifferentialEvolutionSolver as TheSolver solver = TheSolver(ndim, min(40, ndim * 5)) elif solver == 'diffev2': from mystic.solvers import DifferentialEvolutionSolver2 as TheSolver solver = TheSolver(ndim, min(40, ndim * 5)) elif solver == 'fmin_powell': #XXX: better as the default? (it's not random) from mystic.solvers import PowellDirectionalSolver as TheSolver solver = TheSolver(ndim) elif solver == 'fmin': from mystic.solvers import NelderMeadSimplexSolver as TheSolver solver = TheSolver(ndim) elif solver == 'buckshot': from mystic.solvers import BuckshotSolver as TheSolver solver = TheSolver(ndim, max(8, npts)) #XXX: needs better default? ensemble = True elif solver == 'lattice': from mystic.solvers import LatticeSolver as TheSolver solver = TheSolver(ndim, max(8, npts)) #XXX: needs better default? ensemble = True if termination is None: from mystic.termination import ChangeOverGeneration as COG termination = COG() if not ensemble: if guess is not None: solver.SetInitialPoints(guess) #XXX: nice if 'diffev' had methods else: solver.SetRandomInitialPoints(lower_bounds, upper_bounds) if lower_bounds or upper_bounds: solver.SetStrictRanges(lower_bounds, upper_bounds) if hasattr(constraints, 'iter') and hasattr(constraints, 'error'): solver.SetPenalty(constraints) #i.e. is a penalty function else: # is a constraints solver solver.SetConstraints(constraints) from numpy import seterr settings = seterr(all='ignore') solver.Solve(cost, termination) seterr(**settings) soln = solver.bestSolution from numpy import ndarray, array if isinstance(soln, ndarray) and not isinstance(guess, ndarray): soln = soln.tolist() elif isinstance(guess, ndarray) and not isinstance(soln, ndarray): soln = array(soln) #XXX: or always return a list ? return soln #XXX: check with 'issolution' ?
def solve(samp, xyz_of_samp, _cost, method, cx_is_positive=False): """Find reasonable positions and anchors given a set of samples. """ u = np.shape(samp)[0] ux = np.shape(xyz_of_samp)[0] number_of_params_pos = 3*(u - ux) def costx(posvec, anchvec): """Identical to cost, except the shape of inputs and capture of samp, xyz_of_samp, ux, and u Parameters ---------- x : [A_ay A_az A_bx A_by A_bz A_cx A_cy A_cz A_dz x1 y1 z1 x2 y2 z2 ... xu yu zu """ anchors = anchorsvec2matrix(anchvec) pos = np.zeros((u, 3)) if(np.size(xyz_of_samp) != 0): pos[0:ux] = xyz_of_samp pos[ux:] = np.reshape(posvec, (u-ux,3)) return _cost(anchors, pos, samp) l_long = 5000.0 l_short = 1700.0 data_z_min = -20.0 # Limits of anchor positions: # |ANCHOR_XY| < 4000 # ANCHOR_B_X > 0 # ANCHOR_C_X < 0 # |ANCHOR_ABC_Z| < 1700 # 0 < ANCHOR_D_Z < 4000 # Limits of data collection volume: # |x| < 1700 # |y| < 1700 # -20.0 < z < 3400.0 # Define bounds lb = [ -l_long, # A_ay > -4000.0 -l_short, # A_az > -1700.0 0.0, # A_bx > 0 0.0, # A_by > 0 -l_short, # A_bz > -1700.0 -l_long, # A_cx > -4000 0.0, # A_cy > 0 -l_short, # A_cz > -1700.0 0.0, # A_dz > 0 ] + [-l_short, -l_short, data_z_min]*(u-ux) ub = [ 0.0, # A_ay < 0 l_short, # A_az < 1700 l_long, # A_bx < 4000 l_long, # A_by < 4000 l_short, # A_bz < 1700 0.0, # A_cx < 0 l_long, # A_cy < 4000.0 l_short, # A_cz < 1700 l_long, # A_dz < 4000.0 ] + [l_short, l_short, 2*l_short]*(u-ux) # If the user has input xyz data, then signs should be ok anyways if(ux > 2): lb[A_bx] = -l_long # It would work to just swap the signs of bx and cx after the optimization # But there are fewer assumptions involved in setting correct bounds from the start instead if(cx_is_positive): tmp = lb[A_bx] lb[A_bx] = lb[A_cx] lb[A_cx] = tmp tmp = ub[A_bx] ub[A_bx] = ub[A_cx] ub[A_cx] = tmp pos_est0 = np.zeros((u-ux,3)) # The positions we need to estimate anchors_est = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]) x_guess0 = list(anchorsmatrix2vec(anchors_est)) + list(posmatrix2vec(pos_est0)) if(method == 'PowellDirectionalSolver'): from mystic.termination import ChangeOverGeneration, NormalizedChangeOverGeneration, VTR from mystic.solvers import PowellDirectionalSolver from mystic.termination import Or, CollapseAt, CollapseAs from mystic.termination import ChangeOverGeneration as COG target = 1.0 term = Or((COG(generations=100), CollapseAt(target, generations=100))) # Solver 0 solver0 = PowellDirectionalSolver(number_of_params_pos+params_anch) solver0.SetEvaluationLimits(evaluations=3200000, generations=10000) solver0.SetTermination(term) solver0.SetInitialPoints(x_guess0) solver0.SetStrictRanges(lb, ub) solver0.Solve(lambda x: costx(x[params_anch:], x[0:params_anch])) x_guess0 = solver0.bestSolution # PowellDirectional sometimes finds new ways if kickstarted anew for i in range(1,20): solver0 = PowellDirectionalSolver(number_of_params_pos+params_anch) solver0.SetInitialPoints(x_guess0) solver0.SetStrictRanges(lb, ub) solver0.Solve(lambda x: costx(x[params_anch:], x[0:params_anch])) x_guess0 = solver0.bestSolution return x_guess0 elif(method == 'SLSQP'): # 'SLSQP' is crazy fast and lands on 0.0000 error x_guess0 = scipy.optimize.minimize(lambda x: costx(x[params_anch:], x[0:params_anch]), x_guess0, method=method, bounds=list(zip(lb,ub)), options={'disp':True,'ftol':1e-20, 'maxiter':150000}) return x_guess0.x elif(method == 'L-BFGS-B'): ## 'L-BFGS-B' Is crazy fast but doesn't quite land at 0.0000 error x_guess0 = scipy.optimize.minimize(lambda x: costx(x[params_anch:], x[0:params_anch]), x_guess0, method=method, bounds=list(zip(lb,ub)), options={'ftol':1e-12, 'maxiter':150000}) return x_guess0.x else: print("Method %s is not supported!" % method) sys.exit(1)
def test_NelderMeadSimplexSolver_COG(self): from mystic.solvers import NelderMeadSimplexSolver from mystic.termination import ChangeOverGeneration as COG self.solver = NelderMeadSimplexSolver(self.ND) self.term = COG() self._run_solver()
from mystic.termination import ChangeOverGeneration as COG # update termination condition with new masks ## termination should be Or(*conditions), where ## conditions are: COG(), Collapse*(), and possibly others. # takes termination condition (or solver?) and returns termination condition # also requires updated masks as input verbose = True #False #from mystic.models import rosen as model; target = 1.0 from mystic.models import sphere as model target = 0.0 n = 10 #term = Or((COG(generations=300), CollapseAt(None, generations=100), CollapseAs(generations=100))) term = Or((COG(generations=500), CollapseAt(target, generations=100))) #term = COG(generations=500) from mystic.solvers import DifferentialEvolutionSolver as TheSolver #from mystic.solvers import PowellDirectionalSolver as TheSolver from mystic.solvers import BuckshotSolver #solver = BuckshotSolver(n, 10) solver = TheSolver(n) solver.SetRandomInitialPoints() solver.SetStrictRanges(min=[0] * n, max=[5] * n) solver.SetEvaluationLimits(evaluations=320000, generations=1000) solver.SetTermination(term) #from mystic.termination import state #print state(solver._termination).keys() solver.Solve(model, disp=verbose)
def test_PowellDirectionalSolver_COG(self): from mystic.solvers import PowellDirectionalSolver from mystic.termination import ChangeOverGeneration as COG self.solver = PowellDirectionalSolver(self.ND) self.term = COG() self._run_solver()
def solve(constraints, guess=None, nvars=None, solver=None, \ lower_bounds=None, upper_bounds=None, termination=None): """Use optimization to find a solution to a set of constraints. Inputs: constraints -- a constraints solver function or a penalty function Additional Inputs: guess -- list of parameter values proposed to solve the constraints. lower_bounds -- list of lower bounds on solution values. upper_bounds -- list of upper bounds on solution values. nvars -- number of parameter values. solver -- the mystic solver to use in the optimization termination -- the mystic termination to use in the optimization NOTE: The resulting constraints will likely be more expensive to evaluate and less accurate than writing the constraints solver from scratch. """ ndim = 1 #XXX: better, increase in while loop catching IndexError ? if nvars is not None: ndim = nvars elif guess is not None: ndim = len(guess) elif lower_bounds is not None: ndim = len(lower_bounds) elif upper_bounds is not None: ndim = len(upper_bounds) def cost(x): return 1. #XXX: don't allow solver string as a short-cut? if solver is None or solver == 'diffev': from mystic.solvers import DifferentialEvolutionSolver as TheSolver solver = TheSolver(ndim, min(40, ndim * 5)) elif solver == 'diffev2': from mystic.solvers import DifferentialEvolutionSolver2 as TheSolver solver = TheSolver(ndim, min(40, ndim * 5)) elif solver == 'fmin_powell': #XXX: better as the default? (it's not random) from mystic.solvers import PowellDirectionalSolver as TheSolver solver = TheSolver(ndim) elif solver == 'fmin': from mystic.solvers import NelderMeadSimplexSolver as TheSolver solver = TheSolver(ndim) if termination is None: from mystic.termination import ChangeOverGeneration as COG termination = COG() if guess != None: solver.SetInitialPoints(guess) #XXX: nice if 'diffev' also had methods else: solver.SetRandomInitialPoints(lower_bounds, upper_bounds) if lower_bounds or upper_bounds: solver.SetStrictRanges(lower_bounds, upper_bounds) if hasattr(constraints, 'iter') and hasattr(constraints, 'error'): solver.SetPenalty(constraints) #i.e. is a penalty function else: # is a constraints solver solver.SetConstraints(constraints) solver.Solve(cost, termination) soln = solver.bestSolution from numpy import ndarray, array if isinstance(soln, ndarray) and not isinstance(guess, ndarray): soln = soln.tolist() elif isinstance(guess, ndarray) and not isinstance(soln, ndarray): soln = array(soln) #XXX: or always return a list ? return soln #XXX: check with 'issolution' ?