hide long namesshow long names
hide short namesshow short names
Integer type:  int32  int64  nag_int  show int32  show int32  show int64  show int64  show nag_int  show nag_int

PDF version (NAG web site, 64-bit version, 64-bit version)
Chapter Contents
Chapter Introduction
NAG Toolbox

NAG Toolbox: nag_opt_lsq_check_deriv (e04ya)

Purpose

nag_opt_lsq_check_deriv (e04ya) checks that a user-supplied function for evaluating a vector of functions and the matrix of their first derivatives produces derivative values which are consistent with the function values calculated.

Syntax

[fvec, fjac, user, ifail] = e04ya(m, lsqfun, x, 'n', n, 'user', user)
[fvec, fjac, user, ifail] = nag_opt_lsq_check_deriv(m, lsqfun, x, 'n', n, 'user', user)
Note: the interface to this routine has changed since earlier releases of the toolbox:
Mark 22: liw, lw have been removed from the interface
Mark 24: drop w and iw, introduce user in main routine and all call-backs
.

Description

Routines for minimizing a sum of squares of mm nonlinear functions (or ‘residuals’), fi(x1,x2,,xn)fi(x1,x2,,xn), for i = 1,2,,mi=1,2,,m and mnmn, may require you to supply a function to evaluate the fifi and their first derivatives. nag_opt_lsq_check_deriv (e04ya) checks the derivatives calculated by such user-supplied functions, e.g., functions of the form required for nag_opt_lsq_uncon_quasi_deriv_comp (e04gb), nag_opt_lsq_uncon_mod_deriv_comp (e04gd) and nag_opt_lsq_uncon_mod_deriv2_comp (e04he). As well as the function to be checked (lsqfun), you must supply a point x = (x1,x2,,xn)T x = (x1,x2,,xn)T  at which the check will be made. nag_opt_lsq_check_deriv (e04ya) is essentially identical to CHKLSJ in the NPL Algorithms Library.
nag_opt_lsq_check_deriv (e04ya) first calls lsqfun to evaluate the fi(x)fi(x) and their first derivatives, and uses these to calculate the sum of squares F(x) = i = 1m[fi(x)]2F(x)=i=1 m [fi(x)]2, and its first derivatives gj = ( F )/( xj )|x gj = F x j | x , for j = 1,2,,nj=1,2,,n. The components of gg along two orthogonal directions (defined by unit vectors p1p1 and p2p2, say) are then calculated; these will be gTp1gTp1 and gTp2gTp2 respectively. The same components are also estimated by finite differences, giving quantities
vk = (F(x + hpk)F(x))/h,  k = 1,2
vk=F(x+hpk)-F(x)h,  k=1,2
where hh is a small positive scalar. If the relative difference between v1v1 and gTp1gTp1 or between v2v2 and gTp2gTp2 is judged too large, an error indicator is set.

References

None.

Parameters

Compulsory Input Parameters

1:     m – int64int32nag_int scalar
The number mm of residuals, fi(x)fi(x), and the number nn of variables, xjxj.
Constraint: 1nm1nm.
2:     lsqfun – function handle or string containing name of m-file
lsqfun must calculate the vector of values fi(x)fi(x) and their first derivatives (fi)/(xj) fi xj  at any point xx. (The minimization functions mentioned in Section [Description] give you the option of resetting a parameter to terminate immediately. nag_opt_lsq_check_deriv (e04ya) will also terminate immediately, without finishing the checking process, if the parameter in question is reset.)
[iflag, fvec, fjac, user] = lsqfun(iflag, m, n, xc, ldfjac, user)

Input Parameters

1:     iflag – int64int32nag_int scalar
To lsqfun, iflag will be set to 22.
2:     m – int64int32nag_int scalar
The numbers mm of residuals.
3:     n – int64int32nag_int scalar
The numbers nn of variables.
4:     xc(n) – double array
xx, the point at which the values of the fifi and the (fi)/(xj) fi xj  are required.
5:     ldfjac – int64int32nag_int scalar
The first dimension of the array fjac as declared in the (sub)program from which nag_opt_lsq_check_deriv (e04ya) is called.
6:     user – Any MATLAB object
lsqfun is called from nag_opt_lsq_check_deriv (e04ya) with the object supplied to nag_opt_lsq_check_deriv (e04ya).

Output Parameters

