NAG Library Function Document

1Purpose

nag_opt_check_2nd_deriv (e04hdc) checks that a user-supplied function for calculating second derivatives of an objective function is consistent with a user-supplied function for calculating the corresponding first derivatives.

2Specification

 #include #include
void  nag_opt_check_2nd_deriv (Integer n,
 void (*objfun)(Integer n, const double x[], double *objf, double g[], Nag_Comm *comm),
 void (*hessfun)(Integer n, const double x[], double h[], double hd[], Nag_Comm *comm),
const double x[], double g[], double hesl[], double hesd[], Nag_Comm *comm, NagError *fail)

3Description

Routines for minimizing a function $F\left({x}_{1},{x}_{2},\dots ,{x}_{n}\right)$ of the variables ${x}_{1},{x}_{2},\dots ,{x}_{n}$ may require you to provide a subroutine to evaluate the second derivatives of $F$. nag_opt_check_2nd_deriv (e04hdc) is designed to check the second derivatives calculated by such user-supplied functions. As well as the function to be checked (hessfun), you must supply a function (objfun) to evaluate the first derivatives, and a point $x={\left({x}_{1},{x}_{2},\dots ,{x}_{n}\right)}^{\mathrm{T}}$ at which the checks will be made. Note that nag_opt_check_2nd_deriv (e04hdc) checks functions of the form required for nag_opt_bounds_2nd_deriv (e04lbc).
nag_opt_check_2nd_deriv (e04hdc) first calls objfun and hessfun to evaluate the first and second derivatives of $F$ at $x$. The user-supplied Hessian matrix ($H$, say) is projected onto two orthogonal vectors $y$ and $z$ to give the scalars ${y}^{\mathrm{T}}Hy$ and ${z}^{\mathrm{T}}Hz$ respectively. The same projections of the Hessian matrix are also estimated by finite differences, giving
 $p = yT g x + hy - yT g x / h and q = zT g x + hz - zT g x / h$
respectively, where $g\left(\right)$ denotes the vector of first derivatives at the point in brackets and $h$ is a small positive scalar. If the relative difference between $p$ and ${y}^{\mathrm{T}}Hy$ or between $q$ and ${z}^{\mathrm{T}}Hz$ is judged too large, an error indicator is set.
None.

5Arguments

1:    $\mathbf{n}$IntegerInput
On entry: the number $n$ of independent variables in the objective function.
Constraint: ${\mathbf{n}}\ge 1$.
2:    $\mathbf{objfun}$function, supplied by the userExternal Function
objfun must evaluate the function $F\left(x\right)$ and its first derivatives $\frac{\partial F}{\partial {x}_{j}}$ at a specified point. (However, if you do not wish to calculate $F$ or its first derivatives at a particular point, there is the option of setting an argument to cause nag_opt_check_2nd_deriv (e04hdc) to terminate immediately.)
The specification of objfun is:
 void objfun (Integer n, const double x[], double *objf, double g[], Nag_Comm *comm)
