Skip to content

Commit 6cf4ca3

Browse files
Merge branch 'JuliaSmoothOptimizers:master' into rayleigh
2 parents a8eb9c0 + 080e2ef commit 6cf4ca3

File tree

8 files changed

+465
-257
lines changed

8 files changed

+465
-257
lines changed

src/LMModel.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
export LMModel
2+
3+
@doc raw"""
4+
LMModel(j_prod!, jt_prod, F, v, σ, xk)
5+
6+
Given the unconstrained optimization problem:
7+
```math
8+
\min \tfrac{1}{2} \| F(x) \|^2,
9+
```
10+
this model represents the smooth LM subproblem:
11+
```math
12+
\min_s \ \tfrac{1}{2} \| F(x) + J(x)s \|^2 + \tfrac{1}{2} σ \|s\|^2
13+
```
14+
where `J` is the Jacobian of `F` at `xk`, represented via matrix-free operations.
15+
`j_prod!(xk, s, out)` computes `J(xk) * s`, and `jt_prod!(xk, r, out)` computes `J(xk)' * r`.
16+
17+
`σ > 0` is a regularization parameter and `v` is a vector of the same size as `F(xk)` used for intermediary computations.
18+
"""
19+
mutable struct LMModel{T <: Real, V <: AbstractVector{T}, Jac <: Union{AbstractMatrix, AbstractLinearOperator}} <:
20+
AbstractNLPModel{T, V}
21+
J::Jac
22+
F::V
23+
v::V
24+
xk::V
25+
σ::T
26+
meta::NLPModelMeta{T, V}
27+
counters::Counters
28+
end
29+
30+
function LMModel(J::Jac, F::V, σ::T, xk::V) where {T, V, Jac}
31+
meta = NLPModelMeta(
32+
length(xk),
33+
x0 = xk, # Perhaps we should add lvar and uvar as well here.
34+
)
35+
v = similar(F)
36+
return LMModel(J, F, v, xk, σ, meta, Counters())
37+
end
38+
39+
function NLPModels.obj(nlp::LMModel, x::AbstractVector{T}) where {T}
40+
@lencheck nlp.meta.nvar x
41+
increment!(nlp, :neval_obj)
42+
mul!(nlp.v, nlp.J, x)
43+
nlp.v .+= nlp.F
44+
return (dot(nlp.v, nlp.v) + nlp.σ * dot(x, x)) / 2
45+
end
46+
47+
function NLPModels.grad!(nlp::LMModel, x::AbstractVector{T}, g::AbstractVector{T}) where {T}
48+
@lencheck nlp.meta.nvar x
49+
@lencheck nlp.meta.nvar g
50+
increment!(nlp, :neval_grad)
51+
mul!(nlp.v, nlp.J, x)
52+
nlp.v .+= nlp.F
53+
mul!(g, nlp.J', nlp.v)
54+
@. g += nlp.σ .* x
55+
return g
56+
end

0 commit comments

Comments
 (0)