1:     iflag – int64int32nag_int scalar
If you reset iflag to some negative number in lsqfun and return control to nag_opt_lsq_check_deriv (e04ya), the function will terminate immediately with ifail set to your setting of iflag.
2:     fvec(m) – double array
Unless iflag is reset to a negative number, fvec(i)fveci must contain the value of fifi at the point xx, for i = 1,2,,mi=1,2,,m.
3:     fjac(ldfjac,n) – double array
ldfjacmldfjacm.
Unless iflag is reset to a negative number, fjac(i,j)fjacij must contain the value of (fi)/(xj) fi xj at the point xx, for i = 1,2,,mi=1,2,,m and j = 1,2,,nj=1,2,,n.
4:     user – Any MATLAB object
3:     x(n) – double array
n, the dimension of the array, must satisfy the constraint 1nm1nm.
x(j)xj, for j = 1,2,,nj=1,2,,n, must be set to the coordinates of a suitable point at which to check the derivatives calculated by lsqfun. ‘Obvious’ settings, such as 00 or 11, should not be used since, at such particular points, incorrect terms may take correct values (particularly zero), so that errors can go undetected. For a similar reason, it is preferable that no two elements of x should have the same value.

Optional Input Parameters

1:     n – int64int32nag_int scalar
Default: For n, the dimension of the array x.
The number mm of residuals, fi(x)fi(x), and the number nn of variables, xjxj.
Constraint: 1nm1nm.
2:     user – Any MATLAB object
user is not used by nag_opt_lsq_check_deriv (e04ya), but is passed to lsqfun. 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.

Input Parameters Omitted from the MATLAB Interface

ldfjac iuser liw w lw

Output Parameters

1:     fvec(m) – double array
Unless you set iflag negative in the first call of lsqfun, fvec(i)fveci contains the value of fifi at the point supplied by you in x, for i = 1,2,,mi=1,2,,m.
2:     fjac(ldfjac,n) – double array
ldfjacmldfjacm.
Unless you set iflag negative in the first call of lsqfun, fjac(i,j)fjacij contains the value of the first derivative (fi)/(xj) fi xj at the point given in x, as calculated by lsqfun, for i = 1,2,,mi=1,2,,m and j = 1,2,,nj=1,2,,n.
3:     user – Any MATLAB object
4:     ifail – int64int32nag_int scalar
ifail = 0ifail=0 unless the function detects an error (see [Error Indicators and Warnings]).

Error Indicators and Warnings

Note: nag_opt_lsq_check_deriv (e04ya) may return useful information for one or more of the following detected errors or warnings.
Errors or warnings detected by the function:

Cases prefixed with W are classified as warnings and do not generate an error of type NAG:error_n. See nag_issue_warnings.

W ifail < 0ifail<0
A negative value of ifail indicates an exit from nag_opt_lsq_check_deriv (e04ya) because you have set iflag negative in lsqfun. The setting of ifail will be the same as your setting of iflag. The check on lsqfun will not have been completed.
  ifail = 1ifail=1
On entry,m < nm<n,
orn < 1n<1,
orldfjac < mldfjac<m,
orliw < 1liw<1,
orlw < 3 × n + m + m × nlw<3×n+m+m×n.
W ifail = 2ifail=2
You should check carefully the derivation and programming of expressions for the (fi)/(xj) fi xj , because it is very unlikely that lsqfun is calculating them correctly.

Accuracy

ifail is set to 22 if
(vkgTpk)2 h × ((gTpk)2 + 1)
( vk - gT pk ) 2 h× ( ( gT pk ) 2 +1 )
for k = 1​ or ​2k=1​ or ​2. (See Section [Description] for definitions of the quantities involved.) The scalar hh is set equal to sqrt(ε)ε, where εε is the machine precision as given by nag_machine_precision (x02aj).

Further Comments

nag_opt_lsq_check_deriv (e04ya) calls lsqfun three times.
Before using nag_opt_lsq_check_deriv (e04ya) to check the calculation of the first derivatives, you should be confident that lsqfun is calculating the residuals correctly.
nag_opt_lsq_check_deriv (e04ya) only checks the derivatives calculated by a user-supplied function when iflag = 2iflag=2. So, if lsqfun is intended for use in conjunction with a minimization function which may set iflag to 11, you must check that, for given settings of the xc(j)xcj, lsqfun produces the same values for the (fi)/(xj) fi xj  when iflag is set to 11 as when iflag is set to 22.

Example

function nag_opt_lsq_check_deriv_example
m = int64(15);
x = [0.19; -1.34; 0.88];
y=[0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39];

t = [1.0, 15.0, 1.0;
     2.0, 14.0, 2.0;
     3.0, 13.0, 3.0;
     4.0, 12.0, 4.0;
     5.0, 11.0, 5.0;
     6.0, 10.0, 6.0;
     7.0, 9.0, 7.0;
     8.0, 8.0, 8.0;
     9.0, 7.0, 7.0;
     10.0, 6.0, 6.0;
     11.0, 5.0, 5.0;
     12.0, 4.0, 4.0;
     13.0, 3.0, 3.0;
     14.0, 2.0, 2.0;
     15.0, 1.0, 1.0];

user = {y; t};

