Gradient descent

Manopt.gradient_descentFunction
gradient_descent(M, f, grad_f, p=rand(M); kwargs...)
gradient_descent(M, gradient_objective, p=rand(M); kwargs...)
gradient_descent!(M, f, grad_f, p; kwargs...)
gradient_descent!(M, gradient_objective, p; kwargs...)

perform the gradient descent algorithm

\[p_{k+1} = \operatorname{retr}_{p_k}\bigl( -s_k\operatorname{grad}f(p_k) \bigr), \qquad k=0,1,…\]

where $s_k > 0$ denotes a step size.

The algorithm can be performed in-place of p.

Input

  • M::AbstractManifold: a Riemannian manifold $\mathcal{M}$
  • f: a cost function $f: \mathcal{M}→ ℝ$ implemented as (M, p) -> v
  • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal{M} → T\mathcal{M}$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
  • p::P: a point on the manifold $\mathcal{M}$

Alternatively to f and grad_f you can provide the corresponding AbstractManifoldFirstOrderObjective gradient_objective directly.

Keyword arguments

All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

If you provide the ManifoldFirstOrderObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

Output

The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

source
Manopt.gradient_descent!Function
gradient_descent(M, f, grad_f, p=rand(M); kwargs...)
gradient_descent(M, gradient_objective, p=rand(M); kwargs...)
gradient_descent!(M, f, grad_f, p; kwargs...)
gradient_descent!(M, gradient_objective, p; kwargs...)

perform the gradient descent algorithm

\[p_{k+1} = \operatorname{retr}_{p_k}\bigl( -s_k\operatorname{grad}f(p_k) \bigr), \qquad k=0,1,…\]

where $s_k > 0$ denotes a step size.

The algorithm can be performed in-place of p.

Input

  • M::AbstractManifold: a Riemannian manifold $\mathcal{M}$
  • f: a cost function $f: \mathcal{M}→ ℝ$ implemented as (M, p) -> v
  • grad_f: the (Riemannian) gradient $\operatorname{grad}f: \mathcal{M} → T\mathcal{M}$ of f as a function (M, p) -> X or a function (M, X, p) -> X computing X in-place
  • p::P: a point on the manifold $\mathcal{M}$

Alternatively to f and grad_f you can provide the corresponding AbstractManifoldFirstOrderObjective gradient_objective directly.

Keyword arguments

All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.

If you provide the ManifoldFirstOrderObjective directly, the evaluation= keyword is ignored. The decorations are still applied to the objective.

If you activate tutorial mode (cf. is_tutorial_mode), this solver provides additional debug warnings.

Output

The obtained approximate minimizer $p^*$. To obtain the whole final state of the solver, see get_solver_return for details, especially the return_state= keyword.

source

State

Manopt.GradientDescentStateType
GradientDescentState{P,T} <: AbstractGradientSolverState

Describes the state of a gradient based descent algorithm.

Fields

  • callbacks::D: provided callback functions given as a dictionary with symbols as keys
  • p::P: a point on the manifold $\mathcal{M}$ storing the current iterate
  • X::T: a tangent vector at the point $p$ on the manifold $\mathcal{M}$ storing the gradient at the current iterate
  • stop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilled
  • stepsize::Stepsize: a functor inheriting from Stepsize to determine a step size
  • direction::DirectionUpdateRule : a processor to handle the obtained gradient and compute a direction to “walk into”.
  • retraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractions

Constructor

GradientDescentState(M::AbstractManifold; kwargs...)

Initialize the gradient descent solver state, where

Input

Keyword arguments

See also

gradient_descent

source

Direction update rules

A field of the state is the direction, a DirectionUpdateRule, which by default is the IdentityUpdateRule that just evaluates the gradient. The following ones are furthermore available

Manopt.AverageGradientMethod
AverageGradient(; kwargs...)
AverageGradient(M::AbstractManifold; kwargs...)

Add an average of gradients to a gradient processor. A set of previous directions (from the inner processor) and the last iterate are stored, average is taken after vector transporting them to the current iterate's tangent space.

Input

Keyword arguments

Info

This function generates a ManifoldDefaultsFactory for AverageGradientRule. For default values that depend on the manifold, this factory postpones the construction until the manifold is available, for example from a corresponding AbstractManoptSolverState.

