# NAG CL Interfacee04hdc (check_​deriv2)

## 1Purpose

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
void  e04hdc (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)
The function may be called by the names: e04hdc, nag_opt_check_deriv2 or nag_opt_check_2nd_deriv.

## 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$. 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 e04hdc checks functions of the form required for e04lbc.
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}$Integer Input
On entry: the number $n$ of independent variables in the objective function.
Constraint: ${\mathbf{n}}\ge 1$.
2: $\mathbf{objfun}$function, supplied by the user External 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 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}$Integer Input
On entry: the number $n$ of variables.
2: $\mathbf{x}\left[{\mathbf{n}}\right]$const double Input
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}$; e04hdc will then terminate.
4: $\mathbf{g}\left[{\mathbf{n}}\right]$double Output
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 e04hdc will terminate immediately with the error indicator NE_USER_STOP. If fail is supplied to 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 e04hdc these pointers may be allocated memory and initialized with various quantities for use by objfun when called from e04hdc.
Note: objfun should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by e04hdc. If your code inadvertently does return any NaNs or infinities, e04hdc is likely to produce unexpected results.
Note: e04hcc should be used to check the first derivatives calculated by objfun before e04hdc is used to check the second derivatives, since e04hdc assumes that the first derivatives are correct.
3: $\mathbf{hessfun}$function, supplied by the user External 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 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}$Integer Input
On entry: the number $n$ of variables in the objective function.
2: $\mathbf{x}\left[{\mathbf{n}}\right]$const double Input
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]$double Output
This array is allocated internally by 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]$double Input/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 e04hdc will terminate immediately with the error indicator NE_USER_STOP. If fail is supplied to 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 e04hdc these pointers may be allocated memory and initialized with various quantities for use by hessfun when called from e04hdc.
Note: hessfun should not return floating-point NaN (Not a Number) or infinity values, since these are not handled by e04hdc. If your code inadvertently does return any NaNs or infinities, 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 double Input
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]$double Output
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]$double Output
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]$double Output
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.1.1 in the Introduction to the NAG Library CL Interface).
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 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 7 in the Introduction to the NAG Library CL Interface).

## 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 X02AJC and other quantities are as defined in Section 3.

## 8Parallelism and Performance

e04hdc is not threaded in any implementation.

e04hdc calls hessfun once and objfun three times.

## 10Example

Suppose that it is intended to use 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 e04hdc is preceded by a call of 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)