Integer type:  int32  int64  nag_int  show int32  show int32  show int64  show int64  show nag_int  show nag_int

Chapter Contents
Chapter Introduction
NAG Toolbox

# NAG Toolbox: nag_opt_nlp2_sparse_jacobian (e04vj)

## Purpose

nag_opt_nlp2_sparse_jacobian (e04vj) may be used before nag_opt_nlp2_sparse_solve (e04vh) to determine the sparsity pattern for the Jacobian.

## Syntax

[iafun, javar, nea, a, igfun, jgvar, neg, cw, iw, rw, user, ifail] = e04vj(nf, usrfun, lena, leng, x, xlow, xupp, cw, iw, rw, 'n', n, 'user', user)
[iafun, javar, nea, a, igfun, jgvar, neg, cw, iw, rw, user, ifail] = nag_opt_nlp2_sparse_jacobian(nf, usrfun, lena, leng, x, xlow, xupp, cw, iw, rw, 'n', n, 'user', user)
Note: the interface to this routine has changed since earlier releases of the toolbox:
 At Mark 22: lencw, leniw and lenrw were removed from the interface

## Description

When using nag_opt_nlp2_sparse_solve (e04vh), if you set the optional parameter ${\mathbf{Derivative Option}}=0$ and usrfun provides none of the derivatives, you may need to call nag_opt_nlp2_sparse_jacobian (e04vj) to determine the input arrays iafun, javar, a, igfun and jgvar. These arrays define the pattern of nonzeros in the Jacobian matrix. A typical sequence of calls could be
```[cw, iw, rw, ifail] = e04vg();
[..., cw, iw, rw, ...] = e04vj(...);
[cw, iw, rw, ifail] = e04vl('Derivative Option = 0', cw, iw, rw);
[..., cw, iw, rw, ...] = e04vh(...);```
nag_opt_nlp2_sparse_jacobian (e04vj) determines the sparsity pattern for the Jacobian and identifies the constant elements automatically. To do so, nag_opt_nlp2_sparse_jacobian (e04vj) approximates the problem functions, $F\left(x\right)$, at three random perturbations of the given initial point $x$. If an element of the approximate Jacobian is the same at all three points, then it is taken to be constant. If it is zero, it is taken to be identically zero. Since the random points are not chosen close together, the heuristic will correctly classify the Jacobian elements in the vast majority of cases. In general, nag_opt_nlp2_sparse_jacobian (e04vj) finds that the Jacobian can be permuted to the form:
 $Gx A3 A2 A4 ,$
where ${A}_{2}$, ${A}_{3}$ and ${A}_{4}$ are constant. Note that $G\left(x\right)$ might contain elements that are also constant, but nag_opt_nlp2_sparse_jacobian (e04vj) must classify them as nonlinear. This is because nag_opt_nlp2_sparse_solve (e04vh) ‘removes’ linear variables from the calculation of $F$ by setting them to zero before calling usrfun. A knowledgeable user would be able to move such elements from $F\left(x\right)$ in usrfun and enter them as part of iafun, javar and a for nag_opt_nlp2_sparse_solve (e04vh).

## References

Hock W and Schittkowski K (1981) Test Examples for Nonlinear Programming Codes. Lecture Notes in Economics and Mathematical Systems 187 Springer–Verlag

## Parameters

Note: all optional parameters are described in detail in Description of the s in nag_opt_nlp2_sparse_solve (e04vh).

### Compulsory Input Parameters

1:     $\mathrm{nf}$int64int32nag_int scalar
$\mathit{nf}$, the number of problem functions in $F\left(x\right)$, including the objective function (if any) and the linear and nonlinear constraints. Simple upper and lower bounds on $x$ can be defined using the arguments xlow and xupp and should not be included in $F$.
Constraint: ${\mathbf{nf}}>0$.
2:     $\mathrm{usrfun}$ – function handle or string containing name of m-file
usrfun must define the problem functions $F\left(x\right)$. This function is passed to nag_opt_nlp2_sparse_jacobian (e04vj) as the external argument usrfun.
[status, f, g, user] = usrfun(status, n, x, needf, nf, f, needg, leng, g, user)

