Skip to content

Commit

Permalink
Better convergence assessment. (#244)
Browse files Browse the repository at this point in the history
* Better convergence assessment.

* Move nan-check out of assess.
  • Loading branch information
pkofod authored Jun 12, 2020
1 parent 3e4cf24 commit f07b4e7
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 18 deletions.
7 changes: 2 additions & 5 deletions src/nlsolve/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ function assess_convergence(x,
xtol,
ftol)
x_converged, f_converged = false, false
if !any(isnan, x_previous) && norm(x-x_previous) <= xtol
if norm(x-x_previous) <= xtol
x_converged = true
end

if maximum(abs, f) <= ftol
f_converged = true
end

converged = x_converged || f_converged

return x_converged, f_converged, converged
return x_converged, f_converged
end

function check_isfinite(x::AbstractArray)
Expand Down
6 changes: 5 additions & 1 deletion src/solvers/anderson.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ end
end

# check convergence
x_converged, f_converged, converged = assess_convergence(cache.g, cache.x, fx, xtol, ftol)
x_converged, f_converged = assess_convergence(cache.g, cache.x, fx, xtol, ftol)
if any(isnan, cache.x) || any(isnan, value(df))
break
end
converged = x_converged || f_converged
converged && break

# update current iterate
Expand Down
14 changes: 8 additions & 6 deletions src/solvers/broyden.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ function broyden_(df::Union{NonDifferentiable, OnceDifferentiable},
Jinv = Matrix{T}(I, n, n)
check_isfinite(value(df))
it = 0
x_converged, f_converged, converged = assess_convergence(value(df), ftol)
x_converged, f_converged = assess_convergence(x, xold, value(df), NaN, ftol)
stopped = any(isnan, x) || any(isnan, value(df)) ? true : false

# FIXME: How should this flag be set?
mayterminate = false
converged = x_converged || f_converged

# Maintain a cache for line search results
# lsr = LineSearches.LineSearchResults(T)
# lsr = LineSearches.LineSearchResults(T)

tr = SolverTrace()
tracing = store_trace || show_trace || extended_trace
Expand All @@ -61,7 +61,7 @@ function broyden_(df::Union{NonDifferentiable, OnceDifferentiable},
maybe_stuck = false
max_resets = 3
resets = 0
while !converged && it < iterations
while !stopped && !converged && it < iterations

it += 1

Expand Down Expand Up @@ -99,8 +99,10 @@ function broyden_(df::Union{NonDifferentiable, OnceDifferentiable},
end

if !maybe_stuck
x_converged, f_converged, converged = assess_convergence(x, xold, value(df), xtol, ftol)
x_converged, f_converged = assess_convergence(x, xold, value(df), xtol, ftol)
converged = x_converged || f_converged
end
stopped = any(isnan, x) || any(isnan, value(df)) ? true : false

maybe_stuck = false
@broydentrace sqeuclidean(x, xold)
Expand Down
11 changes: 8 additions & 3 deletions src/solvers/newton.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ function newton_(df::OnceDifferentiable,
check_isfinite(value(df))
vecvalue = vec(value(df))
it = 0
x_converged, f_converged, converged = assess_convergence(value(df), ftol)
x_converged, f_converged = assess_convergence(initial_x, cache.xold, value(df), NaN, ftol)
stopped = any(isnan, cache.x) || any(isnan, value(df)) ? true : false

converged = x_converged || f_converged
x_ls = copy(cache.x)
tr = SolverTrace()
tracing = store_trace || show_trace || extended_trace
Expand Down Expand Up @@ -79,7 +82,7 @@ function newton_(df::OnceDifferentiable,
end
dfo = OnceDifferentiable(fo, go!, fgo!, cache.x, zero(real(T)))

while !converged && it < iterations
while !stopped && !converged && it < iterations

it += 1

Expand Down Expand Up @@ -117,8 +120,10 @@ function newton_(df::OnceDifferentiable,
end
# fvec is here also updated in the linesearch so no need to call f again.
copyto!(cache.x, x_ls)
x_converged, f_converged, converged = assess_convergence(cache.x, cache.xold, value(df), xtol, ftol)
x_converged, f_converged = assess_convergence(cache.x, cache.xold, value(df), xtol, ftol)
stopped = any(isnan, cache.x) || any(isnan, value(df)) ? true : false

converged = x_converged || f_converged
newtontrace(sqeuclidean(cache.x, cache.xold), tracing, extended_trace, cache, df, it, tr, store_trace, show_trace)
end
return SolverResults("Newton with line-search",
Expand Down
12 changes: 9 additions & 3 deletions src/solvers/trust_region.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ function trust_region_(df::OnceDifferentiable,
check_isfinite(cache.r)

it = 0
x_converged, f_converged, converged = assess_convergence(value(df), ftol)
x_converged, f_converged = assess_convergence(initial_x, cache.xold, value(df), NaN, ftol)
stopped = any(isnan, cache.x) || any(isnan, value(df)) ? true : false

converged = x_converged || f_converged
delta = convert(real(T), NaN)
rho = convert(real(T), NaN)
if converged
Expand Down Expand Up @@ -160,7 +163,7 @@ function trust_region_(df::OnceDifferentiable,

eta = convert(real(T), 1e-4)

while !converged && it < iterations
while !stopped && !converged && it < iterations
it += 1

# Compute proposed iteration step
Expand All @@ -187,10 +190,12 @@ function trust_region_(df::OnceDifferentiable,
end
end

x_converged, f_converged, converged = assess_convergence(cache.x, cache.xold, cache.r, xtol, ftol)
x_converged, f_converged = assess_convergence(cache.x, cache.xold, cache.r, xtol, ftol)
converged = x_converged || f_converged
else
cache.x .-= cache.p
x_converged, converged = false, false

end

@trustregiontrace euclidean(cache.x, cache.xold)
Expand All @@ -203,6 +208,7 @@ function trust_region_(df::OnceDifferentiable,
elseif rho >= 0.5
delta = max(delta, 2 * wnorm(cache.d, cache.p))
end
stopped = any(isnan, cache.x) || any(isnan, value(df)) ? true : false
end

name = "Trust-region with dogleg"
Expand Down

2 comments on commit f07b4e7

@pkofod
Copy link
Member Author

@pkofod pkofod commented on f07b4e7 Jun 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/16251

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v4.4.0 -m "<description of version>" f07b4e7788930d22d7710fba9c9d495261ec5b4b
git push origin v4.4.0

Please sign in to comment.