Example #1
0
 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]
Example #2
0
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']))
Example #3
0
    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
Example #4
0
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
Example #5
0
    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
Example #6
0
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
Example #7
0
    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
Example #8
0
    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
Example #9
0
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)
Example #10
0
    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
Example #11
0
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