def minimize( self, problem: Problem, x0: np.ndarray, id: str, history_options: HistoryOptions = None, optimize_options: OptimizeOptions = None, ) -> OptimizerResult: """Perform optimization. Parameters: see `Optimizer` documentation.""" if cyipopt is None: raise ImportError( "This optimizer requires an installation of ipopt. You can " "install ipopt via `pip install ipopt`.") objective = problem.objective bounds = np.array([problem.lb, problem.ub]).T ret = cyipopt.minimize_ipopt( fun=objective.get_fval, x0=x0, method=None, # ipopt does not use this argument for anything jac=objective.get_grad, hess=None, # ipopt does not support Hessian yet hessp=None, # ipopt does not support Hessian vector product yet bounds=bounds, tol=None, # can be set via options options=self.options, ) # the ipopt return object is a scipy.optimize.OptimizeResult return OptimizerResult(x=ret.x, exitflag=ret.status, message=ret.message)
def test_minimize_ipopt_if_scipy(): """If SciPy is installed `minimize_ipopt` works correctly.""" from scipy.optimize import rosen, rosen_der x0 = [1.3, 0.7, 0.8, 1.9, 1.2] res = cyipopt.minimize_ipopt(rosen, x0, jac=rosen_der) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 0.0) assert res.get("status") == 0 assert res.get("success") is True np.testing.assert_allclose(res.get("x"), np.ones(5))
def test_minimize_ipopt_nojac_if_scipy(): """`minimize_ipopt` works without Jacobian.""" from scipy.optimize import rosen x0 = [1.3, 0.7, 0.8, 1.9, 1.2] options = {"tol": 1e-7} res = cyipopt.minimize_ipopt(rosen, x0, options=options) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 0.0) assert res.get("status") == 0 assert res.get("success") is True np.testing.assert_allclose(res.get("x"), np.ones(5), rtol=1e-5)
def test_minimize_ipopt_nojac_constraints_if_scipy(): """ `minimize_ipopt` works without Jacobian and with constraints""" from scipy.optimize import rosen, rosen_der x0 = [1.3, 0.7, 0.8, 1.9, 1.2] constr = {"fun": lambda x: rosen(x) - 1.0, "type": "ineq"} res = cyipopt.minimize_ipopt(rosen, x0, jac=rosen_der, constraints=constr) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 1.0) assert res.get("status") == 0 assert res.get("success") is True expected_res = np.array( [1.00407015, 0.99655763, 1.05556205, 1.18568342, 1.38386505]) np.testing.assert_allclose(res.get("x"), expected_res)
def test_minimize_ipopt_nojac_constraints_if_scipy(): """ `minimize_ipopt` works without Jacobian and with constraints""" from scipy.optimize import rosen x0 = [1.3, 0.7, 0.8, 1.9, 1.2] constr = {"fun": lambda x: rosen(x) - 1.0, "type": "ineq"} res = cyipopt.minimize_ipopt(rosen, x0, constraints=constr) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 1.0) assert res.get("status") == 0 assert res.get("success") is True expected_res = np.array([1.001867, 0.99434067, 1.05070075, 1.17906312, 1.38103001]) np.testing.assert_allclose(res.get("x"), expected_res)
def test_minimize_ipopt_nojac_constraints_vectorvalued_if_scipy(): """ `minimize_ipopt` works without Jacobian and with constraints without specifying the jacobian of the vector valued constraint function""" from scipy.optimize import rosen, rosen_der x0 = np.array([0.5, 0.75]) bounds = [np.array([0, 1]), np.array([-0.5, 2.0])] expected_res = 0.25 * np.ones_like(x0) eq_cons = {"fun": lambda x: x - expected_res, "type": "eq"} res = cyipopt.minimize_ipopt(rosen, x0, jac=rosen_der, bounds=bounds, constraints=[eq_cons]) assert isinstance(res, dict) assert res.get("status") == 0 assert res.get("success") is True np.testing.assert_allclose(res.get("x"), expected_res)
def test_minimize_ipopt_jac_and_hessians_constraints_if_scipy( ): """`minimize_ipopt` works with objective gradient and Hessian and constraint jacobians and Hessians.""" from scipy.optimize import rosen, rosen_der, rosen_hess x0 = [0.0, 0.0] constr = { "type": "ineq", "fun": lambda x: -x[0]**2 - x[1]**2 + 2, "jac": lambda x: np.array([-2 * x[0], -2 * x[1]]), "hess": lambda x, v: -2 * np.eye(2) * v[0] } bounds = [(-1.5, 1.5), (-1.5, 1.5)] res = cyipopt.minimize_ipopt(rosen, x0, jac=rosen_der, hess=rosen_hess, constraints=constr) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 0.0) assert res.get("status") == 0 assert res.get("success") is True expected_res = np.array([1.0, 1.0]) np.testing.assert_allclose(res.get("x"), expected_res, rtol=1e-5)
def test_minimize_ipopt_import_error_if_no_scipy(): """`minimize_ipopt` not callable without SciPy installed.""" expected_error_msg = re.escape("Install SciPy to use the " "`minimize_ipopt` function.") with pytest.raises(ImportError, match=expected_error_msg): cyipopt.minimize_ipopt(None, None)
hessian_approximation, "hessian_approximation_space": hessian_approximation_space, # linear solver "linear_solver": linear_solver, **linear_solver_options, # **converted_bool_to_str_options, } raw_res = cyipopt.minimize_ipopt( fun=criterion, x0=x, bounds=_get_scipy_bounds(lower_bounds, upper_bounds), jac=derivative, constraints=nonlinear_constraints, tol=convergence_relative_criterion_tolerance, options=options, ) res = process_scipy_result(raw_res) return res def _convert_bool_to_str(var, name): """Convert input to either 'yes' or 'no' and check the output is yes or no. Args: var (str or bool): user input name (str): name of the variable.
@author: alexandregirard """ from scipy.optimize import minimize from cyipopt import minimize_ipopt def cost (x): j = x[0]+x[1] return -j def constraint_circle(x): res = x[0]**2+x[1]**2 - 1 return -res cons = ({'type': 'ineq', 'fun': constraint_circle}) #cons = ({'type': 'eq', 'fun': constraint_circle}) bnds = ((0, None), (0, None)) res = minimize( cost, (0, 0), method='SLSQP', bounds=bnds, constraints=cons) print(res) res2 = minimize_ipopt( cost, (0, 0), bounds=bnds, constraints=cons) print(res2)
import numpy as np from scipy.optimize import rosen, rosen_der from cyipopt import minimize_ipopt x0 = np.array([0.5, 0]) bounds = [np.array([0, 1]), np.array([-0.5, 2.0])] eq_cons = { "type": "eq", "fun": lambda x: np.array([2 * x[0] + x[1] - 1, x[0]**2 - 0.1]) } res = minimize_ipopt(rosen, x0, jac=rosen_der, bounds=bounds, constraints=[eq_cons]) print(res)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Fri Sep 10 11:12:11 2021 @author: alexandregirard """ from scipy.optimize import minimize from cyipopt import minimize_ipopt fun = lambda x: (x[0] - 1)**2 + (x[1] - 2.5)**2 cons = ({'type': 'ineq', 'fun': lambda x: x[0] - 2 * x[1] + 2}, {'type': 'ineq', 'fun': lambda x: -x[0] - 2 * x[1] + 6}, {'type': 'ineq', 'fun': lambda x: -x[0] + 2 * x[1] + 2}) bnds = ((0, None), (0, None)) res = minimize(fun, (2, 0), method='SLSQP', bounds=bnds, constraints=cons) print(res) res2 = minimize_ipopt(fun, (2, 0), bounds=bnds, constraints=cons) print(res2)
hessian_approximation, "hessian_approximation_space": hessian_approximation_space, # linear solver "linear_solver": linear_solver, **linear_solver_options, # **converted_bool_to_str_options, } raw_res = cyipopt.minimize_ipopt( fun=func, x0=x, bounds=get_scipy_bounds(lower_bounds, upper_bounds), jac=gradient, constraints=(), tol=convergence_relative_criterion_tolerance, options=options, ) res = process_scipy_result(raw_res) return res def _convert_bool_to_str(var, name): """Convert input to either 'yes' or 'no' and check the output is yes or no. Args: var (str or bool): user input name (str): name of the variable.
cons = [ { 'type': 'eq', 'fun': con_eq_jit, 'jac': con_eq_jac, 'hess': con_eq_hessvp }, { 'type': 'ineq', 'fun': con_ineq_jit, 'jac': con_ineq_jac, 'hess': con_ineq_hessvp }, ] # initial guess x0 = np.array([1, 5, 5, 1]) # variable bounds: 1 <= x[i] <= 5 bnds = [(1, 5) for _ in range(x0.size)] res = minimize_ipopt(obj_jit, jac=obj_grad, hess=obj_hess, x0=x0, bounds=bnds, constraints=cons, options={'disp': 5}) print(res)
# tmp = np.eye(Gi_block.shape[0]) Fi = np.reshape(tmp @ X_hat.flatten(), (nm, -1)) fi = np.fft.irfft(Fi, 2 * nf + 2) * nf residual = F_pto_fun(x) + F_ext_fun(x) - fi return residual.flatten() #%% x0 = np.random.rand(num_modes * (2 * num_freq + 1) + 3 * (2 * num_freq)) eq_cons = { 'type': 'eq', 'fun': resid_fun, 'jac': jacobian(resid_fun), } res = minimize_ipopt(fun=obj_fun, x0=x0, jac=grad(obj_fun), constraints=(eq_cons), options={'print_level': 5}, tol=1e-14) # plt.close('all') fig, ax = plt.subplots() ax.plot(x0, label='$x_0$', marker='.') ax.plot(res.x, label='$x$', marker='o') ax.legend()
def test_minimize_ipopt_hs071(): """ `minimize_ipopt` works with objective gradient and Hessian and constraint jacobians and Hessians. The objective and the constraints functions return a tuple containing the function value and the evaluated gradient or jacobian. Solves Hock & Schittkowski's test problem 71: min x0*x3*(x0+x1+x2)+x2 s.t. x0**2 + x1**2 + x2**2 + x3**2 - 40 = 0 x0 * x1 * x2 * x3 - 25 >= 0 1 <= x0,x1,x2,x3 <= 5 """ def obj_and_grad(x): obj = x[0] * x[3] * np.sum(x[:3]) + x[2] grad = np.array([ x[0] * x[3] + x[3] * np.sum(x[0:3]), x[0] * x[3], x[0] * x[3] + 1.0, x[0] * np.sum(x[0:3]) ]) return obj, grad def obj_hess(x): return np.array([[2 * x[3], 0.0, 0, 0], [x[3], 0, 0, 0], [x[3], 0, 0, 0], [2 * x[0] + x[1] + x[2], x[0], x[0], 0]]) def con_eq_and_jac(x): value = np.sum(x**2) - 40 jac = np.array([2 * x]) return value, jac def con_eq_hess(x, v): return v[0] * 2.0 * np.eye(4) def con_ineq_and_jac(x): value = np.prod(x) - 25 jac = np.array([np.prod(x) / x]) return value, jac def con_ineq_hess(x, v): return v[0] * np.array([[0, 0, 0, 0], [x[2] * x[3], 0, 0, 0], [x[1] * x[3], x[0] * x[3], 0, 0], [x[1] * x[2], x[0] * x[2], x[0] * x[1], 0]]) con1 = { "type": "eq", "fun": con_eq_and_jac, "jac": True, "hess": con_eq_hess } con2 = { "type": "ineq", "fun": con_ineq_and_jac, "jac": True, "hess": con_ineq_hess } constrs = (con1, con2) x0 = np.array([1.0, 5.0, 5.0, 1.0]) bnds = [(1, 5) for _ in range(x0.size)] res = cyipopt.minimize_ipopt(obj_and_grad, jac=True, hess=obj_hess, x0=x0, bounds=bnds, constraints=constrs) assert isinstance(res, dict) assert np.isclose(res.get("fun"), 17.01401727277449) assert res.get("status") == 0 assert res.get("success") is True expected_res = np.array([0.99999999, 4.74299964, 3.82114998, 1.3794083]) np.testing.assert_allclose(res.get("x"), expected_res)