1:    $\mathbf{n}$IntegerInput
On entry: the number $n$ of variables.
2:    $\mathbf{x}\left[{\mathbf{n}}\right]$const doubleInput
On entry: the point $x$ at which the value of $F$, or $F$ and the $\frac{\partial F}{\partial {x}_{j}}$, are required.
3:    $\mathbf{objf}$double *Output
On exit: objfun must set objf to the value of the objective function $F$ at the current point $x$. If it is not possible to evaluate $F$ then objfun should assign a negative value to $\mathbf{comm}\mathbf{\to }\mathbf{flag}$; nag_opt_check_2nd_deriv (e04hdc) will then terminate.
4:    $\mathbf{g}\left[{\mathbf{n}}\right]$doubleOutput
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number, objfun must set ${\mathbf{g}}\left[j-1\right]$ to the value of the first derivative $\frac{\partial F}{\partial {x}_{j}}$ at the current point $x$ for $j=1,2,\dots ,n$.
5:    $\mathbf{comm}$Nag_Comm *
Pointer to structure of type Nag_Comm; the following members are relevant to objfun.
flagIntegerOutput
On exit: if objfun resets $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ to some negative number then nag_opt_check_2nd_deriv (e04hdc) will terminate immediately with the error indicator NE_USER_STOP. If fail is supplied to nag_opt_check_2nd_deriv (e04hdc) ${\mathbf{fail}}\mathbf{.}\mathbf{errnum}$ will be set to your setting of $\mathbf{comm}\mathbf{\to }\mathbf{flag}$.
firstNag_BooleanInput
On entry: will be set to Nag_TRUE on the first call to objfun and Nag_FALSE for all subsequent calls.
nfIntegerInput
On entry: the number of evaluations of the objective function; this value will be equal to the number of calls made to objfun (including the current one).
userdouble *
iuserInteger *
pPointer
The type Pointer will be void * with a C compiler that defines void * and char * otherwise.
Before calling nag_opt_check_2nd_deriv (e04hdc) these pointers may be allocated memory and initialized with various quantities for use by objfun when called from nag_opt_check_2nd_deriv (e04hdc).
Note: objfun should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by nag_opt_check_2nd_deriv (e04hdc). If your code inadvertently does return any NaNs or infinities, nag_opt_check_2nd_deriv (e04hdc) is likely to produce unexpected results.
Note: nag_opt_check_deriv (e04hcc) should be used to check the first derivatives calculated by objfun before nag_opt_check_2nd_deriv (e04hdc) is used to check the second derivatives, since nag_opt_check_2nd_deriv (e04hdc) assumes that the first derivatives are correct.
3:    $\mathbf{hessfun}$function, supplied by the userExternal Function
hessfun must calculate the second derivatives of $F\left(x\right)$ at any point $x$. (As with objfun there is the option of causing nag_opt_check_2nd_deriv (e04hdc) to terminate immediately.)
The specification of hessfun is:
 void hessfun (Integer n, const double x[], double h[], double hd[], Nag_Comm *comm)
1:    $\mathbf{n}$IntegerInput
On entry: the number $n$ of variables in the objective function.
2:    $\mathbf{x}\left[{\mathbf{n}}\right]$const doubleInput
On entry: the point $x$ at which the second derivatives are required.
3:    $\mathbf{h}\left[{\mathbf{n}}×\left({\mathbf{n}}-1\right)/2\right]$doubleOutput
This array is allocated internally by nag_opt_check_2nd_deriv (e04hdc).
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number hessfun must place the strict lower triangle of the second derivative matrix of $F$ (evaluated at the point $x$) in h, stored by rows, i.e., set
• ${\mathbf{h}}\left[\left(i-1\right)\left(i-2\right)/2+j-1\right]={\frac{{\partial }^{2}F}{\partial {x}_{i}\partial {x}_{j}}|}_{x={\mathbf{x}}}\text{, for ​}i=2,3,\dots ,n\text{; ​}j=1,2,\dots ,i-1\text{.}$
(The upper triangle is not required because the matrix is symmetric.)
4:    $\mathbf{hd}\left[{\mathbf{n}}\right]$doubleInput/Output
On entry: the value of $\frac{\partial F}{\partial {x}_{\mathit{j}}}$ at the point $x$, for $\mathit{j}=1,2,\dots ,n$. These values may be useful in the evaluation of the second derivatives.
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number hessfun must place the diagonal elements of the second derivative matrix of $F$ (evaluated at the point $x$) in hd, i.e., set
 $hd j-1 = ∂2F ∂xj2 x=x , for ​ j = 1 , 2 , … , n .$
