Home > manopt > core > getCost.m

getCost

PURPOSE ^

Computes the cost function at x.

SYNOPSIS ^

function cost = getCost(problem, x, storedb, key)

DESCRIPTION ^

 Computes the cost function at x.

 function cost = getCost(problem, x)
 function cost = getCost(problem, x, storedb)
 function cost = getCost(problem, x, storedb, key)

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

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

 See also: canGetCost

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function cost = getCost(problem, x, storedb, key)
0002 % Computes the cost function at x.
0003 %
0004 % function cost = getCost(problem, x)
0005 % function cost = getCost(problem, x, storedb)
0006 % function cost = getCost(problem, x, storedb, key)
0007 %
0008 % Returns the value at x of the cost function described in the problem
0009 % structure.
0010 %
0011 % storedb is a StoreDB object, key is the StoreDB key to point x.
0012 %
0013 % See also: canGetCost
0014 
0015 % This file is part of Manopt: www.manopt.org.
0016 % Original author: Nicolas Boumal, Dec. 30, 2012.
0017 % Contributors:
0018 % Change log:
0019 %
0020 %   April 3, 2015 (NB):
0021 %       Works with the new StoreDB class system.
0022 %
0023 %   Aug. 2, 2018 (NB):
0024 %       The value of the cost function is now always cached.
0025 %
0026 %   Sep. 6, 2018 (NB):
0027 %       If the gradient is computed too (because we had to call costgrad
0028 %       with the store as input as per the user's request), then the
0029 %       gradient is also cached.
0030 
0031     % Allow omission of the key, and even of storedb.
0032     if ~exist('key', 'var')
0033         if ~exist('storedb', 'var')
0034             storedb = StoreDB();
0035         end
0036         key = storedb.getNewKey();
0037     end
0038 
0039 
0040     % Contrary to most similar functions, here, we get the store by
0041     % default. This is for the caching functionality described below.
0042     store = storedb.getWithShared(key);
0043     store_is_stale = false;
0044 
0045     % If the cost function has been computed before at this point (and its
0046     % memory is still in storedb), then we just look up the value.
0047     if isfield(store, 'cost__')
0048         cost = store.cost__;
0049         return;
0050     end
0051     
0052 
0053     if isfield(problem, 'cost')
0054     %% Compute the cost function using cost.
0055     
0056         % Check whether this function wants to deal with storedb or not.
0057         switch nargin(problem.cost)
0058             case 1
0059                 cost = problem.cost(x);
0060             case 2
0061                 [cost, store] = problem.cost(x, store);
0062             case 3
0063                 % Pass along the whole storedb (by reference), with key.
0064                 cost = problem.cost(x, storedb, key);
0065                 % The store structure in storedb might have been modified
0066                 % (since it is passed by reference), so before caching
0067                 % we'll have to update (see below).
0068                 store_is_stale = true;
0069             otherwise
0070                 up = MException('manopt:getCost:badcost', ...
0071                     'cost should accept 1, 2 or 3 inputs.');
0072                 throw(up);
0073         end
0074         
0075     elseif isfield(problem, 'costgrad')
0076     %% Compute the cost function using costgrad.
0077     
0078         % Check whether this function wants to deal with storedb or not.
0079         switch nargin(problem.costgrad)
0080             case 1
0081                 cost = problem.costgrad(x);
0082             case 2
0083                 [cost, grad, store] = problem.costgrad(x, store);
0084             case 3
0085                 % Pass along the whole storedb (by reference), with key.
0086                 cost = problem.costgrad(x, storedb, key);
0087                 store_is_stale = true;
0088             otherwise
0089                 up = MException('manopt:getCost:badcostgrad', ...
0090                     'costgrad should accept 1, 2 or 3 inputs.');
0091                 throw(up);
0092         end
0093 
0094     else
0095     %% Abandon computing the cost function.
0096 
0097         up = MException('manopt:getCost:fail', ...
0098             ['The problem description is not explicit enough to ' ...
0099              'compute the cost.']);
0100         throw(up);
0101         
0102     end
0103     
0104     % If we are not sure that the store structure is up to date, update.
0105     if store_is_stale
0106         store = storedb.getWithShared(key);
0107     end
0108     
0109     % Cache here.
0110     store.cost__ = cost;
0111     
0112     % If we got the cost via costgrad and it took the store as input, then
0113     % the gradient has also been computed and we can cache it.
0114     if exist('grad', 'var')
0115         store.grad__ = grad;
0116     end
0117 
0118     storedb.setWithShared(store, key);
0119     
0120 end

Generated on Fri 30-Sep-2022 13:18:25 by m2html © 2005