Skip to content

Commit

Permalink
Add documentation / tests for warm starting
Browse files Browse the repository at this point in the history
  • Loading branch information
chrhansk committed Oct 10, 2024
1 parent a135df2 commit 61bacd9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
28 changes: 25 additions & 3 deletions cyipopt/cython/ipopt_wrapper.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,15 @@ cdef class Problem:
x : array-like, shape(n, )
Initial guess.
lagrange : array-like, shape(m, ), optional (default=[])
Initial values for the constraint multipliers (only if warm start option is chosen).
zl : array-like, shape(n, ), optional (default=[])
Initial values for the multipliers for lower variable bounds (only if warm start option is chosen).
zu : array-like, shape(n, ), optional (default=[])
Initial values for the multipliers for upper variable bounds (only if warm start option is chosen).
Returns
-------
x : array, shape(n, )
Expand Down Expand Up @@ -625,14 +634,27 @@ cdef class Problem:
cdef ApplicationReturnStatus stat
cdef np.ndarray[DTYPEd_t, ndim=1] g = np.zeros((self.__m,), dtype=DTYPEd)

if lagrange == []:
lagrange = np.atleast_1d(lagrange)
zl = np.atleast_1d(zl)
zu = np.atleast_1d(zu)

if len(lagrange) == 0:
lagrange = np.zeros((self.__m,), dtype=DTYPEd)
elif self.__m != len(lagrange):
raise ValueError("Wrong length of lagrange.")

cdef np.ndarray[DTYPEd_t, ndim=1] mult_g = np.array(lagrange, dtype=DTYPEd).flatten()

if zl == []:
if len(zl) == 0:
zl = np.zeros((self.__n,), dtype=DTYPEd)
if zu == []:
elif self.__n != len(zl):
raise ValueError("Wrong length of zl.")

if len(zu) == 0:
zu = np.zeros((self.__n,), dtype=DTYPEd)
elif self.__n != len(zu):
raise ValueError("Wrong length of zu.")

cdef np.ndarray[DTYPEd_t, ndim=1] mult_x_L = np.array(zl, dtype=DTYPEd).flatten()
cdef np.ndarray[DTYPEd_t, ndim=1] mult_x_U = np.array(zu, dtype=DTYPEd).flatten()

Expand Down
33 changes: 33 additions & 0 deletions cyipopt/tests/integration/test_hs071.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,39 @@ def test_hs071_solve(hs071_initial_guess_fixture,
np.testing.assert_allclose(x, expected_x)


def test_hs071_warm_start(hs071_initial_guess_fixture,
hs071_optimal_solution_fixture,
hs071_problem_instance_fixture):
x0 = hs071_initial_guess_fixture
nlp = hs071_problem_instance_fixture

_, info = nlp.solve(x0)

x_opt, _ = hs071_optimal_solution_fixture
np.testing.assert_allclose(info['x'], x_opt)

x_init = info['x']
lagrange = info['mult_g']
zl = info['mult_x_L']
zu = info['mult_x_U']

# Set parameters to avoid push the solution
# away from the variable bounds
nlp.add_option('warm_start_init_point', 'yes')
nlp.add_option("warm_start_bound_frac", 1e-6)
nlp.add_option("warm_start_bound_push", 1e-6)
nlp.add_option("warm_start_slack_bound_frac", 1e-6)
nlp.add_option("warm_start_slack_bound_push", 1e-6)
nlp.add_option("warm_start_mult_bound_push", 1e-6)

_, info = nlp.solve(x_init,
lagrange=lagrange,
zl=zl,
zu=zu)

np.testing.assert_allclose(info['x'], x_opt)


def _make_problem(definition, lb, ub, cl, cu):
n = len(lb)
m = len(cl)
Expand Down

0 comments on commit 61bacd9

Please sign in to comment.