annotate toolboxes/FullBNT-1.0.7/netlab3.3/gradchek.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function [gradient, delta] = gradchek(w, func, grad, varargin)
wolffd@0 2 %GRADCHEK Checks a user-defined gradient function using finite differences.
wolffd@0 3 %
wolffd@0 4 % Description
wolffd@0 5 % This function is intended as a utility for other netlab functions
wolffd@0 6 % (particularly optimisation functions) to use. It enables the user to
wolffd@0 7 % check whether a gradient calculation has been correctly implmented
wolffd@0 8 % for a given function. GRADCHEK(W, FUNC, GRAD) checks how accurate the
wolffd@0 9 % gradient GRAD of a function FUNC is at a parameter vector X. A
wolffd@0 10 % central difference formula with step size 1.0e-6 is used, and the
wolffd@0 11 % results for both gradient function and finite difference
wolffd@0 12 % approximation are printed. The optional return value GRADIENT is the
wolffd@0 13 % gradient calculated using the function GRAD and the return value
wolffd@0 14 % DELTA is the difference between the functional and finite difference
wolffd@0 15 % methods of calculating the graident.
wolffd@0 16 %
wolffd@0 17 % GRADCHEK(X, FUNC, GRAD, P1, P2, ...) allows additional arguments to
wolffd@0 18 % be passed to FUNC and GRAD.
wolffd@0 19 %
wolffd@0 20 % See also
wolffd@0 21 % CONJGRAD, GRADDESC, HMC, OLGD, QUASINEW, SCG
wolffd@0 22 %
wolffd@0 23
wolffd@0 24 % Copyright (c) Ian T Nabney (1996-2001)
wolffd@0 25
wolffd@0 26 % Reasonable value for step size
wolffd@0 27 epsilon = 1.0e-6;
wolffd@0 28
wolffd@0 29 func = fcnchk(func, length(varargin));
wolffd@0 30 grad = fcnchk(grad, length(varargin));
wolffd@0 31
wolffd@0 32 % Treat
wolffd@0 33 nparams = length(w);
wolffd@0 34 deltaf = zeros(1, nparams);
wolffd@0 35 step = zeros(1, nparams);
wolffd@0 36 for i = 1:nparams
wolffd@0 37 % Move a small way in the ith coordinate of w
wolffd@0 38 step(i) = 1.0;
wolffd@0 39 fplus = feval('linef', epsilon, func, w, step, varargin{:});
wolffd@0 40 fminus = feval('linef', -epsilon, func, w, step, varargin{:});
wolffd@0 41 % Use central difference formula for approximation
wolffd@0 42 deltaf(i) = 0.5*(fplus - fminus)/epsilon;
wolffd@0 43 step(i) = 0.0;
wolffd@0 44 end
wolffd@0 45 gradient = feval(grad, w, varargin{:});
wolffd@0 46 fprintf(1, 'Checking gradient ...\n\n');
wolffd@0 47 delta = gradient - deltaf;
wolffd@0 48 fprintf(1, ' analytic diffs delta\n\n');
wolffd@0 49 disp([gradient', deltaf', delta'])