Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve a few places in the docs. #415

Merged
merged 2 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ All notable Changes to the Julia package `Manopt.jl` will be documented in this
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.2] – unreleased
## [0.5.2] – October 5, 2024

### Added

* three new symbols to easier state to record the `:Gradient`, the `:GradientNorm`, and the `:Stepsize`.

### Changed

* fix a few typos in the docstrings.
* fix a few typos in the documentation
* improved the documentation for the initial guess of [`ArmijoLinesearchStepsize`](https://manoptjl.org/stable/plans/stepsize/#Manopt.ArmijoLinesearch).

## [0.5.1] – September 4, 2024

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Manopt"
uuid = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5"
authors = ["Ronny Bergmann <manopt@ronnybergmann.net>"]
version = "0.5.1"
version = "0.5.2"

[deps]
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
Expand Down
2 changes: 1 addition & 1 deletion src/plans/gradient_plan.jl
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ mutable struct RecordGradient{T} <: RecordAction
recorded_values::Array{T,1}
RecordGradient{T}() where {T} = new(Array{T,1}())
end
RecordGradient(ξ::T) where {T} = RecordGradient{T}()
RecordGradient(::T) where {T} = RecordGradient{T}()
function (r::RecordGradient{T})(
::AbstractManoptProblem, s::AbstractManoptSolverState, k::Int
) where {T}
Expand Down
9 changes: 8 additions & 1 deletion src/plans/record.jl
Original file line number Diff line number Diff line change
Expand Up @@ -897,10 +897,14 @@ create a [`RecordAction`](@ref) where

* a [`RecordAction`](@ref) is passed through
* a [`Symbol`] creates
* `:Change` to record the change of the iterates in `o.x``
* `:Change` to record the change of the iterates, see [`RecordChange`](@ref)
* `:Gradient` to record the gradient, see [`RecordGradient`](@ref)
* `:GradientNorm to record the norm of the gradient, see [`RecordGradientNorm`](@ref)
* `:Iterate` to record the iterate
* `:Iteration` to record the current iteration number
* `IterativeTime` 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.

Expand All @@ -912,9 +916,12 @@ RecordActionFactory(::AbstractManoptSolverState, sa::Pair{<:RecordAction,Symbol}
function RecordActionFactory(s::AbstractManoptSolverState, symbol::Symbol)
(symbol == :Change) && return RecordChange()
(symbol == :Cost) && return RecordCost()
(symbol == :Gradient) && return RecordGradient(get_gradient(s))
(symbol == :GradientNorm) && return RecordGradientNorm()
(symbol == :Iterate) && return RecordIterate(get_iterate(s))
(symbol == :Iteration) && return RecordIteration()
(symbol == :IterativeTime) && return RecordTime(; mode=:iterative)
(symbol == :Stepsize) && return RecordStepsize()
(symbol == :Stop) && return RecordStoppingReason()
(symbol == :Subsolver) && return RecordSubsolver()
(symbol == :Time) && return RecordTime(; mode=:cumulative)
Expand Down
60 changes: 44 additions & 16 deletions src/plans/stepsize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ default_stepsize(M::AbstractManifold, sT::Type{<:AbstractManoptSolverState})

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`](@extref `ManifoldsBase.injectivity_radius-Tuple{AbstractManifold}`)`(M)`.
"""
function max_stepsize(M::AbstractManifold, p)
return max_stepsize(M)
Expand Down Expand Up @@ -228,6 +230,27 @@ most prominently the negative gradient.
"""
abstract type Linesearch <: Stepsize end

"""
armijo_initial_guess(mp::AbstractManoptProblem, s::AbstractManoptSolverState, k, l)

# Input

* `mp`: the [`AbstractManoptProblem`](@ref) we are aiminig to minimize
* `s`: the [`AbstractManoptSolverState`](@ref) for the current solver
* `k`: the current iteration
* `l`: the last step size computed in the previous iteration.

Return an initial guess for the [`ArmijoLinesearchStepsize`](@ref).

The default provided is based on the [`max_stepsize`](@ref)`(M)`, which we denote by ``m``.
Let further ``X`` be the current descent direction with norm ``n=$(_tex(:norm, "X"; index="p"))`` its length.
Then this (default) initial guess returns

* ``l`` if ``m`` is not finite
* ``$(_tex(:min))(l, $(_tex(:frac,"m","n")))`` otherwise

This ensures that the initial guess does not yield to large (initial) steps.
"""
function armijo_initial_guess(
mp::AbstractManoptProblem, s::AbstractManoptSolverState, ::Int, l::Real
)
Expand All @@ -247,23 +270,24 @@ based on the search direction `X`

# Fields

* `candidate_point`: to store an interim result
* `initial_stepsize`: and initial step size
* `candidate_point`: to store an interim result
* `initial_stepsize`: and initial step size
$(_var(:Keyword, :retraction_method))
* `contraction_factor`: exponent for line search reduction
* `sufficient_decrease`: gain within Armijo's rule
* `last_stepsize`: the last step size to start the search with
* `initial_guess`: based on a [`AbstractManoptProblem`](@ref) `p`,
[`AbstractManoptSolverState`](@ref) `s` and a current iterate `i` and a last step size `l`,
this returns an initial guess. The default uses the last obtained stepsize
* `additional_decrease_condition`: (`(M,p) -> true`) specify a condition a new point has to additionally
* `contraction_factor`: exponent for line search reduction
* `sufficient_decrease`: gain within Armijo's rule
* `last_stepsize`: the last step size to start the search with
* `initial_guess`: a function to provide an initial guess for the step size,
it maps `(m,p,k,l) -> α` based on a [`AbstractManoptProblem`](@ref) `p`,
[`AbstractManoptSolverState`](@ref) `s`, the current iterate `k` and a last step size `l`.
It returns the initial guess `α`.
* `additional_decrease_condition`: specify a condition a new point has to additionally
fulfill. The default accepts all points.
* `additional_increase_condition`: (`(M,p) -> true`) specify a condtion that additionally to
* `additional_increase_condition`: specify a condtion that additionally to
checking a valid increase has to be fulfilled. The default accepts all points.
* `stop_when_stepsize_less`: smallest stepsize when to stop (the last one before is taken)
* `stop_when_stepsize_exceeds`: largest stepsize when to stop.
* `stop_increasing_at_step`: last step to increase the stepsize (phase 1),
* `stop_decreasing_at_step`: last step size to decrease the stepsize (phase 2),
* `stop_when_stepsize_less`: smallest stepsize when to stop (the last one before is taken)
* `stop_when_stepsize_exceeds`: largest stepsize when to stop.
* `stop_increasing_at_step`: last step to increase the stepsize (phase 1),
* `stop_decreasing_at_step`: last step size to decrease the stepsize (phase 2),

Pass `:Messages` to a `debug=` to see `@info`s when these happen.

Expand All @@ -281,7 +305,7 @@ $(_var(:Keyword, :retraction_method))
* `contraction_factor=0.95`
* `sufficient_decrease=0.1`
* `last_stepsize=initialstepsize`
* `initial_guess=(p,s,i,l) -> l`
* `initial_guess=[`armijo_initial_guess`](@ref) – (p,s,i,l) -> l`
* `stop_when_stepsize_less=0.0`
* `stop_when_stepsize_exceeds`
* `stop_increasing_at_step=100`
Expand Down Expand Up @@ -434,7 +458,11 @@ Overall, we look for step size, that provides _enough decrease_, see
speciy a point to be used as memory for the candidate points.
* `contraction_factor=0.95`: how to update ``s`` in the decrease step
* `initial_stepsize=1.0``: specify an initial step size
* `initial_guess=armijo_initial_guess`: instead of the initial step, start with this guess.
* `initial_guess=`[`armijo_initial_guess`](@ref): Compute the initial step size of
a line search based on this function.
The funtion required is `(p,s,k,l) -> α` and computes the initial step size ``α``
based on a [`AbstractManoptProblem`](@ref) `p`, [`AbstractManoptSolverState`](@ref) `s`,
the current iterate `k` and a last step size `l`.
$(_var(:Keyword, :retraction_method))
* `stop_when_stepsize_less=0.0`: a safeguard, stop when the decreasing step is below this (nonnegative) bound.
* `stop_when_stepsize_exceeds=max_stepsize(M)`: a safeguard to not choose a too long step size when initially increasing
Expand Down
Loading