source
Manopt.MomentumGradientMethod
MomentumGradient(args...; kwargs...)

Append a momentum to a gradient processor.

The last direction and last iterate are stored and the new one is composed as $η_k = m η_{k-1}' + d_k$, where $d_k$ is the current (inner) direction, $η_{k-1}'$ is the last direction transported to the current iterate, and $m$ is the momentum. The step size is not folded into $η_i$, the solver applies it to the returned direction. This is the Riemannian version of gradient descent with momentum, first used in [RMH18, Section 3.1]; see [LS26, Section 6] for a convergence analysis.

Input

  • M (optional)

Keyword arguments

Info

This function generates a ManifoldDefaultsFactory for MomentumGradientRule. For default values that depend on the manifold, this factory postpones the construction until the manifold is available, for example from a corresponding AbstractManoptSolverState.

source
Manopt.NesterovMethod
Nesterov(; kwargs...)
Nesterov(M::AbstractManifold; kwargs...)

Assume $f$ is $L$-Lipschitz and $μ$-strongly convex. Given

  • a step size $h_k<\frac{1}{L}$ (from the GradientDescentState)
  • a shrinkage parameter $β_k$
  • and a current iterate $p_k$
  • as well as the interim values $γ_k$ and $v_k$ from the previous iterate.

This computes a Nesterov type update using the following steps, see [ZS18]

  1. Compute the positive root $α_k∈(0,1)$ of $α_k^2 = h_k\bigl((1-α_k)γ_k+α_k μ\bigr)$.
  2. Set $\bar{γ}_{k+1} = (1-α_k)γ_k + α_kμ$
  3. $y_k = \operatorname{retr}_{p_k}\Bigl(\frac{α_kγ_k}{γ_k + α_kμ}\operatorname{retr}^{-1}_{p_k}v_k \Bigr)$
  4. $p_{k+1} = \operatorname{retr}_{y_k}(-h_k \operatorname{grad}f(y_k))$
  5. $v_{k+1} = \operatorname{retr}_{y_k}\Bigl(\frac{(1-α_k)γ_k}{\bar{γ}_{k+1}}\operatorname{retr}_{y_k}^{-1}(v_k) - \frac{α_k}{\bar{γ}_{k+1}}\operatorname{grad}f(y_k) \Bigr)$
  6. $γ_{k+1} = \frac{1}{1+β_k}\bar{γ}_{k+1}$

Then, with $d = \operatorname{retr}^{-1}_{p_k}p_{k+1}$ the direction from $p_k$ to $p_{k+1}$, the pair $(h_k, -d/h_k)$ is returned, so that the solver's step $\operatorname{retr}_{p_k}(-h_k ⋅ (-d/h_k))$ yields $p_{k+1}$.

Input

Keyword arguments

Info

This function generates a ManifoldDefaultsFactory for NesterovRule. For default values that depend on the manifold, this factory postpones the construction until the manifold is available, for example from a corresponding AbstractManoptSolverState.

source
Manopt.PreconditionedDirectionMethod
PreconditionedDirection(preconditioner; kwargs...)
PreconditionedDirection(M::AbstractManifold, preconditioner; kwargs...)

Add a preconditioner to a gradient processor following the motivation for optimization, as a linear invertible map $P: T_{p}\mathcal{M} → T_{p}\mathcal{M}$ that usually should be

  • symmetric: $⟨X, P(Y)⟩ = ⟨P(X), Y⟩$
  • positive definite $⟨X, P(X)⟩ > 0$ for $X$ not the zero-vector

The gradient is then preconditioned as $P(X)$, where $X$ is either the gradient of the objective or the result of a previous (internally stored) gradient processor.

For example if you provide as the preconditioner the inverse of the Hessian $\operatorname{Hess}^{-1} f$, you turn a gradient descent into a Newton method.

Arguments

  • M::AbstractManifold: a Riemannian manifold $\mathcal{M}$ (optional)
  • preconditioner: preconditioner function, either as a (M, p, X) -> Y allocating or (M, Y, p, X) -> Y mutating function

Keyword arguments

Info

This function generates a ManifoldDefaultsFactory for PreconditionedDirectionRule. For default values that depend on the manifold, this factory postpones the construction until the manifold is available, for example from a corresponding AbstractManoptSolverState.

source

Internal functions

Manopt.AverageGradientRuleType
AverageGradientRule <: DirectionUpdateRule

