Debug Output
Debug output can easily be added to any solver run. On the high level interfaces, like gradient_descent, you can just use the debug= keyword.
Manopt.DebugAction — TypeDebugActionA DebugAction is a small functor to print/issue debug output. The usual call is given by (p,o,i) -> s that performs the debug based on a Problem p, Options o and the current iterate i.
By convention i=0 is interpreted as "For Initialization only", i.e. only debug info that prints initialization reacts, i<0 triggers updates of variables internally but does not trigger any output. Finally typemin(Int) is used to indicate a call from stop_solver! that returns true afterwards.
Fields (assumed by subtypes to exist)
printmethod to perform the actual print. Can for example be set to a file export,
or to @info. The default is the print function on the default Base.stdout.
Manopt.DebugChange — TypeDebugChange()debug for the amount of change of the iterate (stored in get_iterate(o) of the Options) during the last iteration. See DebugEntryChange for the general case
Keyword Parameters
storage– (StoreOptionsAction( (:Iterate,) )) – (eventually shared) the storage of the previous actionprefix– ("Last Change:") prefix of the debug output (ignored if you setformat)io– (stdout) default steream to print the debug to.format- ("$prefix %f") format to print the output using an sprintf format.manifold(DefaultManifold(1)) manifold whose default inverse retraction should be used for approximating the distance.invretr- (default_inverse_retraction_method(manifold)) the inverse retraction to be used for approximating distance.
Manopt.DebugCost — TypeDebugCost <: DebugActionprint the current cost function value, see get_cost.
Constructors
DebugCost()Parameters
format- ("$prefix %f") format to print the output using sprintf and a prefix (seelong).io– (stdout) default steream to print the debug to.long- (false) short form to set the format toF(x):(default) orcurrent cost:and the cost
Manopt.DebugDivider — TypeDebugDivider <: DebugActionprint a small divider (default " | ").
Constructor
DebugDivider(div,print)Manopt.DebugEntry — TypeDebugEntry <: RecordActionprint a certain fields entry of type {T} during the iterates, where a format can be specified how to print the entry.
Addidtional Fields
field– Symbol the entry can be accessed with withinOptions
Constructor
DebugEntry(f[, prefix="$f:", format = "$prefix %s", io=stdout])Manopt.DebugEntryChange — TypeDebugEntryChange{T} <: DebugActionprint a certain entries change during iterates
Additional Fields
print– (print) function to print the resultprefix– ("Change of :Iterate") prefix to the print outformat– ("$prefix %e") format to print (uses the `prefix by default and scientific notation)field– Symbol the field can be accessed with withinOptionsdistance– function (p,o,x1,x2) to compute the change/distance between two values of the entrystorage– aStoreOptionsActionto store the previous value of:f
Constructors
DebugEntryChange(f,d)Keyword arguments
io(stdout) anIOStreamprefix("Change of $f")storage(StoreOptionsAction((f,))) aStoreOptionsActioninitial_valuean initial value for the change ofo.field.format– ("$prefix %e") format to print the change
Manopt.DebugEvery — TypeDebugEvery <: DebugActionevaluate and print debug only every $i$th iteration. Otherwise no print is performed. Whether internal variables are updates is determined by alwaysUpdate.
This method does not perform any print itself but relies on it's childrens print.
Manopt.DebugGradientChange — TypeDebugGradientChange()debug for the amount of change of the gradient (stored in get_gradient(o) of the Options o) during the last iteration. See DebugEntryChange for the general case
Keyword Parameters
storage– (StoreOptionsAction( (:Gradient,) )) – (eventually shared) the storage of the previous actionprefix– ("Last Change:") prefix of the debug output (ignored if you setformat)io– (stdout) default steream to print the debug to.format- ("$prefix %f") format to print the output using an sprintf format.
Manopt.DebugGroup — TypeDebugGroup <: DebugActiongroup a set of DebugActions into one action, where the internal prints are removed by default and the resulting strings are concatenated
Constructor
DebugGroup(g)construct a group consisting of an Array of DebugActions g, that are evaluated en bloque; the method does not perform any print itself, but relies on the internal prints. It still concatenates the result and returns the complete string
Manopt.DebugIterate — TypeDebugIterate <: DebugActiondebug for the current iterate (stored in get_iterate(o)).
Constructor
DebugIterate()Parameters
io– (stdout) default steream to print the debug to.long::Boolwhether to printx:orcurrent iterate
Manopt.DebugIteration — TypeDebugIteration <: DebugActionConstructor
DebugIteration()Keyword parameters
format- ("# %-6d") format to print the output using an sprintf format.io– (stdout) default steream to print the debug to.
debug for the current iteration (prefixed with # by )
Manopt.DebugOptions — TypeDebugOptions <: OptionsThe debug options append to any options a debug functionality, i.e. they act as a decorator pattern. Internally a Dictionary is kept that stores a DebugAction for several occasions using a Symbol as reference. The default occasion is :All and for example solvers join this field with :Start, :Step and :Stop at the beginning, every iteration or the end of the algorithm, respectively
The original options can still be accessed using the get_options function.
Fields (defaults in brackets)
options– the options that are extended by debug informationdebugDictionary– aDict{Symbol,DebugAction}to keep track of Debug for different actions
Constructors
DebugOptions(o,dA)construct debug decorated options, where dD can be
- a
DebugAction, then it is stored within the dictionary at:All - an
ArrayofDebugActions, then it is stored as adebugDictionarywithin:All. - a
Dict{Symbol,DebugAction}. - an Array of Symbols, String and an Int for the
DebugFactory
Manopt.DebugStoppingCriterion — TypeDebugStoppingCriterion <: DebugActionprint the Reason provided by the stopping criterion. Usually this should be empty, unless the algorithm stops.
Manopt.DebugTime — TypeDebugTime()Measure time and print the intervals. Using start=true you can start the timer on construction, for example to measure the runtime of an algorithm overall (adding)
The measured time is rounded using the given time_accuracy and printed after canonicalization.
Keyword Parameters
prefix– ("Last Change:") prefix of the debug output (ignored if you setformat)io– (stdout) default steream to print the debug to.format- ("$prefix %s") format to print the output using an sprintf format, where%sis the canonicalized time`.mode– (:cumulative) whether to display the total time or reset on every call using:iterative.start– (false) indicate whether to start the timer on creation or not. Otherwise it might only be started on firsr call.time_accuracy– (Millisecond(1)) round the time to this period before printing the canonicalized time
Manopt.DebugWarnIfCostIncreases — TypeDebugWarnIfCostIncreases <: DebugActionprint a warning if the cost increases.
Note that this provides an additional warning for gradient descent with its default constant step size.
Constructor
DebugWarnIfCostIncreases(warn=:Once; tol=1e-13)Initialize the warning to warning level (:Once) and introduce a tolerance for the test of 1e-13.
The warn level can be set to :Once to only warn the first time the cost increases, to :Always to report an increase every time it happens, and it can be set to :No to deactivate the warning, then this DebugAction is inactive. All other symbols are handled as if they were :Always:
Manopt.DebugWarnIfCostNotFinite — TypeDebugWarnIfCostNotFinite <: DebugActionA debug to see when a field (value or array within the Options is or contains values that are not finite, for example Inf or Nan.
Constructor
DebugWarnIfCostNotFinite(field::Symbol, warn=:Once)Initialize the warning to warn :Once.
This can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:
Manopt.DebugWarnIfFieldNotFinite — TypeDebugWarnIfFieldNotFinite <: DebugActionA debug to see when a field from the options is not finite, for example Inf or Nan
Constructor
DebugWarnIfFieldNotFinite(field::Symbol, warn=:Once)Initialize the warning to warn :Once.
This can be set to :Once to only warn the first time the cost is Nan. It can also be set to :No to deactivate the warning, but this makes this Action also useless. All other symbols are handled as if they were :Always:
Example
DebugWaranIfFieldNotFinite(:gradient)Creates a [DebugAction] to track whether the gradient does not get Nan or Inf.
Manopt.DebugActionFactory — MethodDebugActionFactory(s)create a DebugAction where
- a
Stringyields the correspoinding divider - a
DebugActionis passed through - a [
Symbol] createsDebugEntryof that symbol, with the exceptions of:Change,:Iterate,:Iteration, and:Cost. - a
Tuple{Symbol,String}creates aDebugEntryof that symbol where the String specifies the format.
Manopt.DebugActionFactory — MethodDebugActionFactory(s::Symbol)Convert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done. Note that the Shortcut symbols should all start with a capital letter.
:Costcreates aDebugCost:Changecreates aDebugChange:GradientChangecreates aDebugGradientChange:Iteratecreates aDebugIterate:Iterationcreates aDebugIteration:Stepsizecreates aDebugStepsize:WarnCostcreates aDebugWarnIfCostNotFinite:WarnGradientcreates aDebugWarnIfFieldNotFinitefor the:gradient.:Timecreates aDebugTime:IterativeTimecreates aDebugTime(:Iterative)
any other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.
Manopt.DebugActionFactory — MethodDebugActionFactory(t::Tuple{Symbol,String)Convert certain Symbols in the debug=[ ... ] vector to DebugActions Currently the following ones are done, where the string in t[2] is passed as the format the corresponding debug. Note that the Shortcut symbols t[1] should all start with a capital letter.
:Costcreates aDebugCost:Changecreates aDebugChange:GradientChangecreates aDebugGradientChange:Iteratecreates aDebugIterate:Iterationcreates aDebugIteration:Stepsizecreates aDebugStepsize:Timecreates aDebugTime:IterativeTimecreates aDebugTime(:Iterative)
any other symbol creates a DebugEntry(s) to print the entry (o.:s) from the options.
Manopt.DebugFactory — MethodDebugFactory(a)given an array of Symbols, Strings DebugActions and Ints
- The symbol
:Stopcreates an entry of to display the stopping criterion at the end (:Stop => DebugStoppingCriterion()), for further symbols seeDebugActionFactory - Tuples of a symbol and a string can be used to also specify a format, see
DebugActionFactory - any string creates a
DebugDivider - any
DebugActionis directly included - an Integer
kintroduces that debug is only printed everykth iteration
Return value
This function returns a dictionary with an entry :All containing one general DebugAction, possibly a DebugGroup of entries. It might contain an entry :Start, :Step, :Stop with an action (each) to specify what to do at the start, after a step or at the end of an Algorithm, respectively. On all three occastions the :All action is exectued. Note that only the :Stop entry is actually filled when specifying the :Stop symbol.
Example
The array
[:Iterate, " | ", :Cost, :Stop, 10]Adds a group to :All of three actions (DebugIteration, DebugDivider with " | " to display, DebugCost) as a DebugGroup inside an DebugEvery to only be executed every 10th iteration. It also adds the DebugStoppingCriterion to the :Stop entry of the dictionary.
Manopt.reset! — Methodreset!(d::DebugTime)reset the internal time of a DebugTime, that is start from now again.
Manopt.stop! — Methodstop!(d::DebugTime)stop the reset the internal time of a DebugTime, that is set the time to 0 (undefined)
Technical Details: The Debug Solver
The decorator to print debug during the iterations can be activated by decorating the Options with DebugOptions and implementing your own DebugActions. For example printing a gradient from the GradientDescentOptions is automatically available, as explained in the gradient_descent solver.
Manopt.initialize_solver! — Methodinitialize_solver!(p::Problem, o::DebugOptions)Initialize the solver to the optimization Problem by initializing all values in the DebugOptionso.
Since debug acts as a decorator this also calls the initialize_solver! of the correpsonding internally stored options
Manopt.step_solver! — Methodstep_solver!(p::Problem, o::DebugOptions, i)
Do one iteration step (the `i`th) for [`Problem`](@ref)` p` by modifyingthe values in the Optionso.options and print the debug specified
Manopt.stop_solver! — Methodstop_solver!(p,o,i)determine whether the solver for Problem p and the DebugOptions o should stop at iteration i by calling the function corresponding to the internally stored Options. If so, print debug from :All and :Stop.