Skip to content

Commit 2682813

Browse files
committed
test: add stupid test for get_initial_stepsize
1 parent b941227 commit 2682813

2 files changed

Lines changed: 68 additions & 33 deletions

File tree

src/plans/stepsize.jl

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,39 +1691,31 @@ end
16911691
@doc raw"""
16921692
DistanceOverGradientsStepsize{R<:Real} <: Stepsize
16931693
1694-
Implements the Riemannian Distance over Gradients (RDoG) stepsize schedule, a learning-rate-free
1695-
optimization method for Riemannian manifolds introduced by [DoddSharrockNemeth:2024].
1696-
1697-
This stepsize adapts automatically without hyperparameter tuning by tracking the maximum distance
1698-
from the initial point and accumulating gradient norms.
1699-
17001694
# Fields
17011695
1702-
* `initial_distance::R`: initial distance estimate ``ϵ > 0``
1703-
* `max_distance::R`: maximum distance from initial point ``\bar{r}_t = \max_{s≤t} d(p_0, p_s)``
1704-
* `gradient_sum::R`: accumulated squared gradient norms ``G_t = \sum_{s=0}^t \|∇f(p_s)\|^2``
1705-
* `initial_point`: the initial point ``p_0``
1706-
* `use_curvature::Bool`: whether to use sectional curvature in the stepsize
1707-
* `sectional_curvature_bound::R`: lower bound on sectional curvature ``κ`` (only used if `use_curvature=true`)
1708-
1709-
To see how stepsize at iteration ``t`` is computed see [`geometric_curvature_function`](@ref).
1696+
* `initial_distance::R`: initial distance estimate ``ϵ>0``
1697+
* `max_distance::R`: tracked maximum distance ``\bar r_t``
1698+
* `gradient_sum::R`: accumulated sum ``G_t``
1699+
* `initial_point`: stored start point ``p_0``
1700+
* `use_curvature::Bool`: toggle curvature correction ``ζ_κ``
1701+
* `sectional_curvature_bound::R`: lower bound ``κ`` used in ``ζ_κ`` when `use_curvature=true`
1702+
* `last_stepsize::R`: last computed stepsize
17101703
17111704
# Constructor
17121705
17131706
DistanceOverGradientsStepsize(M::AbstractManifold; kwargs...)
17141707
1715-
Initialize the RDoG stepsize on manifold `M`.
1716-
17171708
## Keyword arguments
17181709
1719-
* `initial_distance=1e-3`: initial distance estimate ``ϵ``
1720-
* `use_curvature=false`: whether to incorporate sectional curvature
1721-
* `sectional_curvature_bound=0.0`: lower bound on sectional curvature (if known)
1722-
$(_var(:Keyword, :p; add="initial point, used to track distances"))
1710+
* `initial_distance=1e-3`: initial estimate ``ϵ``
1711+
* `use_curvature=false`: whether to use ``ζ_κ``
1712+
* `sectional_curvature_bound=0.0`: lower curvature bound ``κ`` (if known)
1713+
$(_var(:Keyword, :p; add = "initial point, used to track distances"))
17231714
1724-
# See also
1715+
# References
17251716
1726-
[`AdaptiveWNGradientStepsize`](@ref), [`gradient_descent`](@ref)
1717+
[DoddSharrockNemeth:2024](@cite): Learning-Rate-Free Stochastic Optimization over
1718+
Riemannian Manifolds (RDoG).
17271719
"""
17281720
mutable struct DistanceOverGradientsStepsize{R <: Real, P} <: Stepsize
17291721
initial_distance::R
@@ -1759,15 +1751,17 @@ end
17591751
@doc raw"""
17601752
geometric_curvature_function(κ::Real, d::Real)
17611753
1762-
Compute the geometric curvature function ``ζ_κ(d)`` for sectional curvature bound ``κ``.
1754+
Compute the geometric curvature function ``ζ_κ(d)`` used by the RDoG stepsize:
17631755
17641756
```math
1765-
η_t = \frac{\bar{r}_t}{\sqrt{ζ_κ(\bar{r}_t)} \sqrt{G_t}}
1757+
ζ_κ(d) =
1758+
\begin{cases}
1759+
1, & \text{if } κ \ge 0,\\[4pt]
1760+
\dfrac{\sqrt{|κ|}\,d}{\tanh(\sqrt{|κ|}\,d)}, & \text{if } κ < 0.
1761+
\end{cases}
17661762
```
17671763
1768-
where ``ζ_κ`` is the geometric curvature function:
1769-
- ``ζ_κ(d) = 1`` if ``κ ≥ 0`` or `use_curvature=false`
1770-
- ``ζ_κ(d) = \frac{\sqrt{|κ|} d}{\tanh(\sqrt{|κ|} d)}`` if ``κ < 0``
1764+
For small arguments, a Taylor approximation is used for numerical stability.
17711765
"""
17721766
function geometric_curvature_function::Real, d::Real)
17731767
if κ < 0 && d > 0
@@ -1855,17 +1849,58 @@ function show(io::IO, rdog::DistanceOverGradientsStepsize)
18551849
return print(io, s)
18561850
end
18571851