Add an average of gradients to a gradient processor.

A set of previous directions (from the inner processor) and the last iterate are stored. The average is taken after vector transporting them to the current iterate's tangent space.

Fields

Constructors

AverageGradientRule(    M::AbstractManifold;    p=rand(M),    n::Int=10,    direction::Union{<:DirectionUpdateRule,ManifoldDefaultsFactory}=Gradient(),    gradients=[zero_vector(M, p) for _ in 1:n],    vector_transport_method=default_vector_transport_method(M, typeof(p)))AverageGradientRule(M::AbstractManifold, p; kwargs...)

Add average to a gradient problem, where

source
Manopt.IdentityUpdateRuleType
IdentityUpdateRule <: DirectionUpdateRule

The default gradient direction update is the identity, usually it just evaluates the gradient.

You can also use Gradient() to create the corresponding factory, though this only delays this parameter-free instantiation to later.

source
Manopt.MomentumGradientRuleType
MomentumGradientRule <: DirectionUpdateRule

Store the necessary information to compute the MomentumGradient direction update, see [RMH18, LS26].

Fields

  • p_old::P: a point on the manifold $\mathcal{M}$
  • momentum::Real: factor for the momentum
  • direction: internal DirectionUpdateRule to determine directions to add the momentum to.
  • vector_transport_method::AbstractVectorTransportMethod: a vector transport $\mathcal T_{⋅←⋅}$ to use, see the section on vector transports
  • η_old::T: the momentum direction accumulated so far, that is the direction the rule returned in the last step. Note that this is not the last gradient.

Constructors

MomentumGradientRule(M::AbstractManifold; kwargs...)MomentumGradientRule(M::AbstractManifold, p; kwargs...)

Initialize a momentum gradient rule, where p and X are memory for interim values, the latter for the accumulated momentum direction η_old.

Keyword arguments

See also

MomentumGradient

source
Manopt.NesterovRuleType
NesterovRule <: DirectionUpdateRule

Compute a Nesterov inspired direction update rule. See Nesterov for details

Fields

Constructor

NesterovRule(M::AbstractManifold; kwargs...)NesterovRule(M::AbstractManifold, p; kwargs...)

Keyword arguments

See also

Nesterov

source
Manopt.PreconditionedDirectionRuleType
PreconditionedDirectionRule <: DirectionUpdateRule

Add a preconditioning as gradient processor, see PreconditionedDirection for more mathematical background.

Fields

  • direction: internal DirectionUpdateRule to determine directions to apply the preconditioning to
  • preconditioner: the preconditioner function

Constructors

PreconditionedDirectionRule(    M::AbstractManifold,    preconditioner;    direction::Union{<:DirectionUpdateRule,ManifoldDefaultsFactory}=IdentityUpdateRule(),    evaluation::AbstractEvaluationType=AllocatingEvaluation())

Add preconditioning to a gradient problem.

Input

  • M::AbstractManifold: a Riemannian manifold $\mathcal{M}$
  • preconditioner: preconditioner function, either as a (M, p, X) -> Y allocating or (M, Y, p, X) -> Y mutating function

Keyword arguments

source

Technical details

The gradient_descent solver requires the following functions of a manifold to be available

  • A retract!(M, q, p, X); it is recommended to set the default_retraction_method to a favorite retraction. If this default is set, a retraction_method= does not have to be specified.
  • By default gradient descent uses ArmijoLinesearch which requires max_stepsize(M) to be set and an implementation of inner(M, p, X, Y).
  • By default the stopping criterion uses the norm as well, to stop when the norm of the gradient is small, but if you implemented inner, the norm is provided already.
  • By default the tangent vector storing the gradient is initialized calling zero_vector(M,p).

Literature

[LS26]
F. Leggio and D. Scuppa. Riemannian Gradient Method with Momentum (2026), arXiv:2603.04078 [math.OC].
[Lue72]
D. G. Luenberger. The gradient projection method along geodesics. Management Science 18, 620–631 (1972).
[RMH18]
S. K. Roy, Z. Mhammedi and M. Harandi. Geometry Aware Constrained Optimization Techniques for Deep Learning. In: 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition (2018).
[ZS18]
H. Zhang and S. Sra. Towards Riemannian accelerated gradient methods, preprint (2018), arXiv:1806.02812.