Home > manopt > tools > statsfunhelper.m

statsfunhelper

PURPOSE ^

Helper tool to create a statsfun for the options structure of solvers.

SYNOPSIS ^

function statsfun = statsfunhelper(inp1, inp2)

DESCRIPTION ^

 Helper tool to create a statsfun for the options structure of solvers.

 function statsfun = statsfunhelper(name, fun)
 function statsfun = statsfunhelper(S)

 Usage with (name, fun):

 Input 1: name is a string which is a valid field name (no spaces, starts
 with a letter or an underscore, only alphanumeric characters and
 underscores).
 
 Input2: fun is a function handle with one output and 1 to 4 inputs, as
 follows (your choice):
 
  fun(x)  or  fun(problem, x)  or  
  fun(problem, x, stats)  or  fun(problem, x, stats, store)
 
 where the inputs are the ones that would be given to options.statsfun, as
 described in the help of the solver used. Typically, x is the point on
 the manifold at the current iterate, problem is the Manopt problem
 structure, stats is all the current statistics recorded for that iterate
 and store is the cache structure at the current iterate.

 When calling a Manopt solver with the options structure, such as for
 example with:

  [x, xcost, info] = steepestdescent(problem, [], options);

 you may set a field of the options structure as follows:

  options.statsfun = statsfunhelper('nameofthefield', fun);

 As a result, at each iteration, the stats structure will contain a field
 stats.nameofthefield with the value returned by the call to fun at that
 iterate. The stats structures are stored in the struct-array info.
 As an example, if the value returned by fun is a scalar, then
 [info.nameofthefield] is a vector containing all returned values.


 Usage with S:

 The input S is a structure. For each field of S, say S.field, the stats
 structure will be augmented with stats.field = fun(..), where fun is the
 function handle stored in S.field, and with the same conventions as
 above. This version allows to record more than one bit of information at
 each iteration. Example:
 
  metrics.nameofthefield = fun;
  metrics.othername = otherfun;
  options.statsfun = statsfunhelper(metrics);

 The different function handles (here, fun and otherfun) can take 1 to 4
 inputs too, and they do not have to take the same number of inputs.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function statsfun = statsfunhelper(inp1, inp2)
0002 % Helper tool to create a statsfun for the options structure of solvers.
0003 %
0004 % function statsfun = statsfunhelper(name, fun)
0005 % function statsfun = statsfunhelper(S)
0006 %
0007 % Usage with (name, fun):
0008 %
0009 % Input 1: name is a string which is a valid field name (no spaces, starts
0010 % with a letter or an underscore, only alphanumeric characters and
0011 % underscores).
0012 %
0013 % Input2: fun is a function handle with one output and 1 to 4 inputs, as
0014 % follows (your choice):
0015 %
0016 %  fun(x)  or  fun(problem, x)  or
0017 %  fun(problem, x, stats)  or  fun(problem, x, stats, store)
0018 %
0019 % where the inputs are the ones that would be given to options.statsfun, as
0020 % described in the help of the solver used. Typically, x is the point on
0021 % the manifold at the current iterate, problem is the Manopt problem
0022 % structure, stats is all the current statistics recorded for that iterate
0023 % and store is the cache structure at the current iterate.
0024 %
0025 % When calling a Manopt solver with the options structure, such as for
0026 % example with:
0027 %
0028 %  [x, xcost, info] = steepestdescent(problem, [], options);
0029 %
0030 % you may set a field of the options structure as follows:
0031 %
0032 %  options.statsfun = statsfunhelper('nameofthefield', fun);
0033 %
0034 % As a result, at each iteration, the stats structure will contain a field
0035 % stats.nameofthefield with the value returned by the call to fun at that
0036 % iterate. The stats structures are stored in the struct-array info.
0037 % As an example, if the value returned by fun is a scalar, then
0038 % [info.nameofthefield] is a vector containing all returned values.
0039 %
0040 %
0041 % Usage with S:
0042 %
0043 % The input S is a structure. For each field of S, say S.field, the stats
0044 % structure will be augmented with stats.field = fun(..), where fun is the
0045 % function handle stored in S.field, and with the same conventions as
0046 % above. This version allows to record more than one bit of information at
0047 % each iteration. Example:
0048 %
0049 %  metrics.nameofthefield = fun;
0050 %  metrics.othername = otherfun;
0051 %  options.statsfun = statsfunhelper(metrics);
0052 %
0053 % The different function handles (here, fun and otherfun) can take 1 to 4
0054 % inputs too, and they do not have to take the same number of inputs.
0055 
0056 % This file is part of Manopt: www.manopt.org.
0057 % Original author: Nicolas Boumal, Dec. 17, 2014.
0058 % Contributors:
0059 % Change log:
0060 %     Jan 2, 2021 (NB):
0061 %         Passing S to thestatsfun explicitly for compatibility with Octave 6.
0062 
0063     if (nargin == 1) && isstruct(inp1)
0064         S = inp1;
0065     elseif (nargin == 2)
0066         S = struct(inp1, inp2);
0067     else
0068         error('statsfunhelper takes 1 or 2 inputs. If 1 input, it must be a structure.');
0069     end
0070 
0071     statsfun = @(problem, x, stats, store) thestatsfun(S, problem, x, stats, store);
0072 
0073     
0074     function stats = thestatsfun(S, problem, x, stats, store)
0075         names = fieldnames(S);
0076         for it = 1 : length(names)
0077             name = names{it};
0078             fun = S.(name);
0079             switch nargin(fun)
0080                 case 1
0081                     stats.(name) = fun(x);
0082                 case 2
0083                     stats.(name) = fun(problem, x);
0084                 case 3
0085                     stats.(name) = fun(problem, x, stats);
0086                 case 4
0087                     stats.(name) = fun(problem, x, stats, store);
0088                 otherwise
0089                     error('The functions passed to statsfunhelper must take 1 to 4 inputs.');
0090             end
0091         end
0092     end
0093 
0094 end

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