diff --git a/src/tron.jl b/src/tron.jl index 52cf300b..7dd9f546 100644 --- a/src/tron.jl +++ b/src/tron.jl @@ -302,6 +302,7 @@ function SolverCore.solve!( s, Hs, max_cgiter = max_cgiter, + max_time = max_time - stats.elapsed_time, subsolver_verbose = subsolver_verbose, ) @@ -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 @@ -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 = "" @@ -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 @@ -587,6 +588,7 @@ function projected_newton!( radius = Δ, rtol = cgtol, atol = zero(T), + timemax = max_time - elapsed_time, verbose = subsolver_verbose, ) @@ -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 diff --git a/src/tronls.jl b/src/tronls.jl index 60f9e98b..622d202e 100644 --- a/src/tronls.jl +++ b/src/tronls.jl @@ -327,6 +327,7 @@ function SolverCore.solve!( u, As, max_cgiter = max_cgiter, + max_time = max_time - stats.elapsed_time, subsolver_verbose = subsolver_verbose, ) @@ -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 @@ -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 = "" @@ -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 @@ -614,6 +615,7 @@ function projected_gauss_newton!( radius = Δ, rtol = cgtol, atol = zero(T), + timemax = max_time - elapsed_time, verbose = subsolver_verbose, ) @@ -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 diff --git a/src/trunk.jl b/src/trunk.jl index f1e4e268..cbc321b5 100644 --- a/src/trunk.jl +++ b/src/trunk.jl @@ -235,6 +235,7 @@ function SolverCore.solve!( rtol = cgtol, radius = tr.radius, itmax = max(2 * n, 50), + timemax = max_time - stats.elapsed_time, verbose = subsolver_verbose, ) s, cg_stats = subsolver.x, subsolver.stats diff --git a/src/trunkls.jl b/src/trunkls.jl index dace877a..79ef752c 100644 --- a/src/trunkls.jl +++ b/src/trunkls.jl @@ -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