[fvec, fjac, user, ifail] = nag_opt_lsq_check_deriv(m, @lsqfun, x, 'user', user)

function [iflag, fvecc, fjacc, user] = lsqfun(iflag, m, n, xc, ljc, user)
  y = user{1};
  t = user{2};

  fvecc = zeros(m, 1);
  fjacc = zeros(ljc, n);

  for i = 1:double(m)
    denom = xc(2)*t(i,2) + xc(3)*t(i,3);
    if (iflag ~= 1)
      fvecc(i) = xc(1) + t(i,1)/denom - y(i);
    end
    if (iflag ~= 0)
      fjacc(i,1) = 1;
      dummy = -1/(denom*denom);
      fjacc(i,2) = t(i,1)*t(i,2)*dummy;
      fjacc(i,3) = t(i,1)*t(i,3)*dummy;
    end
  end
 

fvec =

   -0.0020
   -0.1076
   -0.2330
   -0.3785
   -0.5836
   -0.8689
   -1.3464
   -2.3739
   -2.9750
   -4.0132
   -5.3226
   -7.2917
  -10.5703
  -17.1274
  -36.8087


fjac =

    1.0000   -0.0406   -0.0027
    1.0000   -0.0969   -0.0138
    1.0000   -0.1785   -0.0412
    1.0000   -0.3043   -0.1014
    1.0000   -0.5144   -0.2338
    1.0000   -0.9100   -0.5460
    1.0000   -1.8098   -1.4076
    1.0000   -4.7259   -4.7259
    1.0000   -6.0762   -6.0762
    1.0000   -7.8765   -7.8765
    1.0000  -10.3970  -10.3970
    1.0000  -14.1777  -14.1777
    1.0000  -20.4789  -20.4789
    1.0000  -33.0813  -33.0813
    1.0000  -70.8885  -70.8885


user = 

    [ 1x15 double]
    [15x3  double]


ifail =

                    0


function e04ya_example
m = int64(15);
x = [0.19; -1.34; 0.88];
y=[0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,0.37,0.58,0.73,0.96,1.34,2.10,4.39];

t = [1.0, 15.0, 1.0;
     2.0, 14.0, 2.0;
     3.0, 13.0, 3.0;
     4.0, 12.0, 4.0;
     5.0, 11.0, 5.0;
     6.0, 10.0, 6.0;
     7.0, 9.0, 7.0;
     8.0, 8.0, 8.0;
     9.0, 7.0, 7.0;
     10.0, 6.0, 6.0;
     11.0, 5.0, 5.0;
     12.0, 4.0, 4.0;
     13.0, 3.0, 3.0;
     14.0, 2.0, 2.0;
     15.0, 1.0, 1.0];

user = {y; t};

[fvec, fjac, user, ifail] = e04ya(m, @lsqfun, x, 'user', user)

function [iflag, fvecc, fjacc, user] = lsqfun(iflag, m, n, xc, ljc, user)
  y = user{1};
  t = user{2};

  fvecc = zeros(m, 1);
  fjacc = zeros(ljc, n);

  for i = 1:double(m)
    denom = xc(2)*t(i,2) + xc(3)*t(i,3);
    if (iflag ~= 1)
      fvecc(i) = xc(1) + t(i,1)/denom - y(i);
    end
    if (iflag ~= 0)
      fjacc(i,1) = 1;
      dummy = -1/(denom*denom);
      fjacc(i,2) = t(i,1)*t(i,2)*dummy;
      fjacc(i,3) = t(i,1)*t(i,3)*dummy;
    end
  end
 

fvec =

   -0.0020
   -0.1076
   -0.2330
   -0.3785
   -0.5836
   -0.8689
   -1.3464
   -2.3739
   -2.9750
   -4.0132
   -5.3226
   -7.2917
  -10.5703
  -17.1274
  -36.8087


fjac =

    1.0000   -0.0406   -0.0027
    1.0000   -0.0969   -0.0138
    1.0000   -0.1785   -0.0412
    1.0000   -0.3043   -0.1014
    1.0000   -0.5144   -0.2338
    1.0000   -0.9100   -0.5460
    1.0000   -1.8098   -1.4076
    1.0000   -4.7259   -4.7259
    1.0000   -6.0762   -6.0762
    1.0000   -7.8765   -7.8765
    1.0000  -10.3970  -10.3970
    1.0000  -14.1777  -14.1777
    1.0000  -20.4789  -20.4789
    1.0000  -33.0813  -33.0813
    1.0000  -70.8885  -70.8885


user = 

    [ 1x15 double]
    [15x3  double]


ifail =

                    0



PDF version (NAG web site, 64-bit version, 64-bit version)
Chapter Contents
Chapter Introduction
NAG Toolbox

© The Numerical Algorithms Group Ltd, Oxford, UK. 2009–2013