Skip to content

Commit

Permalink
Add time limit on Krylov solvers (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmigot authored Mar 30, 2024
1 parent 51e4865 commit 50125aa
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 12 deletions.
22 changes: 16 additions & 6 deletions src/tron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ function SolverCore.solve!(
s,
Hs,
max_cgiter = max_cgiter,
max_time = max_time - stats.elapsed_time,
subsolver_verbose = subsolver_verbose,
)

Expand Down Expand Up @@ -525,7 +526,7 @@ end

"""
projected_newton!(solver, x, H, g, Δ, cgtol, ℓ, u, s, Hs; max_cgiter = 50, subsolver_verbose = 0)
projected_newton!(solver, x, H, g, Δ, cgtol, ℓ, u, s, Hs; max_time = Inf, max_cgiter = 50, subsolver_verbose = 0)
Compute an approximate solution `d` for
Expand All @@ -546,8 +547,10 @@ function projected_newton!(
s::AbstractVector{T},
Hs::AbstractVector{T};
max_cgiter::Int = 50,
max_time::Float64 = Inf,
subsolver_verbose = 0,
) where {T <: Real}
start_time, elapsed_time = time(), 0.0
n = length(x)
status = ""

Expand All @@ -559,13 +562,11 @@ function projected_newton!(
mul!(Hs, H, s)

# Projected Newton Step
exit_optimal = false
exit_pcg = false
exit_itmax = false
exit_optimal, exit_pcg, exit_itmax, exit_time = false, false, false, false
iters = 0
x .= x .+ s
project!(x, x, ℓ, u)
while !(exit_optimal || exit_pcg || exit_itmax)
while !(exit_optimal || exit_pcg || exit_itmax || exit_time)
active!(ifix, x, ℓ, u)
if sum(ifix) == n
exit_optimal = true
Expand All @@ -587,6 +588,7 @@ function projected_newton!(
radius = Δ,
rtol = cgtol,
atol = zero(T),
timemax = max_time - elapsed_time,
verbose = subsolver_verbose,
)

Expand Down Expand Up @@ -614,13 +616,21 @@ function projected_newton!(
elseif iters >= max_cgiter
exit_itmax = true
end

elapsed_time = time() - start_time
exit_time = elapsed_time >= max_time
end

status = if exit_optimal
"stationary point found"
elseif exit_pcg
"on trust-region boundary"
elseif exit_itmax
"maximum number of iterations"
elseif exit_time
"time limit exceeded"
else
status # on trust-region
status # unknown
end

return status
Expand Down
22 changes: 16 additions & 6 deletions src/tronls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ function SolverCore.solve!(
u,
As,
max_cgiter = max_cgiter,
max_time = max_time - stats.elapsed_time,
subsolver_verbose = subsolver_verbose,
)

Expand Down Expand Up @@ -551,7 +552,7 @@ end

"""
projected_gauss_newton!(solver, x, A, Fx, Δ, gctol, s, max_cgiter, ℓ, u; max_cgiter = 50, subsolver_verbose = 0)
projected_gauss_newton!(solver, x, A, Fx, Δ, gctol, s, max_cgiter, ℓ, u; max_cgiter = 50, max_time = Inf, subsolver_verbose = 0)
Compute an approximate solution `d` for
Expand All @@ -572,8 +573,10 @@ function projected_gauss_newton!(
u::AbstractVector{T},
As::AbstractVector{T};
max_cgiter::Int = 50,
max_time::Float64 = Inf,
subsolver_verbose = 0,
) where {T <: Real}
start_time, elapsed_time = time(), 0.0
n = length(x)
status = ""

Expand All @@ -589,13 +592,11 @@ function projected_gauss_newton!(
Fxnorm = norm(Fx)

# Projected Newton Step
exit_optimal = false
exit_pcg = false
exit_itmax = false
exit_optimal, exit_pcg, exit_itmax, exit_time = false, false, false, false
iters = 0
x .= x .+ s
project!(x, x, ℓ, u)
while !(exit_optimal || exit_pcg || exit_itmax)
while !(exit_optimal || exit_pcg || exit_itmax || exit_time)
active!(ifix, x, ℓ, u)
if sum(ifix) == n
exit_optimal = true
Expand All @@ -614,6 +615,7 @@ function projected_gauss_newton!(
radius = Δ,
rtol = cgtol,
atol = zero(T),
timemax = max_time - elapsed_time,
verbose = subsolver_verbose,
)

Expand All @@ -637,13 +639,21 @@ function projected_gauss_newton!(
elseif iters >= max_cgiter
exit_itmax = true
end

elapsed_time = time() - start_time
exit_time = elapsed_time >= max_time
end

status = if exit_optimal
"stationary point found"
elseif exit_pcg
"on trust-region boundary"
elseif exit_itmax
"maximum number of iterations"
elseif exit_time
"time limit exceeded"
else
status # on trust-region
status # unknown
end

return status
Expand Down
1 change: 1 addition & 0 deletions src/trunk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ function SolverCore.solve!(
rtol = cgtol,
radius = tr.radius,
itmax = max(2 * n, 50),
timemax = max_time - stats.elapsed_time,

This comment has been minimized.

Copy link
@paraynaud

paraynaud Apr 19, 2024

Member

Krylov integrated the timemax optional argument only at the version 0.9.1
JuliaSmoothOptimizers/Krylov.jl#730
I opened an issue to update accordingly the Project.toml.

verbose = subsolver_verbose,
)
s, cg_stats = subsolver.x, subsolver.stats
Expand Down
1 change: 1 addition & 0 deletions src/trunkls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ function SolverCore.solve!(
rtol = cgtol,
radius = tr.radius,
itmax = max(2 * (n + m), 50),
timemax = max_time - stats.elapsed_time,
verbose = subsolver_verbose,
)
s, cg_stats = subsolver.x, subsolver.stats
Expand Down

0 comments on commit 50125aa

Please sign in to comment.