#!/usr/bin/env python3
"``naginterfaces.library.opt.lsq_gencon_deriv`` Python Example."
# NAG Copyright 2018-2019.
# pylint: disable=invalid-name,too-many-arguments,too-many-locals
from math import exp
import numpy as np
from naginterfaces.library import opt
[docs]def main():
"""
Example for :func:`naginterfaces.library.opt.lsq_gencon_deriv`.
Minimum of a sum of squares, nonlinear constraints, dense, active-set SQP
method, using function values and optionally first derivatives.
>>> main()
naginterfaces.library.opt.lsq_gencon_deriv Python Example Results.
Minimizing Problem 57 from Hock and Schittkowski's
'Test Examples for Nonlinear Scripting Codes'.
Final function value is 1.42298348615e-02.
"""
print(
'naginterfaces.library.opt.lsq_gencon_deriv Python Example Results.'
)
print('Minimizing Problem 57 from Hock and Schittkowski\'s')
print('\'Test Examples for Nonlinear Scripting Codes\'.')
def cb_confun(mode, needc, x, cjac, nstate):
"The nonlinear constraint and its first derivatives."
if needc[0] <= 0 or mode == 1:
c = [0.]*len(needc)
elif mode in [0, 2]:
c = [0.49*x[1] - x[0]*x[1]]
if needc[0] <= 0:
return c
if mode in [1, 2]:
cjac[0, 0] = -x[1]
cjac[0, 1] = -x[0] + 0.49
return c
def cb_objfun(mode, needfi, x, fjac, nstate):
"""
The (two-variable) sum of squares function to minimize,
and its first derivatives.
"""
# The set of 44 'a' data values:
a = [
8., 8., 10., 10., 10., 10., 12., 12., 12.,
12., 14., 14., 14., 16., 16., 16., 18., 18.,
20., 20., 20., 22.,
22., 22., 24., 24., 24., 26., 26., 26., 28.,
28., 30., 30., 30., 32., 32., 34., 36., 36.,
38., 38., 40., 42.,
]
m = fjac.shape[0]
f = np.empty(m)
for fi in range(m):
exp_term = exp(-x[1]*(a[fi] - 8.))
if needfi == fi + 1 or mode in [0, 2]:
f[fi] = x[0] + (0.49 - x[0])*exp_term
if needfi == fi + 1:
return f
if mode in [1, 2]:
fjac[fi, 0] = 1. - exp_term
fjac[fi, 1] = -(0.49 - x[0])*(a[fi] - 8.)*exp_term
return f
# Initialize the communication structure:
comm = opt.nlp1_init('lsq_gencon_deriv')
# The configuration for this problem.
# One nonlinear constraint (defined by confun):
ncnln = 1
# The linear constraints:
a = [[1., 1.]]
# The bounds on x and on the constraints:
bl = [0.4, -4., 1., 0.09]
# 'Infinite' upper bounds:
bu = [1.e25]*len(bl)
# The coefficients of the constant vector in the objective:
y = [
0.49, 0.49, 0.48, 0.47, 0.48, 0.47, 0.46, 0.46, 0.45, 0.43, 0.45,
0.43, 0.43, 0.44, 0.43, 0.43, 0.46, 0.45, 0.42, 0.42, 0.43, 0.41,
0.41, 0.40, 0.42, 0.40, 0.40, 0.41, 0.40, 0.41, 0.41, 0.40, 0.40,
0.40, 0.38, 0.41, 0.40, 0.40, 0.41, 0.38, 0.40, 0.40, 0.39, 0.39
]
# Initial estimate of the solution:
x = [0.4, 0.]
n = len(x)
# Zero the initial nonlinear-constraint Jacobian, which has an effect
# here because of the default setting of 'Derivative Level' (level 3):
cjac = np.zeros((ncnln, n))
# Solve the problem:
objf = opt.lsq_gencon_deriv(
bl, bu, y, cb_objfun, x, comm, a=a, confun=cb_confun, cjac=cjac,
).objf
print('Final function value is {:.11e}.'.format(objf))
if __name__ == '__main__':
main()
import doctest
import sys
sys.exit(
doctest.testmod(
None, verbose=True, report=False,
optionflags=doctest.ELLIPSIS | doctest.REPORT_NDIFF,
).failed
)