Input Parameters

1:     $\mathrm{status}$int64int32nag_int scalar
Indicates the first call to usrfun.
${\mathbf{status}}=0$
There is nothing special about the current call to usrfun.
${\mathbf{status}}=1$
nag_opt_nlp2_sparse_jacobian (e04vj) is calling your function for the first time. Some data may need to be input or computed and saved.
2:     $\mathrm{n}$int64int32nag_int scalar
$n$, the number of variables, as defined in the call to nag_opt_nlp2_sparse_jacobian (e04vj).
3:     $\mathrm{x}\left({\mathbf{n}}\right)$ – double array
The variables $x$ at which the problem functions are to be calculated. The array $x$ must not be altered.
4:     $\mathrm{needf}$int64int32nag_int scalar
Indicates if f must be assigned during the call to usrfun (see f).
5:     $\mathrm{nf}$int64int32nag_int scalar
$\mathit{nf}$, the number of problem functions.
6:     $\mathrm{f}\left({\mathbf{nf}}\right)$ – double array
This will be set by nag_opt_nlp2_sparse_jacobian (e04vj).
7:     $\mathrm{needg}$int64int32nag_int scalar
nag_opt_nlp2_sparse_jacobian (e04vj) will call usrfun with ${\mathbf{needg}}=0$ to indicate that g is not required.
8:     $\mathrm{leng}$int64int32nag_int scalar
The dimension of the array g.
9:     $\mathrm{g}\left({\mathbf{leng}}\right)$ – double array
Concerns the calculations of the derivatives of the function $f\left(x\right)$.
10:   $\mathrm{user}$ – Any MATLAB object
usrfun is called from nag_opt_nlp2_sparse_jacobian (e04vj) with the object supplied to nag_opt_nlp2_sparse_jacobian (e04vj).

Output Parameters

