Levenberg-Marquardt
Manopt.LevenbergMarquardt — Function
LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)
LevenbergMarquardt(M, vgf, p; kwargs...)
LevenbergMarquardt(M, nlso, p; kwargs...)
LevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)
LevenbergMarquardt!(M, vgf, p; kwargs...)
LevenbergMarquardt!(M, nlso, p; kwargs...)compute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22, BB26] to solve
\[\operatorname*{arg\,min}_{p ∈ \mathcal{M}} f(p), \qquad f(p) = \frac{1}{2} \sum_{i=1}^{m} ρ_i \bigl( \lVert F_i(p) \rVert^2 \bigr)\]
where $F_i: \mathcal{M} → ℝ^{n_i}$ is the $i$th block component of length $n_i > 0$ and each $ρ_i: ℝ → ℝ$ is a robustifier function, cf. AbstractRobustifierFunction, for each such a block component. The overall residual function is denoted by $F: \mathcal{M} → ℝ^{n}$ with $n = \sum_{i=1}^{m} n_i$ and concatenates all block components.
The second block of signatures perform the optimization in-place of p.
The regularization parameter is updated using a generalized scheme proposed in [Fan06], Eq. (2.2). See also [Yua15] for other schemes. The generalized scheme offers separate thresholds for the acceptance of new points (candidate_acceptance_threshold), decreasing the regularization parameter (damping_reduction_threshold) and increasing the regularization parameter (damping_increase_threshold).
Input
M::AbstractManifold: a Riemannian manifold $\mathcal{M}$f: a residual function $f: \mathcal{M}→ℝ^m$. The residual function can be provided in two different ways- as a single function returning a vector $f(p) ∈ ℝ^m$
- as a vector of functions, where each single function returns a scalar $f_i(p) ∈ ℝ$
function_type=keyword argument.jacobian_f: the Jacobian of $f$. The Jacobian can be provided in three different ways- as a single function returning a vector of gradient vectors $\bigl(\operatorname{grad} f_i(p)\bigr)_{i=1}^m$
- as a vector of functions, where each single function returns a gradient vector $\operatorname{grad} f_i(p)$, $i=1,…,m$
- as a single function returning a (coefficient) matrix $J ∈ ℝ^{m×d}$, where $d$ is the dimension of the manifold.
AbstractBasisof the tangent space atp. The type is determined by thejacobian_type=keyword argument.p::P: a point on the manifold $\mathcal{M}$num_components: length $m$ of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by callingfone additional time. This is only possible whenevaluationisAllocatingEvaluation, for mutating evaluation this value must be explicitly specified.
You can also provide the cost and its Jacobian already as a VectorGradientFunction vgf to indicate you are working on a single block, Alternatively, passing a ManifoldNonlinearLeastSquaresObjective nlso also works.
Keyword arguments
If you provide f and its jacobian
evaluation::AbstractEvaluationType=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.function_type=FunctionVectorialType: anAbstractVectorialTypespecifying the type of cost function provided.jacobian_type=FunctionVectorialType: anAbstractVectorialTypespecifying the type of Jacobian provided.
as well as then these are already combined in a single VectorGradientFunction vgf
robustifier::AbstractRobustifierFunction=IdentityRobustifier(): for the robust variant, specify how the robustification is meant to take place.- if you provide a single vectorial function and its Jacobian, a single robustifer is applied to every component function of this vectorial function (each component is a block in the sum)
- if you provide a vector of
VectorGradientFunctions, each needs a robustifier.
evaluation::AbstractEvaluationType=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
as well as in general using the model improvement parameter $m_k$ in several places, cf [BB26]
candidate_acceptance_threshold=0.2: sufficient model improvement $η ∈ (0,1)$, i.e. $m_k > η$ to accept a candidate pointdamping_increase_factor=5.0: factor $β_{\text{i}}$ to increase damping, when the model is inaccuratedamping_increase_threshold=candidate_acceptance_threshold: threshold $η_{\text{l}}$ the value $m_k$has to be below to increase damping. The default yields, that we increase damping when we reject a candidate.damping_reduction_factor= 1 / damping_increase_factor: factor $β_{\text{d}}$ to reduce damping, when the model is accuratedamping_reduction_threshold=Inf: threshold $β_{\text{d}}$ to reduce damping, when the model is accurate The default means, that we never reduce damping.damping_term_min = 0.1: lower bound $μ_{\text{l}}$ for the damping $μ_k$ throughout the iterationsdamping_term_max = Inf: upper bound $μ_{\text{u}}$ for the damping $μ_k$ throughout the iterationsinitial_damping_term=damping_term_min: initial damping $μ_0$initial_residual_values = zeros(m): a cache for the vector of residuals,mis the number of residual blocksinitial_jacobian_matrices: a cache for the evaluated Jacobians (currently only used ifuse_unified_basis = true, then initialised to a vector of jacobian matrices, otherwise ignored)retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractionsscaling_threshold = 1.0e-6: a thresholdεto bound the scaling parameterαin the robust case away from1, seeget_LevenbergMarquardt_scalingscaling_mode = :Strict: specify the scaling stabilization mode, seeget_LevenbergMarquardt_scalingstopping_criterion::StoppingCriterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-12)|StopWhenStepsizeLess(1.0e-12): a functor indicating that the stopping criterion is fulfilledsub_objective: specify the objective for the surrogate sub problem to solver in every iteration. This is set depending on theuse_unified_basis- if
trueto theLevenbergMarquardtLinearSurrogateCoordinatesObjectivewhich always works in coordinates of one single basis per tangent space and allows to cache Jacobian evaluations - if
falseto theLevenbergMarquardtLinearSurrogateObjectivethat can work either with linear operators or in (even different) coordinates.
This keyword is ignored if you set the
sub_problemand/orsub_statekeyword directly- if
sub_problem =DefaultManoptProblem(TangentSpace(M, p), sub_objective): specify the sub problem to be solved. This should usually be phrased on the tangent space at the current iteratesub_state =ConjugateResidualState(TangentSpace(M, p), sub_objective): specify the solver for the surrogate, see alsoconjugate_residualuse_unified_basis = false: specify to use a single basis for all Jacobian evaluations at a certain iterate, seesub_objectivethis requires that all Jacobians involved are of typeCoefficientVectorialType, since only then a jacobian can be represented as a matrix, and then here unified in the sense that all use the same basis.
All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.
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.
Manopt.LevenbergMarquardt! — Function
LevenbergMarquardt(M, f, jacobian_f, p, num_components=-1; kwargs...)
LevenbergMarquardt(M, vgf, p; kwargs...)
LevenbergMarquardt(M, nlso, p; kwargs...)
LevenbergMarquardt!(M, f, jacobian_f, p, num_components=-1; kwargs...)
LevenbergMarquardt!(M, vgf, p; kwargs...)
LevenbergMarquardt!(M, nlso, p; kwargs...)compute the the Riemannian Levenberg-Marquardt algorithm [Pee93, AOT22, BB26] to solve
\[\operatorname*{arg\,min}_{p ∈ \mathcal{M}} f(p), \qquad f(p) = \frac{1}{2} \sum_{i=1}^{m} ρ_i \bigl( \lVert F_i(p) \rVert^2 \bigr)\]
where $F_i: \mathcal{M} → ℝ^{n_i}$ is the $i$th block component of length $n_i > 0$ and each $ρ_i: ℝ → ℝ$ is a robustifier function, cf. AbstractRobustifierFunction, for each such a block component. The overall residual function is denoted by $F: \mathcal{M} → ℝ^{n}$ with $n = \sum_{i=1}^{m} n_i$ and concatenates all block components.
The second block of signatures perform the optimization in-place of p.
The regularization parameter is updated using a generalized scheme proposed in [Fan06], Eq. (2.2). See also [Yua15] for other schemes. The generalized scheme offers separate thresholds for the acceptance of new points (candidate_acceptance_threshold), decreasing the regularization parameter (damping_reduction_threshold) and increasing the regularization parameter (damping_increase_threshold).
Input
M::AbstractManifold: a Riemannian manifold $\mathcal{M}$f: a residual function $f: \mathcal{M}→ℝ^m$. The residual function can be provided in two different ways- as a single function returning a vector $f(p) ∈ ℝ^m$
- as a vector of functions, where each single function returns a scalar $f_i(p) ∈ ℝ$
function_type=keyword argument.jacobian_f: the Jacobian of $f$. The Jacobian can be provided in three different ways- as a single function returning a vector of gradient vectors $\bigl(\operatorname{grad} f_i(p)\bigr)_{i=1}^m$
- as a vector of functions, where each single function returns a gradient vector $\operatorname{grad} f_i(p)$, $i=1,…,m$
- as a single function returning a (coefficient) matrix $J ∈ ℝ^{m×d}$, where $d$ is the dimension of the manifold.
AbstractBasisof the tangent space atp. The type is determined by thejacobian_type=keyword argument.p::P: a point on the manifold $\mathcal{M}$num_components: length $m$ of the vector returned by the cost function. By default its value is -1 which means that it is determined automatically by callingfone additional time. This is only possible whenevaluationisAllocatingEvaluation, for mutating evaluation this value must be explicitly specified.
You can also provide the cost and its Jacobian already as a VectorGradientFunction vgf to indicate you are working on a single block, Alternatively, passing a ManifoldNonlinearLeastSquaresObjective nlso also works.
Keyword arguments
If you provide f and its jacobian
evaluation::AbstractEvaluationType=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.function_type=FunctionVectorialType: anAbstractVectorialTypespecifying the type of cost function provided.jacobian_type=FunctionVectorialType: anAbstractVectorialTypespecifying the type of Jacobian provided.
as well as then these are already combined in a single VectorGradientFunction vgf
robustifier::AbstractRobustifierFunction=IdentityRobustifier(): for the robust variant, specify how the robustification is meant to take place.- if you provide a single vectorial function and its Jacobian, a single robustifer is applied to every component function of this vectorial function (each component is a block in the sum)
- if you provide a vector of
VectorGradientFunctions, each needs a robustifier.
evaluation::AbstractEvaluationType=AllocatingEvaluation(): specify whether the functions that return an array, for example a point or a tangent vector, work by allocating its result (AllocatingEvaluation) or whether they modify their input argument to return the result therein (InplaceEvaluation). Since usually the first argument is the manifold, the modified argument is the second.
as well as in general using the model improvement parameter $m_k$ in several places, cf [BB26]
candidate_acceptance_threshold=0.2: sufficient model improvement $η ∈ (0,1)$, i.e. $m_k > η$ to accept a candidate pointdamping_increase_factor=5.0: factor $β_{\text{i}}$ to increase damping, when the model is inaccuratedamping_increase_threshold=candidate_acceptance_threshold: threshold $η_{\text{l}}$ the value $m_k$has to be below to increase damping. The default yields, that we increase damping when we reject a candidate.damping_reduction_factor= 1 / damping_increase_factor: factor $β_{\text{d}}$ to reduce damping, when the model is accuratedamping_reduction_threshold=Inf: threshold $β_{\text{d}}$ to reduce damping, when the model is accurate The default means, that we never reduce damping.damping_term_min = 0.1: lower bound $μ_{\text{l}}$ for the damping $μ_k$ throughout the iterationsdamping_term_max = Inf: upper bound $μ_{\text{u}}$ for the damping $μ_k$ throughout the iterationsinitial_damping_term=damping_term_min: initial damping $μ_0$initial_residual_values = zeros(m): a cache for the vector of residuals,mis the number of residual blocksinitial_jacobian_matrices: a cache for the evaluated Jacobians (currently only used ifuse_unified_basis = true, then initialised to a vector of jacobian matrices, otherwise ignored)retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractionsscaling_threshold = 1.0e-6: a thresholdεto bound the scaling parameterαin the robust case away from1, seeget_LevenbergMarquardt_scalingscaling_mode = :Strict: specify the scaling stabilization mode, seeget_LevenbergMarquardt_scalingstopping_criterion::StoppingCriterion=StopAfterIteration(500)|StopWhenGradientNormLess(1.0e-12)|StopWhenStepsizeLess(1.0e-12): a functor indicating that the stopping criterion is fulfilledsub_objective: specify the objective for the surrogate sub problem to solver in every iteration. This is set depending on theuse_unified_basis- if
trueto theLevenbergMarquardtLinearSurrogateCoordinatesObjectivewhich always works in coordinates of one single basis per tangent space and allows to cache Jacobian evaluations - if
falseto theLevenbergMarquardtLinearSurrogateObjectivethat can work either with linear operators or in (even different) coordinates.
This keyword is ignored if you set the
sub_problemand/orsub_statekeyword directly- if
sub_problem =DefaultManoptProblem(TangentSpace(M, p), sub_objective): specify the sub problem to be solved. This should usually be phrased on the tangent space at the current iteratesub_state =ConjugateResidualState(TangentSpace(M, p), sub_objective): specify the solver for the surrogate, see alsoconjugate_residualuse_unified_basis = false: specify to use a single basis for all Jacobian evaluations at a certain iterate, seesub_objectivethis requires that all Jacobians involved are of typeCoefficientVectorialType, since only then a jacobian can be represented as a matrix, and then here unified in the sense that all use the same basis.
All other keyword arguments are passed to decorate_state! for state decorators or decorate_objective! for objective decorators, respectively.
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.
Options
Manopt.LevenbergMarquardtState — Type
LevenbergMarquardtState{P,T} <: AbstractGradientSolverStateDescribes a Gradient based descent algorithm, with
Fields
damping_term: current value of the damping termdamping_term_min: lower bound for the damping termdamping_term_max: upper bound for the damping termdamping_increase_factor: improvement quotient exceedsdamping_reduction_threshold.damping_reduction_threshold: threshold for the improvement quotient above which the damping term is reduced by multiplying it withβ_reduction.damping_increase_threshold: threshold for the improvement quotient below which the damping term is increased by multiplying it withβ.direction: the current search direction, which is the solution of the linearized subproblem in each iteration.candidate_acceptance_threshold: Scaling factor for the sufficient cost decrease threshold required to accept new proposal points. Allowed range:0 < η < 1.jacobian_matrices: the current Jacobian of $F$ in matrix form per block, hence a vector of matrices. This is (by default) set tonothingif another representation is used.minimum_acceptable_model_improvement: the minimum improvement in the model function that is required to accept a new point; if this is not met, the new point is rejected and the damping term is increased.p::P: a point on the manifold $\mathcal{M}$ storing the current iterateretraction_method::AbstractRetractionMethod: a retraction $\operatorname{retr}$ to use, see the section on retractionsresidual_values: values of the residuals calculated in the solver setup or the previous iterationstop::StoppingCriterion: a functor indicating that the stopping criterion is fulfilledsub_problem::Union{AbstractManoptProblem, F}: specify a problem for a solver or a closed form solution function, which can be allocating or in-place.sub_state::Union{AbstractManoptProblem, F}: a state to specify the sub solver to use. For a closed form solution, this indicates the type of function.X::T: a tangent vector at the point $p$ on the manifold $\mathcal{M}$
Constructor
LevenbergMarquardtState(M, sub_problem, sub_state, initial_residual_values, initial_jacobian; kwargs...)Generate the Levenberg-Marquardt solver state.
Keyword arguments
The following fields are keyword arguments
candidate_acceptance_threshold = 0.2,damping_increase_factor = 5.0damping_reduction_factor = 0.5damping_term_min = 0.1damping_term_max = Infdamping_term = damping_term_mindamping_reduction_threshold = Infdamping_increase_threshold = candidate_acceptance_thresholddirection = copy(M, p, X)p =rand(M)X =zero_vector(M, p)retraction_method::AbstractRetractionMethod=default_retraction_method(M, typeof(p)): a retraction $\operatorname{retr}$ to use, see the section on retractionsstopping_criterion::StoppingCriterion=StopAfterIteration(200)|StopWhenGradientNormLess(1e-12)|StopWhenStepsizeLess(1e-12): a functor indicating that the stopping criterion is fulfilledminimum_acceptable_model_improvement::Real = eps(number_eltype(p))
See also
Sub-problem
A main ingredient of the Levenberg-Marquardt solver is the linear surrogate that is generated in every iteration and then solved, for example by considering the linear system of its optimality conditions. The following cases are available.
Manopt.AbstractLinearSurrogateObjective — Type
AbstractLinearSurrogateObjective{E <: AbstractEvaluationType, O <: AbstractManifoldObjective{E}} <: AbstractManifoldObjective{E}Provide a linear surrogate model for the given AbstractManifoldObjective O of the form
\[μ_p(X) = \frac{1}{2}\lVert \mathcal{L}(X) + y \rVert_{2}^2 + \frac{λ}{2}\lVert X \rVert_{p}^2, \qquad\text{ for }X ∈ T_{p}\mathcal{M}, λ ≥ 0,\]
where $\mathcal{L}$ is a linear operator on the tangent space at a point $p ∈ M$ that maps into some vector space $V$ and $y ∈ V$ is a fixed vector in that space and $\lVert ⋅ \rVert$ is a norm on $V$.
Both $\mathcal{L}$ and $y$ are derived from the objective O and usually depend on the base point $p ∈ M$.
Besides the usual methods defined for AbstractManifoldObjective that may be implemented like get_cost and get_gradient, the following methods should be implemented for a concrete subtype of AbstractLinearSurrogateObjective
get_linear_operatorto compute/evaluate the linear operator $\mathcal{L}$get_vector_fieldto compute/evaluate the vector $y$get_objectiveto provide access to the underlying objectiveO
See also the NormalEquationsObjective for the corresponding normal equations.
Manopt.AbstractLevenbergMarquardtLinearSurrogateObjective — Type
AbstractLevenbergMarquardtLinearSurrogateObjective{E<:AbstractEvaluationType}Abstract supertype for Levenberg-Marquardt surrogates like LevenbergMarquardtLinearSurrogateObjective and LevenbergMarquardtLinearSurrogateCoordinatesObjective.
Manopt.LevenbergMarquardtLinearSurrogateObjective — Type
LevenbergMarquardtLinearSurrogateObjective{E<:AbstractEvaluationType, VF<:AbstractManifoldFirstOrderObjective{E}, R} <: AbstractLevenbergMarquardtLinearSurrogateObjective{E}Given an ManifoldNonlinearLeastSquaresObjective objective and a penalty $λ$, this objective represents the penalized objective for the sub-problem to solve within every step of the Levenberg-Marquardt algorithm following the ideas of [TMHF00] given by
\[μ_p(X) = \frac{1}{2}\lVert \mathcal{L}(X) + y \rVert_{2}^2 + \frac{λ}{2}\lVert X \rVert_{p}^2, \qquad\text{ for }X ∈ T_{p}\mathcal{M}, λ ≥ 0,\]
where $X ∈ T_{p}\mathcal{M}$, $λ ≥ 0$ is the damping or penalty term, $\mathcal{L}: T_{p}\mathcal{M} → ℝ^n$ is a linear operator, and $y = y(p) ∈ ℝ^n$ is a vector field. For the derivation of the Riemannian case, see [BB26].
In order to build a surrogate also for the robustified Levenberg-Marquardt, introduce $α = 1 - \sqrt{1 + 2 \frac{ρ''(p)}{ρ'(p)}\lVert F(p) \rVert_{2}^2}$ and set $y = \frac{\sqrt{ρ'(p)}}{1-α}F(p)$ and $\mathcal{L}(X) = CJ_F(p)[X]$ with
\[C = \sqrt{ρ'(p)}(I-αP), \qquad P = \frac{F(p)F(p)^\mathrm{T}}{\lVert F(p) \rVert_{2}^2},\]
where $F(p) ∈ ℝ^n$ is the vector of residuals at point $p ∈ M$ and $J_F(p): T_{p}\mathcal{M} → ℝ^n$ is the Jacobian. These two can be accessed with get_vector_field for $y$ and get_linear_operator for $\mathcal{L}$, respectively. For technical details on the scaling using $α$, especially how the threshold and mode act as safeguards, see get_LevenbergMarquardt_scaling
Fields
objective: theManifoldNonlinearLeastSquaresObjectiveto penalizepenalty::Real: the damping term $λ$threshold::Real: threshold $ε$ for stabilization of $α$ as $α ≤ 1-ε$, seeget_LevenbergMarquardt_scalingmode::Symbol: which ode to use to stabilize α, see the internal helperget_LevenbergMarquardt_scalingvalue_cache: a vector to store the residuals $F(p)$ at the current pointpinternally to avoid re-computations
Constructor
LevenbergMarquardtLinearSurrogateObjective(objective; penalty::Real = 1e-6, threshold::Real = 1e-4, mode::Symbol = :Strict)Manopt.LevenbergMarquardtLinearSurrogateCoordinatesObjective — Type
LevenbergMarquardtLinearSurrogateCoordinatesObjective{E<:AbstractEvaluationType, VF<:AbstractManifoldFirstOrderObjective{E}, R} <: AbstractLevenbergMarquardtLinearSurrogateObjective{E}A subobjective similar to LevenbergMarquardtLinearSurrogateObjective but which uses coordinate-based Jacobians in a single, selected basis instead of being centered around linear operators.
Fields
objective: theManifoldNonlinearLeastSquaresObjectiveto penalizepenalty::Real: the damping term $λ$threshold::Real: stabilization $ε$ for $α ≤ 1-ε$ in the rescaling of the residual and jacobian, seeget_LevenbergMarquardt_scalingmode::Symbol: which mode to use to stabilize α, see the internal helperget_LevenbergMarquardt_scalingvalue_cache: a vector to store the residuals $F(p)$ at the current pointpinternally to avoid recomputationsjacobian_cache: a vector to store the coordinate-based Jacobian of the residuals at the current pointpinternally to avoid recomputations. If the Jacobian is used as a linear operator, this is just a vector ofnothings.
Constructor
LevenbergMarquardtLinearSurrogateCoordinatesObjective(objective; penalty::Real = 1e-6, threshold::Real = 1e-4, mode::Symbol = :Strict)Manopt.NormalEquationsObjective — Type
NormalEquationsObjective{E <: AbstractEvaluationType, O<: AbstractLinearSurrogateObjective{E}} <: AbstractSymmetricLinearSystemObjective{E}A AbstractLinearSurrogateObjective might be overdetermined, and it usually is overdetermined, e.g. for the case of the LevenbergMarquardt algorithm. For this case, one considers the normal equations.
This wrapper provides the same three functions as the wrapped surrogate
get_linear_operatorto compute/evaluate the linear operator $\mathcal{L}$get_vector_fieldto compute/evaluate the vector $y$get_objectiveto provide access to the underlying surrogate
so that we obtain a symmetric linear system of equations, that can be
- solved with an iterative method like
conjugate_gradient_descentorconjugate_residual - solved as a linear system in a basis of the corresponding tangent space.
Manopt.CoordinatesNormalSystemState — Type
CoordinatesNormalSystemState <: AbstractManoptSolverStateA solver state indicating that we solve the LevenbergMarquardtLinearSurrogateObjective using a linear system in coordinates of the tangent space at the current iterate
Fields
Aan $n×n$ matrix to store the normal equations linear fromget_linear_operatorin coordinates, wherenis the number of coordinatesba $n$ vector storing the right hand side of the normal equations in coordinatesbasis::AbstractBasislinsolvea functor(A,b) -> cto solve the linear system or(c, A, b) -> cdepending on the evaluation type specified insolve!
Constructor
CoordinatesNormalSystemState(
M::AbstractManifold, p = rand(M);
evaluation = InplaceEvaluation(),
linsolve = default_lm_lin_solve!,
basis = DefaultOrthonormalBasis(),
A = nothing
)Construct the state, where not providing a memory for A uses the eltype of p to determine the element type of the matrix to store.
Within these especially the scaling parameter $α$ is important. Its computation and numerical stability aspects are documented as follows.
Manopt.get_LevenbergMarquardt_scaling — Function
residual_scaling, operator_scaling = get_LevenbergMarquardt_scaling(ρ_prime::Real, ρ_double_prime::Real, FSq::Real, threshold::Real=1.0e-5, mode::Symbol=:Strict)Compute the scalings for the residual $y$ and within the operator $C$ that are required for the robust rescaling within LevenbergMarquardts get_vector_field and get_linear_operator, respectively. Here FSq denotes $s = \lVert F(p) \rVert_{2}^2$ of the residual vector function $F$ evaluated at some point $p$, and ρ_prime=ρ'(s) and ρ_double_prime=ρ''(s) denote the current AbstractRobustifierFunctions first and second derivative evaluated at $s$.
The value for $α$ is given by
\[ α = 1 - \sqrt{1 + 2\frac{ρ''(s)}{ρ'(s)}s}\]
and hence the scaling of the residual and the within the projection of the operator are
\[\frac{\sqrt{ρ'(s)}}{1-α} \qquad\text{ and }\qquad \begin{cases} \frac{α}{s} & \text{ if } s ≠ 0\\\\ 0 & \text{ else,}\end{cases}\]
respectively.
Numerical stability
For a unique solution that is a minimizer in a Levenberg-Marquardt step, we require α < 1 and [TMHF00] recommends to bound this even by $1-ε$ for some threshold $ε > 0$.
Furthermore if $ρ'(s) + 2ρ''(s)⋅s ≤ 0$ the Hessian is also indefinite. This can be caught by making sure the argument of the $√$ is ensured to be non-negative.
The Ceres solver even omits the second term in the square root already if $ρ(s)'' < 0$ for stability reason, which means setting $α = 0$. In the case $s = 0$ we also set the operator scaling $α / s = 0$.
This function offers two modes
:Normalkeeps negative $ρ''(s) < 0$ but makes sure the square root is well-defined.:Strict(default) set $α = 0$ when $ρ''(s) < 0$ or when $s = 0$
Solver Internals
Internal functions
Internally within the sub solvers both a linear operator, sometimes as a full matrix, and a vector as right hand side of a linear system have to be constructucted. The following functions accompany this.
Manopt.default_lm_lin_solve! — Function
default_lm_lin_solve!(sk, JJ::AbstractMatrix, grad_f_c)Solve the linear system of equations of the normal equations JJ \ grad_f_c where JJ is a symmetric positive definite matrix and save the result to sk. In case of numerical errors the PosDefException is caught and the default symmetric solver (Symmetric(JJ) \ grad_f_c) is used.
The function is intended to be used with LevenbergMarquardt.
Manopt.add_normal_vector_field! — Function
add_normal_vector_field!(M::AbstractManifold, X, o::AbstractFirstOrderVectorFunction, r::AbstractRobustifierFunction, p)
add_normal_vector_field!(M::AbstractManifold, c, o::AbstractFirstOrderVectorFunction, r::AbstractRobustifierFunction, p, B::AbstractBasis)Add the contribution of o / r to the normal linear operator tangent vector in X or c. See get_normal_vector_field for the mathematical details. Note that this is done per every block (vectorial function with its robustifier) of the underlying ManifoldNonlinearLeastSquaresObjective and summed up.
See also get_normal_linear_operator for evaluating the corresponding linear operator of the (normal) linear system, and get_LevenbergMarquardt_scaling for details on the scaling and computation of $C$.
Manopt.add_normal_linear_operator! — Function
add_normal_linear_operator!(
M::AbstractManifold, A::AbstractMatrix, o::AbstractFirstOrderVectorFunction,
r::AbstractRobustifierFunction, p, basis::AbstractBasis;
value_cache = get_value(M, o, p), ε::Real, mode::Symbol
)Add the contribution of a single block (vectorial function with its robustifier) to the linear normal operator, i.e. compute $A += J_F^*(p)[C^T C J_F(p)[X]]$ in-place of A for the given block. See get_normal_linear_operator for details
Manopt.add_linear_operator_coord! — Function
add_linear_operator_coord!(
M::AbstractManifold, y::AbstractVector, lmsco::LevenbergMarquardtLinearSurrogateCoordinatesObjective, p, cX::AbstractVector
)Add the (Triggs correction, residual-like) linear operator corresponding to the lmsco surrogate to vector y. It is assumed that lmsco.value_cache has been filled in step_solver! of LevenbergMarquardt, so we can just use it here.
Internal structures
The following structure helps to avoid allocating unnecessary zero vectors.
Manopt.ZeroTangentVector — Type
ZeroTangentVectorA small internal helper type to represent the zero tangent vector with two advantages
- we avoid to allocate it
- we can dispatch on it
Technical details
The LevenbergMarquardt solver requires the following functions of a manifold to be available
- A
retract!(M, q, p, X); it is recommended to set thedefault_retraction_methodto a favourite retraction. If this default is set, aretraction_method=does not have to be specified. - the
normas well, to stop when the norm of the gradient is small, but if you implementedinner, the norm is provided already. - A
copyto!(M, q, p)andcopy(M,p)for points.
Literature
- [AOT22]
- S. Adachi, T. Okuno and A. Takeda. Riemannian Levenberg-Marquardt Method with Global and Local Convergence Properties. ArXiv Preprint (2022).
- [BB26]
- M. Baran and R. Bergmann. A modified Riemannian Levenberg-Marquardt algorithm for robust and constraint optimization on manifolds (2026), arXiv:2606.23560 [math.OC].
- [Fan06]
- J. Fan. Convergence Rate of The Trust Region Method for Nonlinear Equations Under Local Error Bound Condition. Computational Optimization and Applications 34, 215–227 (2006).
- [Pee93]
- R. Peeters. On a Riemannian version of the Levenberg-Marquardt algorithm. Serie Research Memoranda 0011 (VU University Amsterdam, Faculty of Economics, Business Administration and Econometrics, 1993).
- [TMHF00]
- B. Triggs, P. F. McLauchlan, R. I. Hartley and A. W. Fitzgibbon. Bundle Adjustment — A Modern Synthesis. In: Vision Algorithms: Theory and Practice, Vol. 1883, edited by G. Goos, J. Hartmanis, J. Van Leeuwen, B. Triggs, A. Zisserman and R. Szeliski (Springer Berlin Heidelberg, Berlin, Heidelberg, 2000); pp. 298–372.
- [Yua15]
- Y.-x. Yuan. Recent advances in trust region algorithms. Mathematical Programming 151, 249–281 (2015).