From 257039a1479bcadc442129acac06f348c952b980 Mon Sep 17 00:00:00 2001 From: Ronny Bergmann Date: Fri, 18 Oct 2024 15:08:27 +0200 Subject: [PATCH] Stabilize `max_stepsize` to also work when no Injectivity_radius`is available. --- Changelog.md | 8 +++++ Project.toml | 2 +- ext/ManoptManifoldsExt/manifold_functions.jl | 4 ++- src/documentation_glossary.jl | 5 ++++ src/plans/stepsize.jl | 31 +++++++++++++++----- test/ManoptTestSuite.jl/ManoptTestSuite.jl | 11 +++++++ test/plans/test_stepsize.jl | 9 ++++++ test/solvers/test_cma_es.jl | 2 +- 8 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 test/ManoptTestSuite.jl/ManoptTestSuite.jl diff --git a/Changelog.md b/Changelog.md index f149948a6c..6f2df52e85 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,14 @@ 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.3] – October 18, 2024 + +### Changed + +* stabilize `max_Stepzise` to also work when `injectivity_radius` dos not exist. + It however would warn new users, that activate tutorial mode. +* Start a `ManoptTestSuite` subpackage to store dummy types and common test helpers in. + ## [0.5.2] – October 5, 2024 ### Added diff --git a/Project.toml b/Project.toml index 5bdec4109e..92a3a94abd 100644 --- a/Project.toml +++ b/Project.toml @@ -53,7 +53,7 @@ LinearAlgebra = "1.6" ManifoldDiff = "0.3.8" Manifolds = "0.9.11, 0.10" ManifoldsBase = "0.15.10" -ManoptExamples = "0.1.8" +ManoptExamples = "0.1.10" Markdown = "1.6" Plots = "1.30" Preferences = "1.4" diff --git a/ext/ManoptManifoldsExt/manifold_functions.jl b/ext/ManoptManifoldsExt/manifold_functions.jl index 1c3d4332f2..e52364f049 100644 --- a/ext/ManoptManifoldsExt/manifold_functions.jl +++ b/ext/ManoptManifoldsExt/manifold_functions.jl @@ -9,7 +9,9 @@ on a tangent bundle might be. function max_stepsize(M::TangentBundle, p) return max_stepsize(M.manifold, p[M, :point]) end - +function max_stepsize(M::TangentBundle) + return max_stepsize(M.manifold) +end """ max_stepsize(M::FixedRankMatrices, p) diff --git a/src/documentation_glossary.jl b/src/documentation_glossary.jl index 55b9aa4427..677587c793 100644 --- a/src/documentation_glossary.jl +++ b/src/documentation_glossary.jl @@ -138,6 +138,11 @@ define!( :AbstractManifold, "[`AbstractManifold`](@extref `ManifoldsBase.AbstractManifold`)", ) +define!( + :Link, + :injectivity_radius, + "[`injectivity_radius`](@extref `ManifoldsBase.injectivity_radius-Tuple{AbstractManifold}`)", +) define!( :Link, :manifold_dimension, diff --git a/src/plans/stepsize.jl b/src/plans/stepsize.jl index e2759011ca..a78a378104 100644 --- a/src/plans/stepsize.jl +++ b/src/plans/stepsize.jl @@ -35,13 +35,28 @@ 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)`. +By default, this returns $(_link(:injectivity_radius))`(M)`, if this exists. +If this is not available on the the method returns `Inf`. """ function max_stepsize(M::AbstractManifold, p) - return max_stepsize(M) + s = try + injectivity_radius(M, p) + catch + is_tutorial_mode() && + @warn "`max_stepsize was called, but there seems to not be an `injectivity_raidus` available on $M." + Inf + end + return s end function max_stepsize(M::AbstractManifold) - return injectivity_radius(M) + s = try + injectivity_radius(M) + catch + is_tutorial_mode() && + @warn "`max_stepsize was called, but there seems to not be an `injectivity_raidus` available on $M." + Inf + end + return s end """ @@ -305,11 +320,11 @@ $(_var(:Keyword, :retraction_method)) * `contraction_factor=0.95` * `sufficient_decrease=0.1` * `last_stepsize=initialstepsize` -* `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` -* `stop_decreasing_at_step=1000` +* `initial_guess=`[`armijo_initial_guess`](@ref)` – (p,s,i,l) -> l` +* `stop_when_stepsize_less=0.0`: stop when the stepsize decreased below this version. +* `stop_when_stepsize_exceeds=[`max_step`](@ref)`(M)`: provide an absolute maximal step size. +* `stop_increasing_at_step=100`: for the initial increase test, stop after these many steps +* `stop_decreasing_at_step=1000`: in the backtrack, stop after these many steps """ mutable struct ArmijoLinesearchStepsize{TRM<:AbstractRetractionMethod,P,I,F,IGF,DF,IF} <: Linesearch diff --git a/test/ManoptTestSuite.jl/ManoptTestSuite.jl b/test/ManoptTestSuite.jl/ManoptTestSuite.jl new file mode 100644 index 0000000000..0ee2caf95e --- /dev/null +++ b/test/ManoptTestSuite.jl/ManoptTestSuite.jl @@ -0,0 +1,11 @@ +""" + ManoptTestSuite.jl + +A small module to provide common dummy types and defaults for testing. +""" +module ManoptTestSuite +using Manopt, Test, ManifoldsBase + +struct DummyManifold <: AbstractManifold{ManifoldsBase.ℝ} end + +end diff --git a/test/plans/test_stepsize.jl b/test/plans/test_stepsize.jl index 4fb25bb90d..5acc7cac60 100644 --- a/test/plans/test_stepsize.jl +++ b/test/plans/test_stepsize.jl @@ -1,5 +1,9 @@ using ManifoldsBase, Manopt, Manifolds, Test +s = joinpath(@__DIR__, "..", "ManoptTestSuite.jl") +!(s in LOAD_PATH) && (push!(LOAD_PATH, s)) +using ManoptTestSuite + @testset "Stepsize" begin M = ManifoldsBase.DefaultManifold(2) @test Manopt.get_message(Manopt.ConstantStepsize(M, 1.0)) == "" @@ -124,4 +128,9 @@ using ManifoldsBase, Manopt, Manifolds, Test "Polyak()\nA stepsize with keyword parameters\n * initial_cost_estimate = 0.0\n" @test ps(dmp, sgs, 1) == (f(M, p) - 0 + 1) / (norm(M, p, X)^2) end + @testset "max_stepsize fallbacks" begin + M = ManoptTestSuite.DummyManifold() + @test isinf(Manopt.max_stepsize(M)) + @test isinf(Manopt.max_stepsize(M, :NoPoint)) + end end diff --git a/test/solvers/test_cma_es.jl b/test/solvers/test_cma_es.jl index 61c036d79e..25ea1f8c7f 100644 --- a/test/solvers/test_cma_es.jl +++ b/test/solvers/test_cma_es.jl @@ -109,7 +109,7 @@ flat_example(::AbstractManifold, p) = 0.0 σ=10.0, stopping_criterion=StopAfterIteration(500) | StopWhenPopulationStronglyConcentrated(1e-5), - rng=MersenneTwister(123), + rng=MersenneTwister(12), return_state=true, ) flat_sc = only(get_active_stopping_criteria(o_flat.stop))