1:     $\mathrm{status}$int64int32nag_int scalar
May be used to indicate that you are unable to evaluate $F$ at the current $x$. (For example, the problem functions may not be defined there).
nag_opt_nlp2_sparse_jacobian (e04vj) evaluates $F\left(x\right)$ at random perturbation of the initial point $x$, say ${x}_{p}$. If the functions cannot be evaluated at ${x}_{p}$, you can set ${\mathbf{status}}=-1$, nag_opt_nlp2_sparse_jacobian (e04vj) will use another random perturbation.
If for some reason you wish to terminate the current problem, set ${\mathbf{status}}\le -2$.
2:     $\mathrm{f}\left({\mathbf{nf}}\right)$ – double array
The computed $F\left(x\right)$ according to the setting of needf.
If ${\mathbf{needf}}=0$, f is not required and is ignored.
If ${\mathbf{needf}}>0$, the components of $F\left(x\right)$ must be calculated and assigned to f. nag_opt_nlp2_sparse_jacobian (e04vj) will always call usrfun with ${\mathbf{needf}}>0$.
To simplify the code, you may ignore the value of needf and compute $F\left(x\right)$ on every entry to usrfun.
3:     $\mathrm{g}\left({\mathbf{leng}}\right)$ – double array
nag_opt_nlp2_sparse_jacobian (e04vj) will always call usrfun with ${\mathbf{needg}}=0$: g is not required to be set on exit but must be declared correctly.
4:     $\mathrm{user}$ – Any MATLAB object
3:     $\mathrm{lena}$int64int32nag_int scalar
The dimension of the arrays iafun, javar and a that hold $\left(i,j,{A}_{ij}\right)$. lena should be an overestimate of the number of elements in the linear part of the Jacobian.
Constraint: ${\mathbf{lena}}\ge 1$.
4:     $\mathrm{leng}$int64int32nag_int scalar
The dimension of the arrays igfun and jgvar that define the varying Jacobian elements $\left(i,j,{G}_{ij}\right)$. leng should be an overestimate of the number of elements in the nonlinear part of the Jacobian.
Constraint: ${\mathbf{leng}}\ge 1$.
5:     $\mathrm{x}\left({\mathbf{n}}\right)$ – double array
An initial estimate of the variables $x$. The contents of $x$ will be used by nag_opt_nlp2_sparse_jacobian (e04vj) in the call of usrfun, and so each element of x should be within the bounds given by xlow and xupp.
6:     $\mathrm{xlow}\left({\mathbf{n}}\right)$ – double array
7:     $\mathrm{xupp}\left({\mathbf{n}}\right)$ – double array
Contain the lower and upper bounds ${l}_{x}$ and ${u}_{x}$ on the variables $x$.
To specify a nonexistent lower bound ${\left[{l}_{x}\right]}_{j}=-\infty$, set ${\mathbf{xlow}}\left(j\right)\le -\mathit{bigbnd}$, where $\mathit{bigbnd}$ is the optional parameter Infinite Bound Size. To specify a nonexistent upper bound ${\mathbf{xupp}}\left(j\right)\ge \mathit{bigbnd}$.
To fix the $j$th variable (say, ${x}_{j}=\beta$, where $\left|\beta \right|<\mathit{bigbnd}$), set ${\mathbf{xlow}}\left(j\right)={\mathbf{xupp}}\left(j\right)=\beta$.
8:     $\mathrm{cw}\left(\mathit{lencw}\right)$ – cell array of strings
lencw, the dimension of the array, must satisfy the constraint $\mathit{lencw}\ge 600$.
Constraint: $\mathit{lencw}\ge 600$.
9:     $\mathrm{iw}\left(\mathit{leniw}\right)$int64int32nag_int array
leniw, the dimension of the array, must satisfy the constraint $\mathit{leniw}\ge 600$.
Constraint: $\mathit{leniw}\ge 600$.
10:   $\mathrm{rw}\left(\mathit{lenrw}\right)$ – double array
lenrw, the dimension of the array, must satisfy the constraint $\mathit{lenrw}\ge 600$.
Constraint: $\mathit{lenrw}\ge 600$.

### Optional Input Parameters

1:     $\mathrm{n}$int64int32nag_int scalar
Default: the dimension of the arrays x, xlow, xupp. (An error is raised if these dimensions are not equal.)
$n$, the number of variables.
Constraint: ${\mathbf{n}}>0$.
2:     $\mathrm{user}$ – Any MATLAB object
user is not used by nag_opt_nlp2_sparse_jacobian (e04vj), but is passed to usrfun. Note that for large objects it may be more efficient to use a global variable which is accessible from the m-files than to use user.

### Output Parameters

