Apply the hook function to possibly replace the current x (for solvers). function [newx, newkey, info, hooked] = applyHook(problem, x, storedb, key, options, info, last) Applies the options.hook user-supplied function (if there is one) to the current x of a solver. If this leads to a change, than the boolean 'hooked' is true, and newx, newkey are different from x, key. Otherwise, newx, newkey are equal to x, key, and the boolean 'hooked' is false. storedb is a StoreDB object, key is the StoreDB key to point x; likewise for newkey and newx. info and last work the same way as in stoppingcriterion. The hook is called at the beginning of each iteration, after saving the stats information, but before evaluating stopping criteria. Time spent in the hook is included in the solver's reported computation time. This function takes care of logging the boolean 'hooked' in the info struct-array. (This requires the field 'hooked' to exist in the first place: applyStatsfun ensures this.) Stored data about the input point in storeDB may be deleted if the point is actually hooked. The options.hook function handle can have these prototypes: [newx, hooked] = hook(problem, x) [newx, newkey, hooked] = hook(problem, x, storedb, key) [newx, newkey, hooked, stats] = hook(problem, x, storedb, key, stats) See also: applyStatsfun stoppingcriterion
0001 function [newx, newkey, info, hooked] = applyHook(problem, x, storedb, key, options, info, last) 0002 % Apply the hook function to possibly replace the current x (for solvers). 0003 % 0004 % function [newx, newkey, info, hooked] = 0005 % applyHook(problem, x, storedb, key, options, info, last) 0006 % 0007 % Applies the options.hook user-supplied function (if there is one) to the 0008 % current x of a solver. If this leads to a change, than the boolean 0009 % 'hooked' is true, and newx, newkey are different from x, key. Otherwise, 0010 % newx, newkey are equal to x, key, and the boolean 'hooked' is false. 0011 % 0012 % storedb is a StoreDB object, key is the StoreDB key to point x; likewise 0013 % for newkey and newx. 0014 % 0015 % info and last work the same way as in stoppingcriterion. 0016 % 0017 % The hook is called at the beginning of each iteration, after saving the 0018 % stats information, but before evaluating stopping criteria. Time spent in 0019 % the hook is included in the solver's reported computation time. 0020 % 0021 % This function takes care of logging the boolean 'hooked' in the info 0022 % struct-array. (This requires the field 'hooked' to exist in the first 0023 % place: applyStatsfun ensures this.) 0024 % 0025 % Stored data about the input point in storeDB may be deleted if the point 0026 % is actually hooked. 0027 % 0028 % The options.hook function handle can have these prototypes: 0029 % 0030 % [newx, hooked] = hook(problem, x) 0031 % [newx, newkey, hooked] = hook(problem, x, storedb, key) 0032 % [newx, newkey, hooked, stats] = hook(problem, x, storedb, key, stats) 0033 % 0034 % See also: applyStatsfun stoppingcriterion 0035 0036 % This file is part of Manopt: www.manopt.org. 0037 % Original author: Nicolas Boumal, July 19, 2020. 0038 % Contributors: Eitan Levin 0039 % Change log: 0040 0041 if isfield(options, 'hook') 0042 0043 nin = nargin(options.hook); 0044 nout = nargout(options.hook); 0045 0046 if nin == 2 && nout == 2 0047 [newx, hooked] = options.hook(problem, x); 0048 if hooked 0049 storedb.remove(key); 0050 newkey = storedb.getNewKey(); 0051 else 0052 newkey = key; 0053 end 0054 elseif nin == 4 && nout == 3 0055 [newx, newkey, hooked] = options.hook(problem, x, storedb, key); 0056 if hooked 0057 storedb.removefirstifdifferent(key, newkey); 0058 end 0059 elseif nin == 5 && nout == 4 0060 stats = info(last); 0061 [newx, newkey, hooked, stats] = ... 0062 options.hook(problem, x, storedb, key, stats); 0063 info(last) = stats; 0064 if hooked 0065 storedb.removefirstifdifferent(key, newkey); 0066 end 0067 else 0068 newx = x; 0069 newkey = key; 0070 hooked = false; 0071 warning('manopt:hook', ... 0072 'options.hook unused: wrong number of inputs/outputs'); 0073 end 0074 0075 else 0076 newx = x; 0077 newkey = key; 0078 hooked = false; 0079 end 0080 0081 % Always register whether or not the point was hooked (i.e., changed). 0082 % This field is first created in applyStatsfun. 0083 stats = info(last); 0084 stats.hooked = hooked; 0085 info(last) = stats; 0086 0087 end