Record values
To record values during the iterations of a solver run, there are in general two possibilities. On the one hand, the high-level interfaces provide a record=
keyword, that accepts several different inputs. For more details see How to record.
Record Actions & the solver state decorator
Manopt.RecordAction
— TypeRecordAction
A RecordAction
is a small functor to record values. The usual call is given by
(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, k) -> s
that performs the record for the current problem and solver combination, and where k
is the current iteration.
By convention i=0
is interpreted as "For Initialization only," so only initialize internal values, but not trigger any record, that the record is called from within stop_solver!
which returns true afterwards.
Any negative value is interpreted as a “reset”, and should hence delete all stored recordings, for example when reusing a RecordAction
. The start of a solver calls the :Iteration
and :Stop
dictionary entries with -1
, to reset those recordings.
By default any RecordAction
is assumed to record its values in a field recorded_values
, an Vector
of recorded values. See get_record
(ra)
.
Manopt.RecordChange
— TypeRecordChange <: RecordAction
debug for the amount of change of the iterate (see get_iterate
(s)
of the AbstractManoptSolverState
) during the last iteration.
Fields
storage
: aStoreStateAction
to store (at least) the last iterate to use this as the last value (to compute the change) serving as a potential cache shared with other components of the solver.inverse_retraction_method=
default_inverse_retraction_method
(M, typeof(p))
: an inverse retraction $\operatorname{retr}^{-1}$ to use, see the section on retractions and their inversesrecorded_values
: to store the recorded values
Constructor
RecordChange(M=DefaultManifold();
inverse_retraction_method = default_inverse_retraction_method(M),
storage = StoreStateAction(M; store_points=Tuple{:Iterate})
)
with the previous fields as keywords. For the DefaultManifold
only the field storage is used. Providing the actual manifold moves the default storage to the efficient point storage.
Manopt.RecordCost
— TypeRecordCost <: RecordAction
Record the current cost function value, see get_cost
.
Fields
recorded_values
: to store the recorded values
Constructor
RecordCost()
Manopt.RecordEntry
— TypeRecordEntry{T} <: RecordAction
record a certain fields entry of type {T} during the iterates
Fields
recorded_values
: the recorded Iteratesfield
: Symbol the entry can be accessed with withinAbstractManoptSolverState
Constructor
RecordEntry(::T, f::Symbol)
RecordEntry(T::DataType, f::Symbol)
Initialize the record action to record the state field f
, and initialize the recorded_values
to be a vector of element type T
.
Examples
RecordEntry(rand(M), :q)
to record the points fromM
stored in some statess.q
RecordEntry(SVDMPoint, :p)
to record the fields.p
which takes values of typeSVDMPoint
.
Manopt.RecordEntryChange
— TypeRecordEntryChange{T} <: RecordAction
record a certain entries change during iterates
Additional fields
recorded_values
: the recorded Iteratesfield
: Symbol the field can be accessed with withinAbstractManoptSolverState
distance
: function (p,o,x1,x2) to compute the change/distance between two values of the entrystorage
: aStoreStateAction
to store (at least)getproperty(o, d.field)
Constructor
RecordEntryChange(f::Symbol, d, a::StoreStateAction=StoreStateAction([f]))
Manopt.RecordEvery
— TypeRecordEvery <: RecordAction
record only every $k$th iteration. Otherwise (optionally, but activated by default) just update internal tracking values.
This method does not perform any record itself but relies on it's children's methods
Manopt.RecordGroup
— TypeRecordGroup <: RecordAction
group a set of RecordAction
s into one action, where the internal RecordAction
s act independently, but the results can be collected in a grouped fashion, a tuple per calls of this group. The entries can be later addressed either by index or semantic Symbols
Constructors
RecordGroup(g::Array{<:RecordAction, 1})
construct a group consisting of an Array of RecordAction
s g
,
RecordGroup(g, symbols)
Examples
g1 = RecordGroup([RecordIteration(), RecordCost()])
A RecordGroup to record the current iteration and the cost. The cost can then be accessed using get_record(r,2)
or r[2]
.
g2 = RecordGroup([RecordIteration(), RecordCost()], Dict(:Cost => 2))
A RecordGroup to record the current iteration and the cost, which can then be accessed using get_record(:Cost)
or r[:Cost]
.
g3 = RecordGroup([RecordIteration(), RecordCost() => :Cost])
A RecordGroup identical to the previous constructor, just a little easier to use. To access all recordings of the second entry of this last g3
you can do either g4[2]
or g[:Cost]
, the first one can only be accessed by g4[1]
, since no symbol was given here.
Manopt.RecordIterate
— TypeRecordIterate <: RecordAction
record the iterate
Constructors
RecordIterate(x0)
initialize the iterate record array to the type of x0
, which indicates the kind of iterate
RecordIterate(P)
initialize the iterate record array to the data type T
.
Manopt.RecordIteration
— TypeRecordIteration <: RecordAction
record the current iteration
Manopt.RecordSolverState
— TypeRecordSolverState <: AbstractManoptSolverState
append to any AbstractManoptSolverState
the decorator with record capability, Internally a dictionary is kept that stores a RecordAction
for several concurrent modes using a Symbol
as reference. The default mode is :Iteration
, which is used to store information that is recorded during the iterations. RecordActions might be added to :Start
or :Stop
to record values at the beginning or for the stopping time point, respectively
The original options can still be accessed using the get_state
function.
Fields
options
the options that are extended by debug informationrecordDictionary
aDict{Symbol,RecordAction}
to keep track of all different recorded values
Constructors
RecordSolverState(o,dR)
construct record decorated AbstractManoptSolverState
, where dR
can be
- a
RecordAction
, then it is stored within the dictionary at:Iteration
- an
Array
ofRecordAction
s, then it is stored as arecordDictionary
(@ref). - a
Dict{Symbol,RecordAction}
.
Manopt.RecordStoppingReason
— TypeRecordStoppingReason <: RecordAction
Record reason the solver stopped, see get_reason
.
Manopt.RecordSubsolver
— TypeRecordSubsolver <: RecordAction
Record the current subsolvers recording, by calling get_record
on the sub state with
Fields
records
: an array to store the recorded valuessymbols
: arguments forget_record
. Defaults to just one symbol:Iteration
, but could be set to also record the:Stop
action.
Constructor
RecordSubsolver(; record=[:Iteration,], record_type=eltype([]))
Manopt.RecordTime
— TypeRecordTime <: RecordAction
record the time elapsed during the current iteration.
The three possible modes are
:cumulative
record times without resetting the timer:iterative
record times with resetting the timer:total
record a time only at the end of an algorithm (seestop_solver!
)
The default is :cumulative
, and any non-listed symbol default to using this mode.
Constructor
RecordTime(; mode::Symbol=:cumulative)
Manopt.RecordWhenActive
— TypeRecordWhenActive <: RecordAction
record action that only records if the active
boolean is set to true. This can be set from outside and is for example triggered by |RecordEvery
](@ref) on recordings of the subsolver. While this is for subsolvers maybe not completely necessary, recording values that are never accessible, is not that useful.
Fields
active
: a boolean that can (de-)activated from outside to turn on/off debugalways_update
: whether or not to call the inner debugs with nonpositive iterates (init/reset)
Constructor
RecordWhenActive(r::RecordAction, active=true, always_update=true)
Access functions
Base.getindex
— Methodgetindex(r::RecordGroup, s::Symbol)
r[s]
getindex(r::RecordGroup, sT::NTuple{N,Symbol})
r[sT]
getindex(r::RecordGroup, i)
r[i]
return an array of recorded values with respect to the s
, the symbols from the tuple sT
or the index i
. See get_record
for details.
Base.getindex
— Methodget_index(rs::RecordSolverState, s::Symbol)
ro[s]
Get the recorded values for recorded type s
, see get_record
for details.
get_index(rs::RecordSolverState, s::Symbol, i...)
ro[s, i...]
Access the recording type of type s
and call its RecordAction
with [i...]
.
Manopt.get_record
— Functionget_record(s::AbstractManoptSolverState, [,symbol=:Iteration])
get_record(s::RecordSolverState, [,symbol=:Iteration])
return the recorded values from within the RecordSolverState
s
that where recorded with respect to the Symbol symbol
as an Array
. The default refers to any recordings during an :Iteration
.
When called with arbitrary AbstractManoptSolverState
, this method looks for the RecordSolverState
decorator and calls get_record
on the decorator.
Manopt.get_record
— Methodget_record(r::RecordAction)
return the recorded values stored within a RecordAction
r
.
Manopt.get_record
— Methodget_record(r::RecordGroup)
return an array of tuples, where each tuple is a recorded set per iteration or record call.
get_record(r::RecordGruop, k::Int)
return an array of values corresponding to the i
th entry in this record group
get_record(r::RecordGruop, s::Symbol)
return an array of recorded values with respect to the s
, see RecordGroup
.
get_record(r::RecordGroup, s1::Symbol, s2::Symbol,...)
return an array of tuples, where each tuple is a recorded set corresponding to the symbols s1, s2,...
per iteration / record call.
Manopt.get_record_action
— Functionget_record_action(s::AbstractManoptSolverState, s::Symbol)
return the action contained in the (first) RecordSolverState
decorator within the AbstractManoptSolverState
o
.
Manopt.get_record_state
— Methodget_record_state(s::AbstractManoptSolverState)
return the RecordSolverState
among the decorators from the AbstractManoptSolverState
o
Manopt.has_record
— Methodhas_record(s::AbstractManoptSolverState)
Indicate whether the AbstractManoptSolverState
s
are decorated with RecordSolverState
Internal factory functions
Manopt.RecordActionFactory
— MethodRecordActionFactory(s::AbstractManoptSolverState, a)
create a RecordAction
where
- a
RecordAction
is passed through - a [
Symbol
] creates:Change
to record the change of the iterates, seeRecordChange
:Gradient
to record the gradient, seeRecordGradient
:GradientNorm to record the norm of the gradient, see [
RecordGradientNorm`](@ref):Iterate
to record the iterate:Iteration
to record the current iteration numberIterativeTime
to record the time iteratively:Cost
to record the current cost function value:Stepsize
to record the current step size:Time
to record the total time taken after every iteration:IterativeTime
to record the times taken for each iteration.
and every other symbol is passed to RecordEntry
, which results in recording the field of the state with the symbol indicating the field of the solver to record.
Manopt.RecordActionFactory
— MethodRecordActionFactory(s::AbstractManoptSolverState, t::Tuple{Symbol, T}) where {T}
create a RecordAction
where
- (
:Subsolver
, s) creates aRecordSubsolver
withrecord=
set to the second tuple entry
For other symbol the second entry is ignored and the symbol is used to generate a RecordEntry
recording the field with the name symbol
of s
.
Manopt.RecordFactory
— MethodRecordFactory(s::AbstractManoptSolverState, a)
Generate a dictionary of RecordAction
s.
First all Symbol
s String
, RecordAction
s and numbers are collected, excluding :Stop
and :WhenActive
. This collected vector is added to the :Iteration => [...]
pair. :Stop
is added as :StoppingCriterion
to the :Stop => [...]
pair. If any of these two pairs does not exist, it is pairs are created when adding the corresponding symbols
For each Pair
of a Symbol
and a Vector
, the RecordGroupFactory
is called for the Vector
and the result is added to the debug dictionary's entry with said symbol. This is wrapped into the RecordWhenActive
, when the :WhenActive
symbol is present
Return value
A dictionary for the different entry points where debug can happen, each containing a RecordAction
to call.
Note that upon the initialisation all dictionaries but the :StartAlgorithm
one are called with an i=0
for reset.
Manopt.RecordGroupFactory
— MethodRecordGroupFactory(s::AbstractManoptSolverState, a)
Generate a [RecordGroup
] of RecordAction
s. The following rules are used
- Any
Symbol
contained ina
is passed toRecordActionFactory
- Any
RecordAction
is included as is.
Any Pair of a RecordAction
and a symbol, that is in order RecordCost() => :A
is handled, that the corresponding record action can later be accessed as g[:A]
, where g
is the record group generated here.
If this results in more than one RecordAction
a RecordGroup
of these is build.
If any integers are present, the last of these is used to wrap the group in a RecordEvery
(k)
.
If :WhenActive
is present, the resulting Action is wrapped in RecordWhenActive
, making it deactivatable by its parent solver.
Manopt.record_or_reset!
— Methodrecord_or_reset!(r, v, k)
either record (k>0
and not Inf
) the value v
within the RecordAction
r
or reset (k<0
) the internal storage, where v
has to match the internal value type of the corresponding RecordAction
.
Manopt.set_parameter!
— Methodset_parameter!(ams::RecordSolverState, ::Val{:Record}, args...)
Set certain values specified by args...
into the elements of the recordDictionary
Further specific RecordAction
s can be found when specific types of AbstractManoptSolverState
define them on their corresponding site.
Technical details
Manopt.initialize_solver!
— Methodinitialize_solver!(ams::AbstractManoptProblem, rss::RecordSolverState)
Extend the initialization of the solver by a hook to run records that were added to the :Start
entry.
Manopt.step_solver!
— Methodstep_solver!(amp::AbstractManoptProblem, rss::RecordSolverState, k)
Extend the i
th step of the solver by a hook to run records, that were added to the :Iteration
entry.
Manopt.stop_solver!
— Methodstop_solver!(amp::AbstractManoptProblem, rss::RecordSolverStatek k)
Extend the call to the stopping criterion by a hook to run records, that were added to the :Stop
entry.