5:    $\mathbf{comm}$Nag_Comm *
Pointer to structure of type Nag_Comm; the following members are relevant to objfun.
flagIntegerOutput
On exit: if hessfun resets $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ to some negative number then nag_opt_check_2nd_deriv (e04hdc) will terminate immediately with the error indicator NE_USER_STOP. If fail is supplied to nag_opt_check_2nd_deriv (e04hdc) ${\mathbf{fail}}\mathbf{.}\mathbf{errnum}$ will be set to your setting of $\mathbf{comm}\mathbf{\to }\mathbf{flag}$.
firstNag_BooleanInput
On entry: will be set to Nag_TRUE on the first call to hessfun and Nag_FALSE for all subsequent calls.
nfIntegerInput
On entry: the number of evaluations of the objective function; this value will be equal to the number of calls made to hessfun (including the current one).
userdouble *
iuserInteger *
pPointer
The type Pointer will be void * with a C compiler that defines void * and char * otherwise.
Before calling nag_opt_check_2nd_deriv (e04hdc) these pointers may be allocated memory and initialized with various quantities for use by hessfun when called from nag_opt_check_2nd_deriv (e04hdc).
Note: hessfun should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by nag_opt_check_2nd_deriv (e04hdc). If your code inadvertently does return any NaNs or infinities, nag_opt_check_2nd_deriv (e04hdc) is likely to produce unexpected results.
Note: the array x must not be changed by hessfun.
4:    $\mathbf{x}\left[{\mathbf{n}}\right]$const doubleInput
On entry: ${\mathbf{x}}\left[\mathit{j}-1\right]$, for $\mathit{j}=1,2,\dots ,n$ must contain the coordinates of a suitable point at which to check the derivatives calculated by objfun. ‘Obvious’ settings, such as 0.0 or 1.0, should not be used since, at such particular points, incorrect terms may take correct values (particularly zero), so that errors could go undetected. Similarly, it is advisable that no two elements of x should be the same.
5:    $\mathbf{g}\left[{\mathbf{n}}\right]$doubleOutput
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number ${\mathbf{g}}\left[j-1\right]$ contains the value of the first derivative $\frac{\partial F}{\partial {x}_{j}}$ at the point given in $x$, as calculated by objfun for $j=1,2,\dots ,n$.
6:    $\mathbf{hesl}\left[{\mathbf{n}}×\left({\mathbf{n}}-1\right)/2\right]$doubleOutput
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number hesl contains the strict lower triangle of the second derivative matrix of $F$, as evaluated by hessfun at the point given in x, stored by rows.
7:    $\mathbf{hesd}\left[{\mathbf{n}}\right]$doubleOutput
On exit: unless $\mathbf{comm}\mathbf{\to }\mathbf{flag}$ is reset to a negative number hesd contains the diagonal elements of the second derivative matrix of $F$, as evaluated by hessfun at the point given in x.
8:    $\mathbf{comm}$Nag_Comm *Input/Output
Note: comm is a NAG defined type (see Section 3.3.1.1 in How to Use the NAG Library and its Documentation).
On entry/exit: structure containing pointers for communication to user-supplied functions; see the above description of objfun for details. If you do not need to make use of this communication feature the null pointer NAGCOMM_NULL may be used in the call to nag_opt_check_2nd_deriv (e04hdc); comm will then be declared internally for use in calls to user-supplied functions.
9:    $\mathbf{fail}$NagError *Input/Output
The NAG error argument (see Section 3.7 in How to Use the NAG Library and its Documentation).

6Error Indicators and Warnings

NE_ALLOC_FAIL
Dynamic memory allocation failed.
NE_DERIV_ERRORS
Large errors were found in the derivatives of the objective function.
NE_INT_ARG_LT
On entry, ${\mathbf{n}}=〈\mathit{\text{value}}〉$.
Constraint: ${\mathbf{n}}\ge 1$.
NE_USER_STOP
User requested termination, user flag value $\text{}=〈\mathit{\text{value}}〉$.

7Accuracy

The error NE_DERIV_ERRORS is returned if
 $yT H y - p ≥ h × yT Hy + 1.0 or zT H z - q ≥ h × zT Hz + 1.0$
where $h$ is set equal to $\sqrt{\epsilon }$ ($\epsilon$ being the machine precision as given by nag_machine_precision (X02AJC) and other quantities are as defined in Section 3.

8Parallelism and Performance

nag_opt_check_2nd_deriv (e04hdc) is not threaded in any implementation.

nag_opt_check_2nd_deriv (e04hdc) calls hessfun once and objfun three times.

10Example

Suppose that it is intended to use nag_opt_bounds_2nd_deriv (e04lbc) to minimize
 $F = x 1 + 10 x 2 2 + 5 x 3 - x 4 2 + x 2 - 2 x 3 4 + 10 x 1 - x 4 4 .$
The following program could be used to check the second derivatives calculated by the required hessfun function. (The call of nag_opt_check_2nd_deriv (e04hdc) is preceded by a call of nag_opt_check_deriv (e04hcc) to check the function objfun which calculates the first derivatives.)

10.1Program Text

Program Text (e04hdce.c)

None.

10.3Program Results

Program Results (e04hdce.r)

© The Numerical Algorithms Group Ltd, Oxford, UK. 2017