1:     $\mathrm{iafun}\left({\mathbf{lena}}\right)$int64int32nag_int array
2:     $\mathrm{javar}\left({\mathbf{lena}}\right)$int64int32nag_int array
Define the coordinates $\left(i,j\right)$ and values ${A}_{ij}$ of the nonzero elements of the linear part $A$ of the function $F\left(x\right)=f\left(x\right)+Ax$.
In particular, nea triples $\left({\mathbf{iafun}}\left(k\right),{\mathbf{javar}}\left(k\right),{\mathbf{a}}\left(k\right)\right)$ define the row and column indices $i={\mathbf{iafun}}\left(k\right)$ and $j={\mathbf{javar}}\left(k\right)$ of the element ${A}_{ij}={\mathbf{a}}\left(k\right)$.
3:     $\mathrm{nea}$int64int32nag_int scalar
Is the number of nonzero entries in $A$ such that $F\left(x\right)=f\left(x\right)+Ax$.
4:     $\mathrm{a}\left({\mathbf{lena}}\right)$ – double array
Define the coordinates $\left(i,j\right)$ and values ${A}_{ij}$ of the nonzero elements of the linear part $A$ of the function $F\left(x\right)=f\left(x\right)+Ax$.
In particular, nea triples $\left({\mathbf{iafun}}\left(k\right),{\mathbf{javar}}\left(k\right),{\mathbf{a}}\left(k\right)\right)$ define the row and column indices $i={\mathbf{iafun}}\left(k\right)$ and $j={\mathbf{javar}}\left(k\right)$ of the element ${A}_{ij}={\mathbf{a}}\left(k\right)$.
5:     $\mathrm{igfun}\left({\mathbf{leng}}\right)$int64int32nag_int array
6:     $\mathrm{jgvar}\left({\mathbf{leng}}\right)$int64int32nag_int array
Define the coordinates $\left(i,j\right)$ of the nonzero elements of $G$, the nonlinear part of the derivatives $J\left(x\right)=G\left(x\right)+A$ of the function $F\left(x\right)=f\left(x\right)+Ax$.
7:     $\mathrm{neg}$int64int32nag_int scalar
The number of nonzero entries in $G$.
8:     $\mathrm{cw}\left(\mathit{lencw}\right)$ – cell array of strings
${\mathbf{cw}}=\mathbf{state}.\text{cw}$$\mathit{lencw}=600$.
Communication array, used to store information between calls to nag_opt_nlp2_sparse_jacobian (e04vj).
9:     $\mathrm{iw}\left(\mathit{leniw}\right)$int64int32nag_int array
${\mathbf{iw}}=\mathbf{state}.\text{iw}$$\mathit{leniw}=600$.
Communication array, used to store information between calls to nag_opt_nlp2_sparse_jacobian (e04vj).
10:   $\mathrm{rw}\left(\mathit{lenrw}\right)$ – double array
${\mathbf{rw}}=\mathbf{state}.\text{rw}$$\mathit{lenrw}=600$.
Communication array, used to store information between calls to nag_opt_nlp2_sparse_jacobian (e04vj).
11:   $\mathrm{user}$ – Any MATLAB object
12:   $\mathrm{ifail}$int64int32nag_int scalar
${\mathbf{ifail}}={\mathbf{0}}$ unless the function detects an error (see Error Indicators and Warnings).

## Error Indicators and Warnings

Errors or warnings detected by the function:
${\mathbf{ifail}}=1$
Constraint: $\mathit{lencw}\ge 600$.
Constraint: $\mathit{leniw}\ge 600$.
Constraint: $\mathit{lenrw}\ge 600$.
The initialization function nag_opt_nlp2_sparse_init (e04vg) has not been called.
${\mathbf{ifail}}=2$
Constraint: ${\mathbf{lena}}\ge 1$.
Constraint: ${\mathbf{leng}}\ge 1$.
${\mathbf{ifail}}=3$
User-supplied function usrfun indicates that functions are undefined near given point x.
You have indicated that the problem functions are undefined by setting ${\mathbf{status}}=-1$ on exit from usrfun. This exit occurs if nag_opt_nlp2_sparse_jacobian (e04vj) is unable to find a point at which the functions are defined.
${\mathbf{ifail}}=4$
User-supplied function usrfun requested termination.
You have indicated the wish to terminate the call to nag_opt_nlp2_sparse_jacobian (e04vj) by setting status to a value $\text{}<-1$ on exit from usrfun.
${\mathbf{ifail}}=5$
Either lena or leng is too small.
${\mathbf{ifail}}=6$
Cannot estimate Jacobian structure at given point x.
${\mathbf{ifail}}=7$
Internal error.
${\mathbf{ifail}}=8$
${\mathbf{ifail}}=-99$
${\mathbf{ifail}}=-399$
Your licence key may have expired or may not have been installed correctly.
${\mathbf{ifail}}=-999$
Dynamic memory allocation failed.

Not applicable.

None.

## Example

