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 runme(): # instantiate the solver _solver = NelderMeadSimplexSolver(3) lb, ub = [0., 0., 0.], [10., 10., 10.] _solver.SetRandomInitialPoints(lb, ub) _solver.SetEvaluationLimits(1000) # add a monitor stream stepmon = VerboseMonitor(1) _solver.SetGenerationMonitor(stepmon) # configure the bounds _solver.SetStrictRanges(lb, ub) # configure stop conditions term = Or(VTR(), ChangeOverGeneration()) _solver.SetTermination(term) # add a periodic dump to an archive tmpfile = 'mysolver.pkl' _solver.SetSaveFrequency(10, tmpfile) # run the optimizer _solver.Solve(rosen) # get results x = _solver.bestSolution y = _solver.bestEnergy # load the saved solver solver = LoadSolver(tmpfile) #os.remove(tmpfile) # obligatory check that state is the same assert all(x == solver.bestSolution) assert y == solver.bestEnergy # modify the termination condition term = VTR(0.0001) solver.SetTermination(term) # run the optimizer solver.Solve(rosen) os.remove(tmpfile) # check the solver serializes _s = dill.dumps(solver) return dill.loads(_s)
@suppressed(1e-2) def conserve(x): return constrain(x) from mystic.monitors import VerboseMonitor mon = VerboseMonitor(10) # solve the dual for alpha from mystic.solvers import DifferentialEvolutionSolver as DESolver from mystic.termination import Or, ChangeOverGeneration, CollapseAt ndim = len(lb) npop = nx * 3 stop = Or(ChangeOverGeneration(1e-8, 200), CollapseAt(0.0)) solver = DESolver(ndim, npop) solver.SetRandomInitialPoints(min=lb, max=_b) solver.SetStrictRanges(min=lb, max=ub) solver.SetGenerationMonitor(mon) solver.SetConstraints(conserve) solver.SetTermination(stop) solver.Solve(objective, ExtraArgs=(Q, b), disp=1) alpha = solver.bestSolution print 'solved x: ', alpha print "constraint A*x == 0: ", inner(Aeq, alpha) print "minimum 0.5*x'Qx + b'*x: ", solver.bestEnergy # calculate weight vectors, support vectors, and bias wv = WeightVector(alpha, X, y)
assert solver._state == None assert LoadSolver(solver._state) == None solver = DifferentialEvolutionSolver(3, 40) solver.SetRandomInitialPoints([0., 0., 0.], [10., 10., 10.]) term = When(VTR()) solver.SetSaveFrequency(10, tmpfile) solver.SetTermination(term) solver.Solve(rosen) x = solver.bestSolution y = solver.bestEnergy _solver = LoadSolver(tmpfile) os.remove(tmpfile) assert all(x == _solver.bestSolution) assert y == _solver.bestEnergy solver = DifferentialEvolutionSolver(3, 40) solver.SetRandomInitialPoints([0., 0., 0.], [10., 10., 10.]) term = Or(VTR(), ChangeOverGeneration()) solver.SetSaveFrequency(10, tmpfile) solver.SetTermination(term) solver.Solve(rosen) x = solver.bestSolution y = solver.bestEnergy _solver = LoadSolver(tmpfile) os.remove(tmpfile) assert all(x == _solver.bestSolution) assert y == _solver.bestEnergy # EOF
#!/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)
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 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 test_me(info='self'): from mystic.solvers import DifferentialEvolutionSolver s = DifferentialEvolutionSolver(4, 4) from mystic.termination import VTR from mystic.termination import ChangeOverGeneration from mystic.termination import NormalizedChangeOverGeneration v = VTR() c = ChangeOverGeneration() n = NormalizedChangeOverGeneration() if disp: print("define conditions...") _v = When(v) _c = When(c) _n = When(n) v_and_c = And(v, c) v_and_n = And(v, n) v_or_c = Or(v, c) v_or_n = Or(v, n) v_and_c__or_n = Or(v_and_c, _n) v_and_c__or_c = Or(v_and_c, _c) v_and_n__or_n = Or(v_and_n, _n) c_and_v = And(c, v) c_or_v = Or(c, v) c_or__c_and_v = Or(_c, c_and_v) assert len(_v) == len(_c) == len(_n) == 1 assert list(_v).index(v) == list(_c).index(c) == list(_n).index(n) == 0 assert list(_v).count(v) == list(_c).count(c) == list(_n).count(n) == 1 assert v in _v and c in _c and n in _n assert v in v_and_c and c in v_and_c assert v in v_and_n and n in v_and_n assert v in v_or_c and c in v_or_c assert v in v_or_n and n in v_or_n assert len(v_and_c) == len(v_and_n) == len(v_or_c) == len(v_or_n) == 2 assert len(v_and_c__or_n) == len(v_and_c__or_c) == len(v_and_n__or_n) == 2 assert v not in v_and_c__or_n and c not in v_and_c__or_n and n not in v_and_c__or_n assert v_and_c in v_and_c__or_n and _n in v_and_c__or_n assert v_and_c in v_and_c__or_c and _c in v_and_c__or_c assert v_and_n in v_and_n__or_n and _n in v_and_n__or_n assert c in c_and_v and v in c_and_v assert c in c_or_v and v in c_or_v assert list(c_and_v).index(c) == list(v_and_c).index(v) assert list(c_and_v).index(v) == list(v_and_c).index(c) assert list(c_or_v).index(c) == list(v_or_c).index(v) assert list(c_or_v).index(v) == list(v_or_c).index(c) assert c_and_v in c_or__c_and_v and _c in c_or__c_and_v if disp: print("_v:%s" % _v) print("_c:%s" % _c) print("_n:%s" % _n) print("v_and_c:%s" % v_and_c) print("v_and_n:%s" % v_and_n) print("v_or_c:%s" % v_or_c) print("v_or_n:%s" % v_or_n) print("v_and_c__or_n:%s" % v_and_c__or_n) print("v_and_c__or_c:%s" % v_and_c__or_c) print("v_and_n__or_n:%s" % v_and_n__or_n) print("c_and_v:%s" % c_and_v) print("c_or_v:%s" % c_or_v) print("c_or__c_and_v:%s" % c_or__c_and_v) if disp: print("initial conditions...") _v_and_c = v_and_c(s, info) _v_and_n = v_and_n(s, info) _v_or_c = v_or_c(s, info) _v_or_n = v_or_n(s, info) assert not _v_and_c assert not _v_and_n assert not _v_or_c assert not _v_or_n if disp: print("v_and_c:%s" % _v_and_c) print("v_and_n:%s" % _v_and_n) print("v_or_c:%s" % _v_or_c) print("v_or_n:%s" % _v_or_n) if disp: print("after convergence toward zero...") s.energy_history = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # _v and _n are True, _c is False _v_and_c = v_and_c(s, info) _v_and_n = v_and_n(s, info) _v_or_c = v_or_c(s, info) _v_or_n = v_or_n(s, info) assert not _v_and_c assert _v_and_n assert _v_or_c assert _v_or_n if info == 'self': assert v in _v_and_n and n in _v_and_n assert v in _v_or_c and c not in _v_or_c assert v in _v_or_n and n in _v_or_n if disp: print("v_and_c:%s" % _v_and_c) print("v_and_n:%s" % _v_and_n) print("v_or_c:%s" % _v_or_c) print("v_or_n:%s" % _v_or_n) if disp: print("nested compound termination...") # _v and _n are True, _c is False _v_and_c__or_n = v_and_c__or_n(s, info) _v_and_c__or_c = v_and_c__or_c(s, info) _v_and_n__or_n = v_and_n__or_n(s, info) assert _v_and_c__or_n assert not _v_and_c__or_c assert _v_and_n__or_n if info == 'self': assert _n in _v_and_c__or_n and v_and_c not in _v_and_c__or_n assert v not in _v_and_c__or_n and c not in _v_and_c__or_n assert v_and_n in _v_and_n__or_n and _n in _v_and_n__or_n assert v not in _v_and_n__or_n and n not in _v_and_n__or_n if disp: print("v_and_c__or_n:%s" % _v_and_c__or_n) print("v_and_c__or_c:%s" % _v_and_c__or_c) print("v_and_n__or_n:%s" % _v_and_n__or_n) if disp: print("individual conditions...") __v = _v(s, info) __c = _c(s, info) __n = _n(s, info) assert __v and __n assert not __c if info == 'self': assert v in __v and n in __n if disp: print("v:%s" % __v) print("c:%s" % __c) print("n:%s" % __n) if disp: print("conditions with false first...") _c_and_v = c_and_v(s, info) _c_or_v = c_or_v(s, info) _c_or__c_and_v = c_or__c_and_v(s, info) assert not _c_and_v assert _c_or_v assert not _c_or__c_and_v if info == 'self': assert v in _c_or_v and c not in _c_or_v if disp: print("c_and_v:%s" % _c_and_v) print("c_or_v:%s" % _c_or_v) print("c_or__c_and_v:%s" % _c_or__c_and_v)
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)