#!/usr/bin/env python3
"``naginterfaces.library.opt.handle_solve_ssqp`` Python Example."
# NAG Copyright 2022.
# pylint: disable=invalid-name,too-many-arguments,too-many-locals,too-many-statements
import numpy as np
from naginterfaces.library import opt
[docs]def main():
"""
Example for :func:`naginterfaces.library.opt.handle_solve_ssqp`.
SQP solver for sparse NLP.
NLP example: Quadratic objective, linear constraint and two nonlinear
constraints.
For illustrative purposes, the quadratic objective is coded as a nonlinear
function to show the usage of objfun, objgrd user call-backs.
>>> main()
naginterfaces.library.opt.handle_solve_ssqp Python Example Results.
At the solution the objective function is 1.900124e+00.
"""
print(
'naginterfaces.library.opt.handle_solve_ssqp Python Example Results.'
)
# The nonlinear objective:
cb_objfun = lambda x, inform: (
(
(x[0]+x[1]+x[2])*(x[0]+x[1]+x[2]) + 3.0*x[2] + 5.0*x[3] +
np.cos(0.01*x[0]) - 1.0
),
0,
)
def cb_objgrd(x, fdx, inform):
"""The gradient of the objective."""
summ = 2.0*(x[0]+x[1]+x[2])
fdx[0] = summ - 0.01*np.sin(0.01*x[0])
fdx[1] = summ
fdx[2] = summ + 3.0
fdx[3] = 5.0
return 0
# The nonlinear constraints function:
cb_confun = lambda x, _ncnln, inform: (
[
x[0]*x[0] + x[1]*x[1] + x[2], x[1]*x[1]*x[1]*x[1] + x[3],
],
0,
)
def cb_congrd(x, gdx, inform):
"""The Jacobian of the nonlinear constraints."""
gdx[:] = [
2.0*x[0],
2.0*x[1],
1.0,
4.0*x[1]*x[1]*x[1],
1.0,
]
return inform
# The initial guess:
x = [1., 2., 3., 4.]
nvar = len(x)
nnzu = 2*nvar
# Create a handle for the problem:
handle = opt.handle_init(nvar)
# Define the bounds:
opt.handle_set_simplebounds(
handle,
bl=[-1.e20, -1.e20, 0., 0.], bu=[1.e20]*nvar,
)
# Define the non-linear objective:
opt.handle_set_nlnobj(
handle,
idxfd=[1, 2, 3, 4],
)
# Define the linear constraints:
opt.handle_set_linconstr(
handle,
bl=[0.], bu=[1.e20],
irowb=[1, 1],
icolb=[1, 2],
b=[2.0, 4.0],
)
nnzu += 2*1
# Define the nonlinear constraints:
opt.handle_set_nlnconstr(
handle,
bl=[2., 4.], bu=[2., 4.],
irowgd=[1, 1, 1, 2, 2], icolgd=[1, 2, 3, 2, 4],
)
nnzu += 2*2
opt.handle_opt_set(
handle, 'Verify Derivatives = Yes',
)
opt.handle_opt_set(
handle, 'Print Solution = No',
)
opt.handle_opt_set(
handle, 'Print Level = 0',
)
# Optionally, define variable x(4) to be linear
# Hinting which variables are linear in problems with many
# variables can speed up performance
opt.handle_set_property(handle, "Linear", 4)
# Solve the problem:
sn_soln = opt.handle_solve_ssqp(
handle, x,
objfun=cb_objfun, objgrd=cb_objgrd, confun=cb_confun, congrd=cb_congrd
)
print(
'At the solution the objective function is {:.6e}.'.format(
sn_soln.rinfo[0]
)
)
# Destroy the handle:
opt.handle_free(handle)
if __name__ == '__main__':
import doctest
import sys
sys.exit(
doctest.testmod(
None, verbose=True, report=False,
optionflags=doctest.ELLIPSIS | doctest.REPORT_NDIFF,
).failed
)