Home > manopt > tools > checkgradient.m

checkgradient

PURPOSE ^

Checks the consistency of the cost function and the gradient.

SYNOPSIS ^

function checkgradient(problem, x, d)

DESCRIPTION ^

 Checks the consistency of the cost function and the gradient.

 function checkgradient(problem)
 function checkgradient(problem, x)
 function checkgradient(problem, x, d)

 checkgradient performs a numerical test to check that the gradient
 defined in the problem structure agrees up to first order with the cost
 function at some point x, along some direction d. The test is based on a
 truncated Taylor series (see online Manopt documentation).

 It is also tested that the gradient is indeed a tangent vector.
 
 Both x and d are optional and will be sampled at random if omitted.

 See also: checkdiff checkhessian

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function checkgradient(problem, x, d)
0002 % Checks the consistency of the cost function and the gradient.
0003 %
0004 % function checkgradient(problem)
0005 % function checkgradient(problem, x)
0006 % function checkgradient(problem, x, d)
0007 %
0008 % checkgradient performs a numerical test to check that the gradient
0009 % defined in the problem structure agrees up to first order with the cost
0010 % function at some point x, along some direction d. The test is based on a
0011 % truncated Taylor series (see online Manopt documentation).
0012 %
0013 % It is also tested that the gradient is indeed a tangent vector.
0014 %
0015 % Both x and d are optional and will be sampled at random if omitted.
0016 %
0017 % See also: checkdiff checkhessian
0018 
0019 % This file is part of Manopt: www.manopt.org.
0020 % Original author: Nicolas Boumal, Dec. 30, 2012.
0021 % Contributors:
0022 % Change log:
0023 %
0024 %   April 3, 2015 (NB):
0025 %       Works with the new StoreDB class system.
0026 %
0027 %   Nov. 1, 2016 (NB):
0028 %       Now calls checkdiff with force_gradient = true, instead of doing an
0029 %       rmfield of problem.diff. This became necessary after getGradient
0030 %       was updated to know how to compute the gradient from directional
0031 %       derivatives.
0032 
0033     
0034     % Verify that the problem description is sufficient.
0035     if ~canGetCost(problem)
0036         error('It seems no cost was provided.');
0037     end
0038     if ~canGetGradient(problem)
0039         warning('manopt:checkgradient:nograd', ...
0040                 'It seems no gradient was provided.');
0041     end
0042         
0043     x_isprovided = exist('x', 'var') && ~isempty(x);
0044     d_isprovided = exist('d', 'var') && ~isempty(d);
0045     
0046     if ~x_isprovided && d_isprovided
0047         error('If d is provided, x must be too, since d is tangent at x.');
0048     end
0049     
0050     % If x and / or d are not specified, pick them at random.
0051     if ~x_isprovided
0052         x = problem.M.rand();
0053     end
0054     if ~d_isprovided
0055         d = problem.M.randvec(x);
0056     end
0057 
0058     %% Check that the gradient yields a first order model of the cost.
0059     
0060     % Call checkdiff with force_gradient set to true, to force that
0061     % function to make a gradient call.
0062     checkdiff(problem, x, d, true);
0063     title(sprintf(['Gradient check.\nThe slope of the continuous line ' ...
0064                    'should match that of the dashed\n(reference) line ' ...
0065                    'over at least a few orders of magnitude for h.']));
0066     xlabel('h');
0067     ylabel('Approximation error');
0068     
0069     %% Try to check that the gradient is a tangent vector.
0070     if isfield(problem.M, 'tangent')
0071         storedb = StoreDB();
0072         key = storedb.getNewKey();
0073         grad = getGradient(problem, x, storedb, key);
0074         pgrad = problem.M.tangent(x, grad);
0075         residual = problem.M.lincomb(x, 1, grad, -1, pgrad);
0076         err = problem.M.norm(x, residual);
0077         fprintf('The residual should be 0, or very close. Residual: %g.\n', err);
0078         fprintf('If it is far from 0, then the gradient is not in the tangent space.\n');
0079     else
0080         fprintf(['Unfortunately, Manopt was unable to verify that the '...
0081                  'gradient is indeed a tangent vector.\nPlease verify ' ...
0082                  'this manually or implement the ''tangent'' function ' ...
0083                  'in your manifold structure.']);
0084     end
0085 
0086 end

Generated on Sat 12-Nov-2016 14:11:22 by m2html © 2005