def optimizeSFA(self, print_level=0, max_iter=50): # create problem if self.constraint_matrix is None: handle = cyipopt.Problem(n=self.k, m=0, problem_obj=sfaObj(self), lb=self.uprior[0], ub=self.uprior[1]) else: handle = cyipopt.Problem(n=self.k, m=self.constraint_matrix.shape[0], problem_obj=sfaObj(self), lb=self.uprior[0], ub=self.uprior[1], cl=self.constraint_values[0], cu=self.constraint_values[1]) # add options handle.add_option('print_level', print_level) if max_iter is not None: handle.add_option('max_iter', max_iter) # initial point if self.soln is None: beta0 = np.linalg.solve(self.X.T.dot(self.X), self.X.T.dot(self.Y)) gama0 = np.repeat(0.01, self.k_gama) deta0 = np.repeat(0.01, self.k_deta) x0 = np.hstack((beta0, gama0, deta0)) else: x0 = self.soln # solver the problem soln, info = handle.solve(x0) # extract the solution self.soln = soln self.info = info self.beta_soln = soln[self.id_beta] self.gama_soln = soln[self.id_gama] self.deta_soln = soln[self.id_deta]
def main(): # # Define the problem # x0 = [1.0, 5.0, 5.0, 1.0] lb = [1.0, 1.0, 1.0, 1.0] ub = [5.0, 5.0, 5.0, 5.0] cl = [25.0, 40.0] cu = [2.0e19, 40.0] nlp = cyipopt.Problem( n=len(x0), m=len(cl), problem_obj=hs071(), lb=lb, ub=ub, cl=cl, cu=cu ) # # Set solver options # #nlp.addOption('derivative_test', 'second-order') nlp.add_option('mu_strategy', 'adaptive') nlp.add_option('tol', 1e-7) # # Scale the problem (Just for demonstration purposes) # nlp.set_problem_scaling( obj_scaling=2, x_scaling=[1, 1, 1, 1] ) nlp.add_option('nlp_scaling_method', 'user-scaling') # # Solve the problem # x, info = nlp.solve(x0) print("Solution of the primal variables: x=%s\n" % repr(x)) print("Solution of the dual variables: lambda=%s\n" % repr(info['mult_g'])) print("Objective=%s\n" % repr(info['obj_val']))
def solve(self, x0=None, tee=False): xl = self._problem.x_lb() xu = self._problem.x_ub() gl = self._problem.g_lb() gu = self._problem.g_ub() if x0 is None: x0 = self._problem.x_init() xstart = x0 nx = len(xstart) ng = len(gl) cyipopt_solver = cyipopt.Problem(n=nx, m=ng, problem_obj=self._problem, lb=xl, ub=xu, cl=gl, cu=gu) # check if we need scaling obj_scaling, x_scaling, g_scaling = self._problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) cyipopt_solver.setProblemScaling(obj_scaling, x_scaling, g_scaling) # add options for k, v in self._options.items(): cyipopt_solver.addOption(k, v) if tee: x, info = cyipopt_solver.solve(xstart) else: newstdout = _redirect_stdout() x, info = cyipopt_solver.solve(xstart) os.dup2(newstdout, 1) return x, info
def hs071_problem_instance_fixture(hs071_defintion_instance_fixture, hs071_initial_guess_fixture, hs071_variable_lower_bounds_fixture, hs071_variable_upper_bounds_fixture, hs071_constraint_lower_bounds_fixture, hs071_constraint_upper_bounds_fixture, ): """Return a default cyipopt.Problem instance of the hs071 test problem.""" problem_definition = hs071_defintion_instance_fixture x0 = hs071_initial_guess_fixture lb = hs071_variable_lower_bounds_fixture ub = hs071_variable_upper_bounds_fixture cl = hs071_constraint_lower_bounds_fixture cu = hs071_constraint_upper_bounds_fixture n = len(x0) m = len(cl) problem = cyipopt.Problem(n=n, m=m, problem_obj=problem_definition, lb=lb, ub=ub, cl=cl, cu=cu) return problem
def solve(self, problem, domain_constraint): if self.init_with_last_result: #TODO implement this raise NotImplementedError("") x0 = problem.get_init_value() lb = domain_constraint.get_lower_bounds() ub = domain_constraint.get_upper_bounds() cl = problem.get_constraint_lower_bounds() cu = problem.get_constraint_upper_bounds() nlp = cyipopt.Problem(n=len(x0), m=len(cl), problem_obj=problem, lb=lb, ub=ub, cl=cl, cu=cu) nlp.addOption('max_iteration', self.max_iteration) nlp.addOption('mu_strategy', self.mu_strategy) nlp.addOption('mu_target', self.mu_target) nlp.addOption('mu_linear_decrease_factor', self.mu_linear_decrease_factor) nlp.addOption('alpha_for_y', self.alpha_for_y) nlp.addOption('obj_scaling_factor', self.obj_scaling_factor) nlp.addOption('nlp_scaling_max_gradient', self.nlp_scaling_max_gradient) x, info = nlp.solve(x0) if info["status"] == 0 or info["status"] == 1: self.prev_result = x return Optimizer.SUCCESS return Optimizer.FAIL
def Ipoptimizer(x0, func, f_eqcons, f_ieqcons, fprime, fprime_eqcons, fprime_ieqcons, fdotdot, config): """ This function implements a call from FADO to the cyipopt python module. """ # pack everything into a class opt_problem = IpoptProblemClass(func, f_eqcons, f_ieqcons, fprime, fprime_eqcons, fprime_ieqcons, fdotdot, config) if fdotdot == None: opt_problem = IpoptFirstOrderProblemClass(func, f_eqcons, f_ieqcons, fprime, fprime_eqcons, fprime_ieqcons) # get the boundary arrays lb = [config.lb] * config.nparam ub = [config.ub] * config.nparam # create constraint values cl = np.append(np.zeros(config.neqcons), config.lower) cu = np.append(np.zeros(config.neqcons), config.upper) # call ipopt to create the problem nlp = cyipopt.Problem(n=config.nparam, m=(config.neqcons + config.nieqcons), problem_obj=opt_problem, lb=lb, ub=ub, cl=cl, cu=cu) nlp.addOption('nlp_scaling_method', 'none') # solve the problem x, info = nlp.solve(x0) return x
def solve(self, model, **kwds): config = self.config(kwds, preserve_implicit=True) if not isinstance(model, Block): raise ValueError("PyomoCyIpoptSolver.solve(model): model " "must be a Pyomo Block") # If this is a Pyomo model / block, then we need to create # the appropriate PyomoNLP, then wrap it in a CyIpoptNLP grey_box_blocks = list(model.component_data_objects( egb.ExternalGreyBoxBlock, active=True)) if grey_box_blocks: # nlp = pyomo_nlp.PyomoGreyBoxNLP(model) nlp = pyomo_grey_box.PyomoNLPWithGreyBoxBlocks(model) else: nlp = pyomo_nlp.PyomoNLP(model) problem = CyIpoptNLP(nlp, intermediate_callback=config.intermediate_callback) xl = problem.x_lb() xu = problem.x_ub() gl = problem.g_lb() gu = problem.g_ub() nx = len(xl) ng = len(gl) cyipopt_solver = cyipopt.Problem( n=nx, m=ng, problem_obj=problem, lb=xl, ub=xu, cl=gl, cu=gu ) # check if we need scaling obj_scaling, x_scaling, g_scaling = problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) try: set_scaling = cyipopt_solver.set_problem_scaling except AttributeError: # Fall back to pre-1.0.0 API set_scaling = cyipopt_solver.setProblemScaling set_scaling(obj_scaling, x_scaling, g_scaling) # add options try: add_option = cyipopt_solver.add_option except AttributeError: # Fall back to pre-1.0.0 API add_option = cyipopt_solver.addOption for k, v in config.options.items(): add_option(k, v) timer = TicTocTimer() try: # We preemptively set up the TeeStream, even if we aren't # going to use it: the implementation is such that the # context manager does nothing (i.e., doesn't start up any # processing threads) until afer a client accesses # STDOUT/STDERR with TeeStream(sys.stdout) as _teeStream: if config.tee: try: fd = sys.stdout.fileno() except (io.UnsupportedOperation, AttributeError): # If sys,stdout doesn't have a valid fileno, # then create one using the TeeStream fd = _teeStream.STDOUT.fileno() else: fd = None with redirect_fd(fd=1, output=fd, synchronize=False): x, info = cyipopt_solver.solve(problem.x_init()) solverStatus = SolverStatus.ok except: msg = "Exception encountered during cyipopt solve:" logger.error(msg, exc_info=sys.exc_info()) solverStatus = SolverStatus.unknown raise wall_time = timer.toc(None) results = SolverResults() if config.load_solutions: nlp.set_primals(x) nlp.set_duals(info['mult_g']) nlp.load_state_into_pyomo( bound_multipliers=(info['mult_x_L'], info['mult_x_U'])) else: soln = results.solution.add() soln.variable.update( (i, {'Value':j, 'ipopt_zL_out': zl, 'ipopt_zU_out': zu}) for i,j,zl,zu in zip( nlp.variable_names(), x, info['mult_x_L'], info['mult_x_U'] ) ) soln.constraint.update( (i, {'Dual':j}) for i,j in zip( nlp.constraint_names(), info['mult_g'])) results.problem.name = model.name obj = next(model.component_data_objects(Objective, active=True)) if obj.sense == minimize: results.problem.sense = ProblemSense.minimize results.problem.upper_bound = info['obj_val'] else: results.problem.sense = ProblemSense.maximize results.problem.lower_bound = info['obj_val'] results.problem.number_of_objectives = 1 results.problem.number_of_constraints = ng results.problem.number_of_variables = nx results.problem.number_of_binary_variables = 0 results.problem.number_of_integer_variables = 0 results.problem.number_of_continuous_variables = nx # TODO: results.problem.number_of_nonzeros results.solver.name = 'cyipopt' results.solver.return_code = info['status'] results.solver.message = info['status_msg'] results.solver.wallclock_time = wall_time status_enum = _cyipopt_status_enum[info['status_msg']] results.solver.termination_condition = _ipopt_term_cond[status_enum] results.solver.status = TerminationCondition.to_solver_status( results.solver.termination_condition) if config.return_nlp: return results, nlp return results
def solve(self, x0=None, tee=False): xl = self._problem.x_lb() xu = self._problem.x_ub() gl = self._problem.g_lb() gu = self._problem.g_ub() if x0 is None: x0 = self._problem.x_init() xstart = x0 nx = len(xstart) ng = len(gl) cyipopt_solver = cyipopt.Problem( n=nx, m=ng, problem_obj=self._problem, lb=xl, ub=xu, cl=gl, cu=gu ) # check if we need scaling obj_scaling, x_scaling, g_scaling = self._problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) try: set_scaling = cyipopt_solver.set_problem_scaling except AttributeError: # Fall back to pre-1.0.0 API set_scaling = cyipopt_solver.setProblemScaling set_scaling(obj_scaling, x_scaling, g_scaling) # add options try: add_option = cyipopt_solver.add_option except AttributeError: # Fall back to pre-1.0.0 API add_option = cyipopt_solver.addOption for k, v in self._options.items(): add_option(k, v) # We preemptively set up the TeeStream, even if we aren't # going to use it: the implementation is such that the # context manager does nothing (i.e., doesn't start up any # processing threads) until afer a client accesses # STDOUT/STDERR with TeeStream(sys.stdout) as _teeStream: if tee: try: fd = sys.stdout.fileno() except (io.UnsupportedOperation, AttributeError): # If sys,stdout doesn't have a valid fileno, # then create one using the TeeStream fd = _teeStream.STDOUT.fileno() else: fd = None with redirect_fd(fd=1, output=fd, synchronize=False): x, info = cyipopt_solver.solve(xstart) return x, info
def minimize_ipopt(fun, x0, args=(), kwargs=None, method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None): """ Minimize a function using ipopt. The call signature is exactly like for `scipy.optimize.mimize`. In options, all options are directly passed to ipopt. Check [http://www.coin-or.org/Ipopt/documentation/node39.html] for details. The options `disp` and `maxiter` are automatically mapped to their ipopt-equivalents `print_level` and `max_iter`. """ if not SCIPY_INSTALLED: raise ImportError( 'Install SciPy to use the `minimize_ipopt` function.') _x0 = np.atleast_1d(x0) problem = IpoptProblemWrapper(fun, args=args, kwargs=kwargs, jac=jac, hess=hess, hessp=hessp, constraints=constraints) lb, ub = get_bounds(bounds) cl, cu = get_constraint_bounds(constraints, x0) if options is None: options = {} nlp = cyipopt.Problem(n=len(_x0), m=len(cl), problem_obj=problem, lb=lb, ub=ub, cl=cl, cu=cu) # python3 compatibility convert_to_bytes(options) # Rename some default scipy options replace_option(options, b'disp', b'print_level') replace_option(options, b'maxiter', b'max_iter') if b'print_level' not in options: options[b'print_level'] = 0 if b'tol' not in options: options[b'tol'] = tol or 1e-8 if b'mu_strategy' not in options: options[b'mu_strategy'] = b'adaptive' if b'hessian_approximation' not in options: if hess is None and hessp is None: options[b'hessian_approximation'] = b'limited-memory' for option, value in options.items(): try: nlp.add_option(option, value) except TypeError as e: raise TypeError( 'Invalid option for IPOPT: {0}: {1} (Original message: "{2}")'. format(option, value, e)) x, info = nlp.solve(_x0) if np.asarray(x0).shape == (): x = x[0] return OptimizeResult(x=x, success=info['status'] == 0, status=info['status'], message=info['status_msg'], fun=info['obj_val'], info=info, nfev=problem.nfev, njev=problem.njev, nit=problem.nit)
def solve(self, model, **kwds): config = self.config(kwds, preserve_implicit=True) if not isinstance(model, Block): raise ValueError("PyomoCyIpoptSolver.solve(model): model " "must be a Pyomo Block") # If this is a Pyomo model / block, then we need to create # the appropriate PyomoNLP, then wrap it in a CyIpoptNLP grey_box_blocks = list( model.component_data_objects(egb.ExternalGreyBoxBlock, active=True)) if grey_box_blocks: # nlp = pyomo_nlp.PyomoGreyBoxNLP(model) nlp = pyomo_grey_box.PyomoNLPWithGreyBoxBlocks(model) else: nlp = pyomo_nlp.PyomoNLP(model) problem = CyIpoptNLP( nlp, intermediate_callback=config.intermediate_callback) xl = problem.x_lb() xu = problem.x_ub() gl = problem.g_lb() gu = problem.g_ub() nx = len(xl) ng = len(gl) cyipopt_solver = cyipopt.Problem(n=nx, m=ng, problem_obj=problem, lb=xl, ub=xu, cl=gl, cu=gu) # check if we need scaling obj_scaling, x_scaling, g_scaling = problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) cyipopt_solver.setProblemScaling(obj_scaling, x_scaling, g_scaling) # add options for k, v in config.options.items(): cyipopt_solver.addOption(k, v) timer = TicTocTimer() try: if config.tee: x, info = cyipopt_solver.solve(problem.x_init()) else: newstdout = _redirect_stdout() x, info = cyipopt_solver.solve(problem.x_init()) os.dup2(newstdout, 1) solverStatus = SolverStatus.ok except: msg = "Exception encountered during cyipopt solve:" logger.error(msg, exc_info=sys.exc_info()) solverStatus = SolverStatus.unknown raise wall_time = timer.toc(None) results = SolverResults() if config.load_solutions: nlp.set_primals(x) nlp.set_duals(info['mult_g']) nlp.load_state_into_pyomo(bound_multipliers=(info['mult_x_L'], info['mult_x_U'])) else: soln = results.solution.add() soln.variable.update((i, { 'Value': j, 'ipopt_zL_out': zl, 'ipopt_zU_out': zu }) for i, j, zl, zu in zip(nlp.variable_names(), x, info['mult_x_L'], info['mult_x_U'])) soln.constraint.update((i, { 'Dual': j }) for i, j in zip(nlp.constraint_names(), info['mult_g'])) results.problem.name = model.name obj = next(model.component_data_objects(Objective, active=True)) if obj.sense == minimize: results.problem.sense = ProblemSense.minimize results.problem.upper_bound = info['obj_val'] else: results.problem.sense = ProblemSense.maximize results.problem.lower_bound = info['obj_val'] results.problem.number_of_objectives = 1 results.problem.number_of_constraints = ng results.problem.number_of_variables = nx results.problem.number_of_binary_variables = 0 results.problem.number_of_integer_variables = 0 results.problem.number_of_continuous_variables = nx # TODO: results.problem.number_of_nonzeros results.solver.name = 'cyipopt' results.solver.return_code = info['status'] results.solver.message = info['status_msg'] results.solver.wallclock_time = wall_time status_enum = _cyipopt_status_enum[info['status_msg']] results.solver.termination_condition = _ipopt_term_cond[status_enum] results.solver.status = TerminationCondition.to_solver_status( results.solver.termination_condition) if config.return_nlp: return results, nlp return results
def optimize_nlp(procedure: InfillProcedure, x: np.ndarray, g: np.ndarray, f: np.ndarray, nlp_options: NLPOptions, x0: list, lb: list, ub: list): if not isinstance(procedure, InfillProcedure): raise ValueError("'procedure' has to be a valid Infill procedure " "object.") if not isinstance(nlp_options, NLPOptions): raise ValueError("'nlp_options' has to be a valid Non-Linear options " "object.") if isinstance(nlp_options, DockerNLPOptions): # use docker server # constraint hyperparameters con_theta = [ model.theta.flatten().tolist() for model in procedure.surr_con ] # process data to be sent surr_data = { 'input_design': x.tolist(), 'fobj_data': { 'fobj_obs': f.tolist(), 'fobj_theta': procedure.surr_obj.theta.flatten().tolist() }, 'const_data': { 'const_obs': g.tolist(), 'const_theta': con_theta }, 'regmodel': procedure.regression, 'corrmodel': 'corrgauss' } # ipopt options nlp_opts = { 'tol': nlp_options.tol, 'max_iter': nlp_options.max_iter, 'con_tol': nlp_options.con_tol } dic = { 'x0': x0, 'lb': lb, 'ub': ub, 'surr_data': surr_data, 'nlp_opts': nlp_opts } # send data to server and return the nlp solution response = requests.post(url=nlp_options.server_url + '/opt', json=dic) sol = response.json() sol['x'] = np.array(sol['x']) # converting from list to np.array elif isinstance(nlp_options, IpOptOptions): # local installation of IpOpt solver x0 = np.array(x0).flatten() lb = np.array(lb).flatten() ub = np.array(ub).flatten() m, n = x.shape # hyperparameters f_theta = procedure.surr_obj.theta.flatten() con_theta = [model.theta.flatten() for model in procedure.surr_con] # build the surrogates obj_surr = Dace(regression=procedure.regression, correlation='corrgauss') obj_surr.fit(S=x, Y=f, theta0=f_theta) con_surr = [] for j in range(g.shape[1]): con_surr_ph = Dace(regression=procedure.regression, correlation='corrgauss') con_surr_ph.fit(S=x, Y=g[:, j], theta0=con_theta[j]) con_surr.append(con_surr_ph) # ------------------------------ Solver call ------------------------------ nlp = cyipopt.Problem(n=x0.size, m=len(con_surr), problem_obj=CaballeroProblem(obj_surr, con_surr), lb=lb, ub=ub, cl=-np.inf * np.ones(len(con_surr)), cu=np.zeros(len(con_surr))) # ipopt options nlp.add_option('tol', nlp_options.tol) nlp.add_option('constr_viol_tol', nlp_options.con_tol) nlp.add_option('max_iter', nlp_options.max_iter) nlp.add_option('hessian_approximation', 'limited-memory') nlp.add_option('print_level', 0) nlp.add_option('mu_strategy', 'adaptive') x, info = nlp.solve(x0) fval = info['obj_val'] exitflag = info['status'] if exitflag == 0 or exitflag == 1 or exitflag == 6: # ipopt succeded exitflag = 1 else: # ipopt failed. See IpReturnCodes_inc.h for complete list of flags exitflag = 0 return {'x': x, 'fval': fval, 'exitflag': exitflag} else: raise NotImplementedError("NLP solver not implemented.") return sol