Home > manopt > core > getEuclideanGradient.m

getEuclideanGradient

PURPOSE ^

Computes the Euclidean gradient of the cost function at x.

SYNOPSIS ^

function egrad = getEuclideanGradient(problem, x, storedb, key)

DESCRIPTION ^

 Computes the Euclidean gradient of the cost function at x.

 function egrad = getEuclideanGradient(problem, x)
 function egrad = getEuclideanGradient(problem, x, storedb)
 function egrad = getEuclideanGradient(problem, x, storedb, key)

 Returns the Euclidean gradient at x of the cost function described in the
 problem structure.

 storedb is a StoreDB object, key is the StoreDB key to point x.

 Because computing the Hessian based on the Euclidean Hessian will require
 the Euclidean gradient every time, to avoid overly redundant
 computations, if the egrad function does not use the store caching
 capabilites, this implements an automatic caching functionality. Writing
 egrad to accept the optional store or storedb parameter will disable
 automatic caching, but allow user controlled caching.

 See also: getGradient canGetGradient canGetEuclideanGradient

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function egrad = getEuclideanGradient(problem, x, storedb, key)
0002 % Computes the Euclidean gradient of the cost function at x.
0003 %
0004 % function egrad = getEuclideanGradient(problem, x)
0005 % function egrad = getEuclideanGradient(problem, x, storedb)
0006 % function egrad = getEuclideanGradient(problem, x, storedb, key)
0007 %
0008 % Returns the Euclidean gradient at x of the cost function described in the
0009 % problem structure.
0010 %
0011 % storedb is a StoreDB object, key is the StoreDB key to point x.
0012 %
0013 % Because computing the Hessian based on the Euclidean Hessian will require
0014 % the Euclidean gradient every time, to avoid overly redundant
0015 % computations, if the egrad function does not use the store caching
0016 % capabilites, this implements an automatic caching functionality. Writing
0017 % egrad to accept the optional store or storedb parameter will disable
0018 % automatic caching, but allow user controlled caching.
0019 %
0020 % See also: getGradient canGetGradient canGetEuclideanGradient
0021 
0022 % This file is part of Manopt: www.manopt.org.
0023 % Original author: Nicolas Boumal, July 9, 2013.
0024 % Contributors:
0025 % Change log:
0026 %
0027 %   April 3, 2015 (NB):
0028 %       Works with the new StoreDB class system.
0029 %
0030 %   June 28, 2016 (NB):
0031 %       Added support for getPartialEuclideanGradient
0032 %
0033 %   July 26, 2018 (NB):
0034 %       The Euclidean gradient is now automatically cached if the Euclidean
0035 %       Hessian is also computable from the problem description. This
0036 %       differs from previous behavior where it would only be cached if
0037 %       problem.egrad did not accept store or storedb as input; the
0038 %       converse was taken as a sign that the user wants to deal with
0039 %       caching on their own, but in reality it proved more confusing than
0040 %       helpful.
0041 %
0042 %   Sep.  6, 2018 (NB):
0043 %       The Euclidean gradient is now always cached. Caching conditioned on
0044 %       the Euclidean Hessian being provided was problematic, because if no
0045 %       Hessian is provided at all, then the default fall-back of finite
0046 %       differences would be slowed down significantly without cache. Since
0047 %       the new storedb functionalities around storedb.remove() much reduce
0048 %       the number of stored stores, this should not be an issue.
0049 
0050     % Allow omission of the key, and even of storedb.
0051     if ~exist('key', 'var')
0052         if ~exist('storedb', 'var')
0053             storedb = StoreDB();
0054         end
0055         key = storedb.getNewKey();
0056     end
0057 
0058     % Contrary to most similar functions, here, we get the store by
0059     % default. This is for the special caching functionality described
0060     % below.
0061     store = storedb.getWithShared(key);
0062     store_is_stale = false;
0063 
0064     % We force caching of the Euclidean gradient. Look up first.
0065     force_egrad_caching = true;
0066     if force_egrad_caching && isfield(store, 'egrad__')
0067         egrad = store.egrad__;
0068         return;
0069     end
0070     
0071     if isfield(problem, 'egrad')
0072     %% Compute the Euclidean gradient using egrad.
0073     
0074         % Check whether this function wants to deal with storedb or not.
0075         switch nargin(problem.egrad)
0076             case 1
0077                 egrad = problem.egrad(x);
0078             case 2
0079                 [egrad, store] = problem.egrad(x, store);
0080             case 3
0081                 egrad = problem.egrad(x, storedb, key);
0082                 % The store structure in storedb might have been modified
0083                 % (since it is passed by reference), so before caching
0084                 % we'll have to update (see below).
0085                 store_is_stale = true;
0086             otherwise
0087                 up = MException('manopt:getEuclideanGradient:badegrad', ...
0088                     'egrad should accept 1, 2 or 3 inputs.');
0089                 throw(up);
0090         end
0091         
0092     elseif canGetPartialEuclideanGradient(problem)
0093     %% Compute the Euclidean gradient using a full partial Euclidean gradient.
0094         
0095         d = problem.ncostterms;
0096         egrad = getPartialEuclideanGradient(problem, x, 1:d, storedb, key);
0097         store_is_stale = true;
0098 
0099     else
0100     %% Abandon computing the Euclidean gradient
0101     
0102         up = MException('manopt:getEuclideanGradient:fail', ...
0103             ['The problem description is not explicit enough to ' ...
0104              'compute the Euclidean gradient of the cost.']);
0105         throw(up);
0106         
0107     end
0108     
0109     % If we are not sure that the store structure is up to date, update.
0110     if store_is_stale
0111         store = storedb.getWithShared(key);
0112     end
0113     
0114     % Cache here.
0115     if force_egrad_caching
0116         store.egrad__ = egrad;
0117     end
0118 
0119     storedb.setWithShared(store, key);
0120     
0121 end

Generated on Mon 10-Sep-2018 11:48:06 by m2html © 2005