This example shows how to call nag_opt_nlp2_sparse_jacobian (e04vj) to determine the sparsity pattern of the Jacobian before calling nag_opt_nlp2_sparse_solve (e04vh) to solve a sparse nonlinear programming problem without providing the Jacobian information in usrfun.
It is a reformulation of Problem 74 from Hock and Schittkowski (1981) and involves the minimization of the nonlinear function
 $fx = 10-6 x33 + 23 × 10-6 x43+3 x3+2 x4$
subject to the bounds
 $-0.55≤x1≤ 0.55, -0.55≤x2≤ 0.55, 0≤x3≤ 1200, 0≤x4≤ 1200,$
to the nonlinear constraints
 $1000sin-x1-0.25+1000sin-x2-0.25-x3 = -894.8, 1000sinx1-0.25+1000sinx1-x2-0.25-x4 = -894.8, 1000sinx2-0.25+1000sinx2-x1-0.25 = -1294.8,$
and to the linear constraints
 $-x1+x2≥-0.55, -x1-x2≥-0.55.$
The initial point, which is infeasible, is
 $x0 = 0, 0, 0, 0 T ,$
and $f\left({x}_{0}\right)=0$.
The optimal solution (to five figures) is
 $x*=0.11887,-0.39623,679.94,1026.0T,$
and $f\left({x}^{*}\right)=5126.4$. All the nonlinear constraints are active at the solution.
The formulation of the problem combines the constraints and the objective into a single vector ($F$).
 $F = 1000 sin -x1 - 0.25 + 1000 sin -x2 - 0.25 - x3 1000 sin x1 - 0.25 + 1000 sin x1 - x2 - 0.25 - x4 1000 sin x2 - 0.25 + 1000 sin x2 - x1 - 0.25 -x1 + x2 x1 - x2 10-6 x33 + 23 × 10-6 x43 + 3x3 + 2x4$
```function e04vj_example

fprintf('e04vj example results\n\n');

nf   = int64(6);
lena = int64(300);
leng = int64(300);
x    = [ 0;     0;       0;     0];
xlow = [-0.55; -0.55;    0;     0];
xupp = [ 0.55;  0.55; 1200;  1200];

[cw, iw, rw, ifail] = e04vg;

[iarow, iacol, nea, a, igrow, igcol, neg, cw, iw, rw, cuser, ifail] = ...
e04vj(...
nf, @usrfun, lena, leng, x, xlow, xupp, cw, iw, rw);

fprintf(' Matrix A:\n');
fprintf(' Non-zero entries = %3d\n',nea);
fprintf(' values         : ');
fprintf('%3.0f',a(1:nea));
fprintf('\n row indices    : ');
fprintf('%3d',iarow(1:nea));
fprintf('\n column indices : ');
fprintf('%3d',iacol(1:nea));
fprintf('\n\n Matrix G:\n');
fprintf(' Non-zero entries = %3d\n',neg);
fprintf(' row indices    : ');
fprintf('%3d',igrow(1:neg));
fprintf('\n column indices : ');
fprintf('%3d',igcol(1:neg));
fprintf('\n');

function [status, f, g, user] = ...
usrfun(status, n, x, needf, nf, f, needg, leng, g, user)

% Always called with needf > 0
f(1) = 1000*sin(-x(1)-0.25) + 1000*sin(-x(2) -0.25) - x(3);
f(2) = 1000*sin(x(1)-0.25) + 1000*sin(x(1)-x(2) -0.25) - x(4);
f(3) = 1000*sin(x(2)-x(1)-0.25) + 1000*sin(x(2) -0.25);
f(4) = -x(1) + x(2);
f(5) = x(1) - x(2);
f(6) = 1.0d-6*x(3)^3 + 2.0d-6*x(4)^3/3 + 3*x(3) + 2*x(4);

% Always called with needg=0
```
```e04vj example results

Matrix A:
Non-zero entries =   4
values         :  -1  1  1 -1
row indices    :   4  5  4  5
column indices :   1  1  2  2

Matrix G:
Non-zero entries =  10
row indices    :   1  2  3  1  2  3  6  6  1  2
column indices :   1  1  1  2  2  2  3  4  3  4
```