#!/usr/bin/env python3
"``naginterfaces.library.opt.nlp1_sparse_solve`` Python Example."
# NAG Copyright 2017-2022.
# pylint: disable=invalid-name,too-many-locals
from math import cos, sin
import warnings
import numpy as np
from naginterfaces.base import utils
from naginterfaces.library import opt
[docs]def main():
"""
Example for :func:`naginterfaces.library.opt.nlp1_sparse_solve`.
Sparse NLP.
>>> main()
naginterfaces.library.opt.nlp1_sparse_solve Python Example Results.
Solve Hock and Schittkowski Problem 74.
Final objective value is 5.1264981e+03
"""
print(
'naginterfaces.library.opt.nlp1_sparse_solve Python Example Results.'
)
print('Solve Hock and Schittkowski Problem 74.')
def cb_confun(mode, ncnln, x, fjac, _nstate):
"""The nonlinear constraints."""
if mode in [0, 2]:
f = [
1000.*sin(-x[0]-0.25) + 1000.*sin(-x[1]-0.25),
1000.*sin(x[0]-0.25) + 1000.*sin(x[0]-x[1]-0.25),
1000.*sin(x[1]-0.25) + 1000.*sin(x[1]-x[0]-0.25),
]
else:
f = np.empty(ncnln)
if mode in [1, 2]:
fjac[:] = [
-1000.*cos(-x[0]-0.25),
1000.*cos(x[0]-0.25) + 1000.*cos(x[0]-x[1]-0.25),
-1000.*cos(x[1]-x[0]-0.25),
-1000.*cos(-x[1]-0.25),
-1000.*cos(x[0]-x[1]-0.25),
1000.*cos(x[1]-x[0]-0.25) + 1000.*cos(x[1]-0.25),
]
return 0, f, fjac
def cb_objfun(mode, x, objgrd, _nstate):
"""The objective function."""
if mode in [0, 2]:
objf = 1.e-6*x[2]**3 + 2.e-6*x[3]**3/3.
else:
objf = 0.
if mode in [1, 2]:
objgrd[:] = [
0.,
0.,
3.e-6*x[2]**2,
2.e-6*x[3]**2,
]
return 0, objf, objgrd
# Silence deprecation warning:
warnings.simplefilter('ignore', utils.NagDeprecatedWarning)
# Initialize the solver:
comm = opt.nlp1_init('nlp1_sparse_solve')
# There are three nonlinear constraints defined by cb_confun:
ncnln = 3
# There are six general constraints:
m = 6
# The numbers of nonlinear variables:
nonln = 4
njnln = 2
# The Jacobian A stored by columns:
a = [
1e+25, 1e+25, 1e+25, -1.0, 1.0,
1e+25, 1e+25, 1e+25, 1.0, -1.0,
-1.0, 3.0, -1.0, 2.0,
]
# The packing information for A:
ha = [
1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
1, 6,
2, 6,
]
ka = [1, 6, 11, 13, 15]
n = len(ka) - 1
# Denote a free row in A:
iobj = 6
# The bounds:
bl = [
-0.55, -0.55, 0., 0.,
-894.8, -894.8, -1294.8,
-0.55, -0.55,
-1e+25,
]
bu = [
0.55, 0.55, 1200., 1200.,
-894.8, -894.8, -1294.8,
1e+25, 1.e+25,
1e+25,
]
# Initial guess:
xs = [0.]*(n+m)
# Cold start:
start = 'Cold'
# Row and column names:
names = [
'Varble 1', 'Varble 2', 'Varble 3', 'Varble 4',
'NlnCon 1', 'NlnCon 2', 'NlnCon 3',
'LinCon 1', 'LinCon 2',
'Free Row',
]
# No superbasics to specify:
ns = 0
istate = np.zeros(n + m, dtype=utils.EngineIntNumPyType)
clamda = np.zeros(n + m)
# Form the main argument list for the routine.
# We perform a query call first using the routine's defaults
# for leniz and lenz to determine their minimum required values.
# For the basis factors in this problem, twice the minimum is
# sufficient.
nlp_args = [
m, ncnln, nonln, njnln, iobj,
a, ha, ka, bl, bu, start,
names, ns, xs, istate, clamda, comm,
]
# Silence warnings from the query call:
warnings.simplefilter('ignore', utils.NagAlgorithmicWarning)
soln_q = opt.nlp1_sparse_solve(
*nlp_args, confun=cb_confun, objfun=cb_objfun
)
# Restore warnings verbosity:
warnings.simplefilter('always', utils.NagAlgorithmicWarning)
obj = opt.nlp1_sparse_solve(
*nlp_args, confun=cb_confun, objfun=cb_objfun,
leniz=2*soln_q.miniz, lenz=2*soln_q.minz
).obj
print('Final objective value is {:.7e}'.format(obj))
if __name__ == '__main__':
import doctest
import sys
sys.exit(
doctest.testmod(
None, verbose=True, report=False,
optionflags=doctest.REPORT_NDIFF,
).failed
)