1858-
"""
1852+
@doc raw"""
18591853
DistanceOverGradients(; kwargs...)
18601854
DistanceOverGradients(M::AbstractManifold; kwargs...)
18611855
1862-
Creates a factory for the [`DistanceOverGradientsStepsize`](@ref).
1856+
Create a factory for the [`DistanceOverGradientsStepsize`](@ref), the
1857+
Riemannian Distance over Gradients (RDoG) learning-rate-free stepsize from
1858+
[DoddSharrockNemeth:2024](@cite). It adapts via the maximum distance from the
1859+
start point and the accumulated gradient norms, optionally corrected by the
1860+
geometric curvature term ``ζ_κ``.
1861+
1862+
Riemannian Distance over Gradients (RDoG) learning-rate-free stepsize schedule
1863+
introduced by [DoddSharrockNemeth:2024]. This schedule adapts without manual
1864+
tuning by combining a distance proxy from the start point with accumulated
1865+
gradient norms.
1866+
1867+
Definitions used by the implementation:
1868+
1869+
* ``\bar r_t := \max(\,ϵ,\, \max_{0\le s\le t} d(p_0, p_s)\,)`` tracks the maximum geodesic
1870+
distance from the initial point ``p_0`` using the current iterate ``p_t``.
1871+
* ``G_t := \sum_{s=0}^t \lVert g_s \rVert^2``, where ``g_s = \operatorname{grad} f(p_s)``.
1872+
1873+
At iteration ``t`` the stepsize used here is
1874+
1875+
```math
1876+
η_t =
1877+
\begin{cases}
1878+
\dfrac{\bar r_t}{\sqrt{G_t}}, & \text{if `use_curvature = false`,}\\[6pt]
1879+
\dfrac{\bar r_t}{\sqrt{\,ζ_κ(\bar r_t)\,}\,\sqrt{G_t}}, & \text{if `use_curvature = true`,}
1880+
\end{cases}
1881+
```
1882+
1883+
with the geometric curvature function ``ζ_κ(d)`` defined in
1884+
[`geometric_curvature_function`](@ref). The initialization in this
1885+
implementation follows the paper: on the first call (``t=0``), we set
1886+
``G_0=\lVert g_0\rVert^2``, ``\bar r_0 = ϵ`` and take
1887+
1888+
```math
1889+
η_0 =
1890+
\begin{cases}
1891+
\dfrac{ϵ}{\lVert g_0\rVert}, & \text{if `use_curvature = false`,}\\[6pt]
1892+
\dfrac{ϵ}{\sqrt{\,ζ_κ(ϵ)\,}\,\lVert g_0\rVert}, & \text{if `use_curvature = true`.}
1893+
\end{cases}
1894+
```
1895+
1896+
On subsequent calls, the state is updated as implemented: ``G_t \leftarrow G_{t-1}
1897+
+ \lVert g_t\rVert^2`` and ``\bar r_t \leftarrow \max(\bar r_{t-1}, d(p_0,p_t))``.
18631898
18641899
## Keyword arguments
18651900
1866-
* `initial_distance=1e-3`: initial distance estimate
1867-
* `use_curvature=false`: whether to use sectional curvature
1868-
* `sectional_curvature_bound=0.0`: lower bound on sectional curvature
1901+
* `initial_distance=1e-3`: initial distance estimate ``ϵ``
1902+
* `use_curvature=false`: whether to include ``ζ_κ``
1903+
* `sectional_curvature_bound=0.0`: curvature lower bound ``κ`` (if known)
18691904
18701905
$(_note(:ManifoldDefaultFactory, "DistanceOverGradientsStepsize"))
18711906
"""

test/plans/test_stepsize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using LinearAlgebra, ManifoldsBase, Manopt, Manifolds, Test
1+
using ManifoldsBase, Manopt, Manifolds, Test
22

33
s = joinpath(@__DIR__, "..", "ManoptTestSuite.jl")
44
!(s in LOAD_PATH) && (push!(LOAD_PATH, s))

0 commit comments

Comments
 (0)