Skip to content

Commit f635c5c

Browse files
implicit jacobian update
1 parent 9d457ea commit f635c5c

File tree

2 files changed

+14
-21
lines changed

2 files changed

+14
-21
lines changed

src/LMModel.jl

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ where `J` is the Jacobian of `F` at `xk`, represented via matrix-free operations
1616
1717
`σ > 0` is a regularization parameter and `v` is a vector of the same size as `F(xk)` used for intermediary computations.
1818
"""
19-
mutable struct LMModel{T <: Real, V <: AbstractVector{T}, J <: Function , Jt <: Function} <:
19+
mutable struct LMModel{T <: Real, V <: AbstractVector{T}, Jac <: Union{AbstractMatrix, AbstractLinearOperator}} <:
2020
AbstractNLPModel{T, V}
21-
j_prod!::J
22-
jt_prod!::Jt
21+
J::Jac
2322
F::V
2423
v::V
2524
xk::V
@@ -28,30 +27,30 @@ mutable struct LMModel{T <: Real, V <: AbstractVector{T}, J <: Function , Jt <:
2827
counters::Counters
2928
end
3029

31-
function LMModel(j_prod!::J, jt_prod!::Jt, F::V, σ::T, xk::V) where {T, V, J, Jt}
30+
function LMModel(J::Jac, F::V, σ::T, xk::V) where {T, V, Jac}
3231
meta = NLPModelMeta(
3332
length(xk),
3433
x0 = xk, # Perhaps we should add lvar and uvar as well here.
3534
)
3635
v = similar(F)
37-
return LMModel(j_prod!, jt_prod!, F, v, xk, σ, meta, Counters())
36+
return LMModel(J, F, v, xk, σ, meta, Counters())
3837
end
3938

40-
function NLPModels.obj(nlp::LMModel, x::AbstractVector{T}) where{T}
39+
function NLPModels.obj(nlp::LMModel, x::AbstractVector{T}) where {T}
4140
@lencheck nlp.meta.nvar x
4241
increment!(nlp, :neval_obj)
43-
nlp.j_prod!(nlp.xk, x, nlp.v) # v = J(xk)x
42+
mul!(nlp.v, nlp.J, x)
4443
nlp.v .+= nlp.F
45-
return ( dot(nlp.v, nlp.v) + nlp.σ * dot(x, x) ) / 2
44+
return (dot(nlp.v, nlp.v) + nlp.σ * dot(x, x)) / 2
4645
end
4746

48-
function NLPModels.grad!(nlp::LMModel, x::AbstractVector{T}, g::AbstractVector{T}) where{T}
47+
function NLPModels.grad!(nlp::LMModel, x::AbstractVector{T}, g::AbstractVector{T}) where {T}
4948
@lencheck nlp.meta.nvar x
5049
@lencheck nlp.meta.nvar g
5150
increment!(nlp, :neval_grad)
52-
nlp.j_prod!(nlp.xk, x, nlp.v) # v = J(xk)x + F
51+
mul!(nlp.v, nlp.J, x)
5352
nlp.v .+= nlp.F
54-
nlp.jt_prod!(nlp.xk, nlp.v, g) # g = J^T(xk) v
53+
mul!(g, nlp.J', nlp.v)
5554
@. g += nlp.σ .* x
5655
return g
5756
end

src/LMTR_alg.jl

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,8 @@ function LMTRSolver(
6767
has_bnds ? shifted(reg_nls.h, xk, max.(-one(T), l_bound_m_x), min.(one(T), u_bound_m_x), reg_nls.selected) :
6868
shifted(reg_nls.h, xk, one(T), χ)
6969

70-
jprod! = let nls = reg_nls.model
71-
(x, v, Jv) -> jprod_residual!(nls, x, v, Jv)
72-
end
73-
jt_prod! = let nls = reg_nls.model
74-
(x, v, Jtv) -> jtprod_residual!(nls, x, v, Jtv)
75-
end
76-
77-
sub_nlp = LMModel(jprod!, jt_prod!, Fk, T(0), xk)
70+
Jk = jac_op_residual(reg_nls.model, xk)
71+
sub_nlp = LMModel(Jk, Fk, T(0), xk)
7872
subpb = RegularizedNLPModel(sub_nlp, ψ)
7973
substats = RegularizedExecutionStats(subpb)
8074
subsolver = subsolver(subpb)
@@ -300,7 +294,7 @@ function SolverCore.solve!(
300294
jtprod_residual!(nls, xk, Fk, ∇fk)
301295
fk = dot(Fk, Fk) / 2
302296

303-
σmax, found_σ = opnorm(jac_op_residual!(nls, xk, Jv, Jtv))
297+
σmax, found_σ = opnorm(solver.subpb.model.J)
304298
found_σ || error("operator norm computation failed")
305299
ν = α * Δk / (1 + σmax^2 ** Δk + 1))
306300
@. mν∇fk = -∇fk * ν
@@ -447,7 +441,7 @@ function SolverCore.solve!(
447441
shift!(ψ, xk)
448442
jtprod_residual!(nls, xk, Fk, ∇fk)
449443

450-
σmax, found_σ = opnorm(jac_op_residual!(nls, xk, Jv, Jtv))
444+
σmax, found_σ = opnorm(solver.subpb.model.J)
451445
found_σ || error("operator norm computation failed")
452446
end
453447

0 commit comments

Comments
 (0)