def all_constraints(self, x=None): """Returns both the inequality and equality constraint values for your function Assumptions: N/A Source: N/A Inputs: x [vector] Outputs: scaled_constraints [vector] Properties Used: None """ self.evaluate(x) aliases = self.optimization_problem.aliases constraints = self.optimization_problem.constraints results = self.results constraint_values = help_fun.get_values(self, constraints, aliases) scaled_constraints = help_fun.scale_const_values( constraints, constraint_values) return scaled_constraints
def inequality_constraint(self, x=None): """Retrieve the inequality constraint values for your function Assumptions: N/A Source: N/A Inputs: x [vector] Outputs: scaled_constraints [vector] Properties Used: None """ self.evaluate(x) aliases = self.optimization_problem.aliases constraints = self.optimization_problem.constraints results = self.results # Setup constraints indices = [] for ii in xrange(0, len(constraints)): if constraints[ii][1] == ('='): indices.append(ii) iqconstraints = np.delete(constraints, indices, axis=0) if iqconstraints == []: scaled_constraints = [] else: constraint_values = help_fun.get_values(self, iqconstraints, aliases) constraint_values[iqconstraints[:, 1] == '<'] = -constraint_values[ iqconstraints[:, 1] == '<'] bnd_constraints = constraint_values - help_fun.scale_const_bnds( iqconstraints) scaled_constraints = help_fun.scale_const_values( iqconstraints, constraint_values) return scaled_constraints
def pyopt_surrogate_setup(surrogate_function, inputs, constraints): """ sets up a surrogate problem so it can be run by pyOpt. Makes the problem to be run Assumptions: None Source: N/A Inputs: surrogate_function [nexus()] inputs [array] constraints [array] Outputs: opt_problem [pyOpt problem] Properties Used: None """ #taken from initial optimization problem that you set up ini = inputs[:, 1] # values bnd = inputs[:, 2] # Bounds scl = inputs[:, 3] # Scaling input_units = inputs[:, -1] * 1.0 constraint_scale = constraints[:, 3] constraint_units = constraints[:, -1] * 1.0 import pyOpt #use pyOpt to set up the problem opt_problem = pyOpt.Optimization('surrogate', surrogate_function) #constraints bnd_constraints = helper_functions.scale_const_bnds(constraints) scaled_constraints = helper_functions.scale_const_values( constraints, bnd_constraints) constraints_out = scaled_constraints * constraint_units scaled_inputs = ini / scl x = scaled_inputs #*input_units print 'x_setup=', x #bound the input variables for j in range(len(inputs[:, 1])): lbd = bnd[j][0] / (scl[j]) #*input_units[j] ubd = bnd[j][1] / (scl[j]) #*input_units[j] opt_problem.addVar('x%i' % j, 'c', lower=lbd, upper=ubd, value=x[j]) #put in the constraints for j in range(len(constraints[:, 0])): edge = constraints_out[j] if constraints[j][1] == '<': opt_problem.addCon('g%i' % j, type='i', upper=edge) elif constraints[j][1] == '>': opt_problem.addCon('g%i' % j, lower=edge, upper=np.inf) elif constraints[j][1] == '>': opt_problem.addCon('g%i' % j, type='e', equal=edge) opt_problem.addObj('f') return opt_problem
def scale_vals(self, inp, con, ini, bnd, scl): """Scales values to help setup the problem Assumptions: N/A Source: N/A Inputs: inp [array] con [array] ini [array] bnd [array] scl [array] Outputs: tuple: x [array] scaled_constraints [array] x_low_bounds [array] x_up_bounds [array] con_up_edge [array] con_low_edge [array] Properties Used: N/A """ # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con, bnd_constraints) x = ini / scl x_low_bound = [] x_up_bound = [] edge = [] con_up_edge = [] con_low_edge = [] for ii in range(0, len(inp)): x_low_bound.append(bnd[ii][0] / scl[ii]) x_up_bound.append(bnd[ii][1] / scl[ii]) for ii in range(0, len(con)): edge.append(scaled_constraints[ii]) if con[ii][1] == '<': con_up_edge.append(edge[ii]) con_low_edge.append(-np.inf) elif con[ii][1] == '>': con_up_edge.append(np.inf) con_low_edge.append(edge[ii]) elif con[ii][1] == '=': con_up_edge.append(edge[ii]) con_low_edge.append(edge[ii]) x_low_bound = np.array(x_low_bound) x_up_bound = np.array(x_up_bound) con_up_edge = np.array(con_up_edge) con_low_edge = np.array(con_low_edge) return (x, scaled_constraints, x_low_bound, x_up_bound, con_up_edge, con_low_edge)
def scale_vals(self,inp,con,ini,bnd,scl): """Scales inputs, constraints, and their bounds. Assumptions: None Source: N/A Inputs: (all SUAVE format specific numpy arrays) inp Design variables con Constraint limits ini Initial values bnd Variable bounds scl Scaling factors Outputs: x <numpy array> Scaled design variables scaled_constraints <numpy array> x_low_bound <numpy array> x_up_bound <numpy array> con_up_edge <numpy array> con_low_edge <numpy array> name <list of strings> List of variable names Properties Used: None """ # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con,bnd_constraints) x = ini/scl x_low_bound = [] x_up_bound = [] edge = [] name = [] con_up_edge = [] con_low_edge = [] for ii in range(0,len(inp)): x_low_bound.append(bnd[ii][0]/scl[ii]) x_up_bound.append(bnd[ii][1]/scl[ii]) for ii in range(0,len(con)): name.append(con[ii][0]) edge.append(scaled_constraints[ii]) if con[ii][1]=='<': con_up_edge.append(edge[ii]) con_low_edge.append(-np.inf) elif con[ii][1]=='>': con_up_edge.append(np.inf) con_low_edge.append(edge[ii]) elif con[ii][1]=='=': con_up_edge.append(edge[ii]) con_low_edge.append(edge[ii]) x_low_bound = np.array(x_low_bound) x_up_bound = np.array(x_up_bound) con_up_edge = np.array(con_up_edge) con_low_edge = np.array(con_low_edge) return (x,scaled_constraints,x_low_bound,x_up_bound,con_up_edge,con_low_edge,name)
def pyopt_surrogate_setup(surrogate_function, inputs, constraints): """ sets up a surrogate problem so it can be run by pyOpt. Makes the problem to be run Assumptions: None Source: N/A Inputs: surrogate_function [nexus()] inputs [array] constraints [array] Outputs: opt_problem [pyOpt problem] Properties Used: None """ #taken from initial optimization problem that you set up ini = inputs[:,1] # values bnd = inputs[:,2] # Bounds scl = inputs[:,3] # Scaling input_units = inputs[:,-1] *1.0 constraint_scale = constraints[:,3] constraint_units = constraints[:,-1]*1.0 import pyOpt #use pyOpt to set up the problem opt_problem = pyOpt.Optimization('surrogate', surrogate_function) #constraints bnd_constraints = helper_functions.scale_const_bnds(constraints) scaled_constraints = helper_functions.scale_const_values(constraints,bnd_constraints) constraints_out = scaled_constraints*constraint_units scaled_inputs = ini/scl x = scaled_inputs#*input_units print 'x_setup=', x #bound the input variables for j in range(len(inputs[:,1])): lbd = bnd[j][0]/(scl[j])#*input_units[j] ubd = bnd[j][1]/(scl[j])#*input_units[j] opt_problem.addVar('x%i' % j, 'c', lower = lbd, upper = ubd, value = x[j]) #put in the constraints for j in range(len(constraints[:,0])): edge = constraints_out[j] if constraints[j][1]=='<': opt_problem.addCon('g%i' % j, type ='i', upper=edge) elif constraints[j][1]=='>': opt_problem.addCon('g%i' % j, lower=edge,upper=np.inf) elif constraints[j][1]=='>': opt_problem.addCon('g%i' % j, type='e', equal=edge) opt_problem.addObj('f') return opt_problem
def Pyoptsparse_Solve(problem, solver='SNOPT', FD='single', sense_step=1.0E-6, nonderivative_line_search=False): """ This converts your SUAVE Nexus problem into a PyOptsparse optimization problem and solves it. Pyoptsparse has many algorithms, they can be switched out by using the solver input. Assumptions: None Source: N/A Inputs: problem [nexus()] solver [str] FD (parallel or single) [str] sense_step [float] nonderivative_line_search [bool] Outputs: outputs [list] Properties Used: None """ # Have the optimizer call the wrapper mywrap = lambda x: PyOpt_Problem(problem, x) inp = problem.optimization_problem.inputs obj = problem.optimization_problem.objective con = problem.optimization_problem.constraints if FD == 'parallel': from mpi4py import MPI comm = MPI.COMM_WORLD myrank = comm.Get_rank() # Instantiate the problem and set objective try: import pyoptsparse as pyOpt except: raise ImportError('No version of pyOptsparse found') opt_prob = pyOpt.Optimization('SUAVE', mywrap) for ii in range(len(obj)): opt_prob.addObj(obj[ii, 0]) # Set inputs nam = inp[:, 0] # Names ini = inp[:, 1] # Initials bnd = inp[:, 2] # Bounds scl = inp[:, 3] # Scale typ = inp[:, 4] # Type # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con, bnd_constraints) x = ini / scl for ii in range(0, len(inp)): lbd = (bnd[ii][0] / scl[ii]) ubd = (bnd[ii][1] / scl[ii]) #if typ[ii] == 'continuous': vartype = 'c' #if typ[ii] == 'integer': #vartype = 'i' opt_prob.addVar(nam[ii], vartype, lower=lbd, upper=ubd, value=x[ii]) # Setup constraints for ii in range(0, len(con)): name = con[ii][0] edge = scaled_constraints[ii] if con[ii][1] == '<': opt_prob.addCon(name, upper=edge) elif con[ii][1] == '>': opt_prob.addCon(name, lower=edge) elif con[ii][1] == '=': opt_prob.addCon(name, lower=edge, upper=edge) # Finalize problem statement and run print(opt_prob) if solver == 'SNOPT': opt = pyOpt.SNOPT() CD_step = (sense_step**2.)**(1. / 3. ) #based on SNOPT Manual Recommendations opt.setOption('Function precision', sense_step**2.) opt.setOption('Difference interval', sense_step) opt.setOption('Central difference interval', CD_step) elif solver == 'SLSQP': opt = pyOpt.SLSQP() elif solver == 'FSQP': opt = pyOpt.FSQP() elif solver == 'PSQP': opt = pyOpt.PSQP() elif solver == 'NSGA2': opt = pyOpt.NSGA2(pll_type='POA') elif solver == 'ALPSO': #opt = pyOpt.pyALPSO.ALPSO(pll_type='DPM') #this requires DPM, which is a parallel implementation opt = pyOpt.ALPSO() elif solver == 'CONMIN': opt = pyOpt.CONMIN() elif solver == 'IPOPT': opt = pyOpt.IPOPT() elif solver == 'NLPQLP': opt = pyOpt.NLQPQLP() elif solver == 'NLPY_AUGLAG': opt = pyOpt.NLPY_AUGLAG() if nonderivative_line_search == True: opt.setOption('Nonderivative linesearch') if FD == 'parallel': outputs = opt(opt_prob, sens='FD', sensMode='pgc') elif solver == 'SNOPT' or solver == 'SLSQP': outputs = opt(opt_prob, sens='FD', sensStep=sense_step) else: outputs = opt(opt_prob) return outputs
def scale_vals(inp,con,ini,bnd,scl): """Scales values to help setup the problem Assumptions: N/A Source: N/A Inputs: inp [array] con [array] ini [array] bnd [array] scl [array] Outputs: tuple: x [array] scaled_constraints [array] x_low_bounds [array] x_up_bounds [array] con_up_edge [array] con_low_edge [array] Properties Used: N/A """ # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con,bnd_constraints) x = ini/scl x_low_bound = [] x_up_bound = [] edge = [] con_up_edge = [] con_low_edge = [] for ii in xrange(0,len(inp)): x_low_bound.append(bnd[ii][0]/scl[ii]) x_up_bound.append(bnd[ii][1]/scl[ii]) for ii in xrange(0,len(con)): edge.append(scaled_constraints[ii]) if con[ii][1]=='<': con_up_edge.append(edge[ii]) con_low_edge.append(-np.inf) elif con[ii][1]=='>': con_up_edge.append(np.inf) con_low_edge.append(edge[ii]) elif con[ii][1]=='=': con_up_edge.append(edge[ii]) con_low_edge.append(edge[ii]) x_low_bound = np.array(x_low_bound) x_up_bound = np.array(x_up_bound) con_up_edge = np.array(con_up_edge) con_low_edge = np.array(con_low_edge) return (x,scaled_constraints,x_low_bound,x_up_bound,con_up_edge,con_low_edge)
def Pyopt_Solve(problem,solver='SNOPT',FD='single', nonderivative_line_search=False): # Have the optimizer call the wrapper mywrap = lambda x:PyOpt_Problem(problem,x) inp = problem.optimization_problem.inputs obj = problem.optimization_problem.objective con = problem.optimization_problem.constraints if FD == 'parallel': from mpi4py import MPI comm = MPI.COMM_WORLD myrank = comm.Get_rank() # Instantiate the problem and set objective import pyOpt opt_prob = pyOpt.Optimization('SUAVE',mywrap) for ii in xrange(len(obj)): opt_prob.addObj(obj[ii,0]) # Set inputs nam = inp[:,0] # Names ini = inp[:,1] # Initials bnd = inp[:,2] # Bounds scl = inp[:,3] # Scale typ = inp[:,4] # Type # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con,bnd_constraints) x = ini/scl for ii in xrange(0,len(inp)): lbd = (bnd[ii][0]/scl[ii]) ubd = (bnd[ii][1]/scl[ii]) #if typ[ii] == 'continuous': vartype = 'c' #if typ[ii] == 'integer': #vartype = 'i' opt_prob.addVar(nam[ii],vartype,lower=lbd,upper=ubd,value=x[ii]) # Setup constraints for ii in xrange(0,len(con)): name = con[ii][0] edge = scaled_constraints[ii] if con[ii][1]=='<': opt_prob.addCon(name, type='i', upper=edge) elif con[ii][1]=='>': opt_prob.addCon(name, type='i', lower=edge,upper=np.inf) elif con[ii][1]=='=': opt_prob.addCon(name, type='e', equal=edge) # Finalize problem statement and run print opt_prob if solver == 'SNOPT': import pyOpt.pySNOPT opt = pyOpt.pySNOPT.SNOPT() elif solver == 'SLSQP': import pyOpt.pySLSQP opt = pyOpt.pySLSQP.SLSQP() opt.setOption('MAXIT', 200) elif solver == 'KSOPT': import pyOpt.pyKSOPT opt = pyOpt.pyKSOPT.KSOPT() elif solver == 'ALHSO': import pyOpt.pyALHSO opt = pyOpt.pyALHSO.ALHSO() elif solver == 'FSQP': import pyOpt.pyFSQP opt = pyOpt.pyFSQP.FSQP() elif solver == 'PSQP': import pyOpt.pyPSQP opt = pyOpt.pyPSQP.PSQP() elif solver == 'NLPQL': import pyOpt.pyNLPQL opt = pyOpt.pyNLPQL.NLPQL() elif solver == 'NSGA2': import pyOpt.pyNSGA2 opt = pyOpt.pyNSGA2.NSGA2(pll_type='POA') if nonderivative_line_search==True: opt.setOption('Nonderivative linesearch') if FD == 'parallel': outputs = opt(opt_prob, sens_type='FD',sens_mode='pgc') else: outputs = opt(opt_prob, sens_type='FD') return outputs
def Pyoptsparse_Solve(problem,solver='SNOPT',FD='single', sense_step=1.0E-6, nonderivative_line_search=False): """ This converts your SUAVE Nexus problem into a PyOptsparse optimization problem and solves it. Pyoptsparse has many algorithms, they can be switched out by using the solver input. Assumptions: None Source: N/A Inputs: problem [nexus()] solver [str] FD (parallel or single) [str] sense_step [float] nonderivative_line_search [bool] Outputs: outputs [list] Properties Used: None """ # Have the optimizer call the wrapper mywrap = lambda x:PyOpt_Problem(problem,x) inp = problem.optimization_problem.inputs obj = problem.optimization_problem.objective con = problem.optimization_problem.constraints if FD == 'parallel': from mpi4py import MPI comm = MPI.COMM_WORLD myrank = comm.Get_rank() # Instantiate the problem and set objective try: import pyoptsparse as pyOpt except: raise ImportError('No version of pyOptsparse found') opt_prob = pyOpt.Optimization('SUAVE',mywrap) for ii in range(len(obj)): opt_prob.addObj(obj[ii,0]) # Set inputs nam = inp[:,0] # Names ini = inp[:,1] # Initials bnd = inp[:,2] # Bounds scl = inp[:,3] # Scale typ = inp[:,4] # Type # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con,bnd_constraints) x = ini/scl for ii in range(0,len(inp)): lbd = (bnd[ii][0]/scl[ii]) ubd = (bnd[ii][1]/scl[ii]) #if typ[ii] == 'continuous': vartype = 'c' #if typ[ii] == 'integer': #vartype = 'i' opt_prob.addVar(nam[ii],vartype,lower=lbd,upper=ubd,value=x[ii]) # Setup constraints for ii in range(0,len(con)): name = con[ii][0] edge = scaled_constraints[ii] if con[ii][1]=='<': opt_prob.addCon(name, upper=edge) elif con[ii][1]=='>': opt_prob.addCon(name, lower=edge) elif con[ii][1]=='=': opt_prob.addCon(name, lower=edge,upper=edge) # Finalize problem statement and run print(opt_prob) if solver == 'SNOPT': opt = pyOpt.SNOPT() CD_step = (sense_step**2.)**(1./3.) #based on SNOPT Manual Recommendations opt.setOption('Function precision', sense_step**2.) opt.setOption('Difference interval', sense_step) opt.setOption('Central difference interval', CD_step) elif solver == 'SLSQP': opt = pyOpt.SLSQP() elif solver == 'FSQP': opt = pyOpt.FSQP() elif solver == 'PSQP': opt = pyOpt.PSQP() elif solver == 'NSGA2': opt = pyOpt.NSGA2(pll_type='POA') elif solver == 'ALPSO': #opt = pyOpt.pyALPSO.ALPSO(pll_type='DPM') #this requires DPM, which is a parallel implementation opt = pyOpt.ALPSO() elif solver == 'CONMIN': opt = pyOpt.CONMIN() elif solver == 'IPOPT': opt = pyOpt.IPOPT() elif solver == 'NLPQLP': opt = pyOpt.NLQPQLP() elif solver == 'NLPY_AUGLAG': opt = pyOpt.NLPY_AUGLAG() if nonderivative_line_search==True: opt.setOption('Nonderivative linesearch') if FD == 'parallel': outputs = opt(opt_prob, sens_type='FD',sens_mode='pgc') elif solver == 'SNOPT' or solver == 'SLSQP': outputs = opt(opt_prob, sens='FD', sensStep = sense_step) else: outputs = opt(opt_prob) return outputs
def scale_vals(self, inp, con, ini, bnd, scl): """Scales inputs, constraints, and their bounds. Assumptions: None Source: N/A Inputs: (all SUAVE format specific numpy arrays) inp Design variables con Constraint limits ini Initial values bnd Variable bounds scl Scaling factors Outputs: x <numpy array> Scaled design variables scaled_constraints <numpy array> x_low_bound <numpy array> x_up_bound <numpy array> con_up_edge <numpy array> con_low_edge <numpy array> name <list of strings> List of variable names Properties Used: None """ # Pull out the constraints and scale them bnd_constraints = help_fun.scale_const_bnds(con) scaled_constraints = help_fun.scale_const_values(con, bnd_constraints) x = ini / scl x_low_bound = [] x_up_bound = [] edge = [] name = [] con_up_edge = [] con_low_edge = [] for ii in xrange(0, len(inp)): x_low_bound.append(bnd[ii][0] / scl[ii]) x_up_bound.append(bnd[ii][1] / scl[ii]) for ii in xrange(0, len(con)): name.append(con[ii][0]) edge.append(scaled_constraints[ii]) if con[ii][1] == '<': con_up_edge.append(edge[ii]) con_low_edge.append(-np.inf) elif con[ii][1] == '>': con_up_edge.append(np.inf) con_low_edge.append(edge[ii]) elif con[ii][1] == '=': con_up_edge.append(edge[ii]) con_low_edge.append(edge[ii]) x_low_bound = np.array(x_low_bound) x_up_bound = np.array(x_up_bound) con_up_edge = np.array(con_up_edge) con_low_edge = np.array(con_low_edge) return (x, scaled_constraints, x_low_bound, x_up_bound, con_up_edge, con_low_edge, name)