Stepsize
In many algorithms, once a direction (in the form of a tangent vector) has been determined, like the steepest descent direction in gradient_descent, it is common to perform a stepsize computation. A special case is a line search method; both a stepsize computation and a line search start from an initial guess.
A stepsize is a function, usually implemented as a struct that can be called like a function, that based on the parameters (problem, state, k, η; kwargs...) computes a new stepsize, where k is the current iteration and η the search direction. A common keyword argument is initial_guess=.
Step sizes often have parameters that might depend on the manifold used and therefore often use the default factory pattern.
Manopt.Stepsize — Type
StepsizeAn abstract type for the functors representing step sizes. These are callable structures. The naming scheme is TypeOfStepSize, for example ConstantStepsize.
Every Stepsize has to provide a constructor and its function has to have the interface (problem, state, k) where an AbstractManoptProblem problem, an AbstractManoptSolverState state, and the current iteration k are the arguments, and returns a number, namely the stepsize to use.
The functor usually should accept arbitrary keyword arguments. Common ones used are
gradient=nothing: to pass a pre-calculated gradient, otherwise it is computed.
For most it is advisable to employ a ManifoldDefaultsFactory. Then the function creating the factory should either be called TypeOf or, if that is confusing or too generic, TypeOfLength.
See also
Manopt.Linesearch — Type
Linesearch <: StepsizeAn abstract functor to represent line search type step size determinations, see Stepsize for details. One example is the ArmijoLinesearchStepsize functor.
Compared to simple step sizes, the line search functors provide an interface of the form (problem, state, k, X) -> s with an additional (but optional) fourth parameter to provide a search direction; this should default to something reasonable, most prominently the negative gradient.
Manopt.AbstractInitialLinesearchGuess — Type
AbstractInitialLinesearchGuessAn abstract type for initial line search guess strategies. These are functors that map (problem, state, k, last_stepsize, η) -> α_0, where α_0 is the initial step size, based on
- an
AbstractManoptProblemproblem - an
AbstractManoptSolverStatestate - the current iteration
k - the last step size
last_stepsize - the search direction
η
Functions
Manopt.default_stepsize — Method
default_stepsize(M::AbstractManifold, ams::AbstractManoptSolverState)Returns the default Stepsize functor used when running the solver specified by the AbstractManoptSolverState ams running with an objective on the AbstractManifold M.
Manopt.get_last_stepsize — Method
get_last_stepsize(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, vars...)return the last computed stepsize stored within AbstractManoptSolverState ams when solving the AbstractManoptProblem amp.
This method takes into account that ams might be decorated. In case this returns NaN, a concrete call to the stored stepsize is performed. For this, usually, the first of the vars... should be the current iterate.
Manopt.get_last_stepsize — Method
get_last_stepsize(::Stepsize, vars...)return the last computed stepsize from within the stepsize. If no last step size is stored, this returns NaN.
Manopt.get_stepsize — Method
get_stepsize(amp::AbstractManoptProblem, ams::AbstractManoptSolverState, vars...)return the stepsize stored within AbstractManoptSolverState ams when solving the AbstractManoptProblem amp. This method also works for decorated options and the Stepsize function within the options, by default stored in ams.stepsize.
Internal functions
Manopt.initialize_stepsize! — Method
initialize_stepsize!(sm::Stepsize)Initialize the state of a stepsize functor. This function should be called in the initialize_solver! function for solvers that do possess a stepsize and can be used to set up internal state of the stepsize functor that is preserved between line searches in the same optimization, for example adaptive thresholds for Wolfe criteria in Hager-Zhang line search.
By default it does nothing.
Manopt.linesearch_backtrack! — Method
s = linesearch_backtrack(M, f, p, s, decrease, contract, η; kwargs...)
s = linesearch_backtrack!(M, q, f, p, s, decrease, contract, η; kwargs...)perform a line search along $\ellf(s) = f(\operatorname{retr}_p(sη))$ to find a stepsize s. See [NW06, Section 3] for details.
The linesearch starts with a first phase where the stepsize is increased as $s ↦ s / σ$ until
\[f(\operatorname{retr}_p(sη)) ≥ f(p) + a * s * Df(p)[η]\]
where $a$ is the decrease parameter, and $Df(p)[η]$ is the directional derivative.
Then the actual backtracking phase starts, where the stepsize is decreased as $s ↦ σ s$ until
\[f(\operatorname{retr}_p(sη)) ≤ f(p) + a * s * Df(p)[η]\]
with the same decrease parameter $a$ as above.
This can be done in-place, where q is the point to store the point reached in.
Both phases have a safeguard on the maximal number of steps to perform as well as an upper and lower bound for the stepsize, respectively. The upper bound is a special case on manifolds to avoid exceeding the injectivity radius. Furthermore, both phases can be equipped with additional conditions to be fulfilled in order to accept the current stepsize.
Arguments
M: the manifold to perform the line search onf: the cost functionp: the current points: an initial stepsizedecrease: the sufficient decrease parameter $a$contract: the contraction factor $σ$η: the search direction
Keyword arguments
retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractionsadditional_increase_condition=(M,p) -> true: impose an additional condition for an increased step size to be acceptedadditional_decrease_condition=(M,p) -> true: impose an additional condition for a decreased step size to be acceptedDlf0: precomputed directional derivative at pointpin directionηif thegradientis specified, this is computed as the real part ofinner(M, p, gradient, η), otherwise it isnothinglf0 = f(M, p): the function value at the initial pointpgradient = nothing: precomputed gradient at pointpreport_messages_in::NamedTuple = (; ): a named tuple ofStepsizeMessages to report messages in. currently supported keywords are:non_descent_direction,:stepsize_exceeds,:stepsize_less,:stop_increasing,:stop_decreasingstop_when_stepsize_less::Real=0.0: to avoid numerical underflowstop_when_stepsize_exceeds::Real=max_stepsize(M, p) / norm(M, p, η): to avoid leaving the injectivity radius on a manifold or exceeding boundaries on a manifold with cornersstop_increasing_at_step=100: stop the initial increase of step size after these many stepsstop_decreasing_at_step=1000: stop the decreasing search after these many stepsThese keywords are used as safeguards, where only the max stepsize is a very manifold specific one.
Return value
A stepsize s and a message msg (in case any of the 5 criteria hit)
Manopt.linesearch_backtrack — Method
s = linesearch_backtrack(M, f, p, s, decrease, contract, η; kwargs...)
s = linesearch_backtrack!(M, q, f, p, s, decrease, contract, η; kwargs...)perform a line search along $\ellf(s) = f(\operatorname{retr}_p(sη))$ to find a stepsize s. See [NW06, Section 3] for details.
The linesearch starts with a first phase where the stepsize is increased as $s ↦ s / σ$ until
\[f(\operatorname{retr}_p(sη)) ≥ f(p) + a * s * Df(p)[η]\]
where $a$ is the decrease parameter, and $Df(p)[η]$ is the directional derivative.
Then the actual backtracking phase starts, where the stepsize is decreased as $s ↦ σ s$ until
\[f(\operatorname{retr}_p(sη)) ≤ f(p) + a * s * Df(p)[η]\]
with the same decrease parameter $a$ as above.
This can be done in-place, where q is the point to store the point reached in.
Both phases have a safeguard on the maximal number of steps to perform as well as an upper and lower bound for the stepsize, respectively. The upper bound is a special case on manifolds to avoid exceeding the injectivity radius. Furthermore, both phases can be equipped with additional conditions to be fulfilled in order to accept the current stepsize.
Arguments
M: the manifold to perform the line search onf: the cost functionp: the current points: an initial stepsizedecrease: the sufficient decrease parameter $a$contract: the contraction factor $σ$η: the search direction
Keyword arguments
retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractionsadditional_increase_condition=(M,p) -> true: impose an additional condition for an increased step size to be acceptedadditional_decrease_condition=(M,p) -> true: impose an additional condition for a decreased step size to be acceptedDlf0: precomputed directional derivative at pointpin directionηif thegradientis specified, this is computed as the real part ofinner(M, p, gradient, η), otherwise it isnothinglf0 = f(M, p): the function value at the initial pointpgradient = nothing: precomputed gradient at pointpreport_messages_in::NamedTuple = (; ): a named tuple ofStepsizeMessages to report messages in. currently supported keywords are:non_descent_direction,:stepsize_exceeds,:stepsize_less,:stop_increasing,:stop_decreasingstop_when_stepsize_less::Real=0.0: to avoid numerical underflowstop_when_stepsize_exceeds::Real=max_stepsize(M, p) / norm(M, p, η): to avoid leaving the injectivity radius on a manifold or exceeding boundaries on a manifold with cornersstop_increasing_at_step=100: stop the initial increase of step size after these many stepsstop_decreasing_at_step=1000: stop the decreasing search after these many stepsThese keywords are used as safeguards, where only the max stepsize is a very manifold specific one.
Return value
A stepsize s and a message msg (in case any of the 5 criteria hit)
Manopt.max_stepsize — Method
max_stepsize(M::AbstractManifold, p)
max_stepsize(M::AbstractManifold)Get the maximum stepsize (at point p) on manifold M. It should be used to limit the distance an algorithm is trying to move in a single step.
By default, this returns injectivity_radius(M), if this exists. If this is not available on the manifold, the method returns Inf.
Manopt.max_stepsize — Method
max_stepsize(M::AbstractManifold, p)
max_stepsize(M::AbstractManifold)Get the maximum stepsize (at point p) on manifold M. It should be used to limit the distance an algorithm is trying to move in a single step.
By default, this returns injectivity_radius(M), if this exists. If this is not available on the manifold, the method returns Inf.