diff --git a/src/LMTR_alg.jl b/src/LMTR_alg.jl index ae6620f5..c2275ad3 100644 --- a/src/LMTR_alg.jl +++ b/src/LMTR_alg.jl @@ -35,9 +35,6 @@ where F(x) and J(x) are the residual and its Jacobian at x, respectively, ψ(s; ### Return values * `xk`: the final iterate -* `Fobj_hist`: an array with the history of values of the smooth objective -* `Hobj_hist`: an array with the history of values of the nonsmooth objective -* `Complex_hist`: an array with the history of number of inner iterations. """ function LMTR( nls::AbstractNLSModel, @@ -107,12 +104,6 @@ function LMTR( treats_bounds ? shifted(h, xk, max.(-Δk, l_bound - xk), min.(Δk, u_bound - xk), selected) : shifted(h, xk, Δk, χ) - Fobj_hist = zeros(maxIter) - Hobj_hist = zeros(maxIter) - Complex_hist = zeros(Int, maxIter) - Grad_hist = zeros(Int, maxIter) - Resid_hist = zeros(Int, maxIter) - if verbose > 0 #! format: off @info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "√ξ1" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "1/ν" "TR" @@ -141,10 +132,6 @@ function LMTR( while !(optimal || tired) k = k + 1 elapsed_time = time() - start_time - Fobj_hist[k] = fk - Hobj_hist[k] = hk - Grad_hist[k] = nls.counters.neval_jtprod_residual + nls.counters.neval_jprod_residual - Resid_hist[k] = nls.counters.neval_residual # model for first prox-gradient iteration φ1(d) = begin @@ -206,8 +193,6 @@ function LMTR( subsolver_options.ϵa = ϵa_subsolver subsolver_options.Δk = Δk_subsolver - Complex_hist[k] = iter - sNorm = χ(s) xkn .= xk .+ s residual!(nls, xkn, Fkn) @@ -293,11 +278,5 @@ function LMTR( set_residuals!(stats, zero(eltype(xk)), ξ1 ≥ 0 ? sqrt(ξ1) : ξ1) set_iter!(stats, k) set_time!(stats, elapsed_time) - set_solver_specific!(stats, :Fhist, Fobj_hist[1:k]) - set_solver_specific!(stats, :Hhist, Hobj_hist[1:k]) - set_solver_specific!(stats, :NonSmooth, h) - set_solver_specific!(stats, :SubsolverCounter, Complex_hist[1:k]) - set_solver_specific!(stats, :NLSGradHist, Grad_hist[1:k]) - set_solver_specific!(stats, :ResidHist, Resid_hist[1:k]) return stats end diff --git a/src/LM_alg.jl b/src/LM_alg.jl index dc5c29e1..f5f1f8d1 100644 --- a/src/LM_alg.jl +++ b/src/LM_alg.jl @@ -34,9 +34,6 @@ and σ > 0 is a regularization parameter. ### Return values * `xk`: the final iterate -* `Fobj_hist`: an array with the history of values of the smooth objective -* `Hobj_hist`: an array with the history of values of the nonsmooth objective -* `Complex_hist`: an array with the history of number of inner iterations. """ function LM( nls::AbstractNLSModel, @@ -102,11 +99,6 @@ function LM( local ξ1 k = 0 - Fobj_hist = zeros(maxIter) - Hobj_hist = zeros(maxIter) - Complex_hist = zeros(Int, maxIter) - Grad_hist = zeros(Int, maxIter) - Resid_hist = zeros(Int, maxIter) if verbose > 0 #! format: off @@ -134,10 +126,6 @@ function LM( while !(optimal || tired) k = k + 1 elapsed_time = time() - start_time - Fobj_hist[k] = fk - Hobj_hist[k] = hk - Grad_hist[k] = nls.counters.neval_jtprod_residual + nls.counters.neval_jprod_residual - Resid_hist[k] = nls.counters.neval_residual # model for first prox-gradient iteration φ1(d) = begin @@ -199,8 +187,6 @@ function LM( subsolver_options.ν = ν_subsolver subsolver_options.ϵa = ϵa_subsolver - Complex_hist[k] = iter - xkn .= xk .+ s residual!(nls, xkn, Fkn) fkn = dot(Fkn, Fkn) / 2 @@ -245,7 +231,7 @@ function LM( σmax = opnorm(Jk) νInv = (1 + θ) * (σmax^2 + σk) # ‖J'J + σₖ I‖ = ‖J‖² + σₖ - Complex_hist[k] += 1 + # Complex_hist[k] += 1 end if ρk < η1 || ρk == Inf @@ -282,11 +268,5 @@ function LM( set_residuals!(stats, zero(eltype(xk)), ξ1 ≥ 0 ? sqrt(ξ1) : ξ1) set_iter!(stats, k) set_time!(stats, elapsed_time) - set_solver_specific!(stats, :Fhist, Fobj_hist[1:k]) - set_solver_specific!(stats, :Hhist, Hobj_hist[1:k]) - set_solver_specific!(stats, :NonSmooth, h) - set_solver_specific!(stats, :SubsolverCounter, Complex_hist[1:k]) - set_solver_specific!(stats, :NLSGradHist, Grad_hist[1:k]) - set_solver_specific!(stats, :ResidHist, Resid_hist[1:k]) return stats end diff --git a/src/R2_alg.jl b/src/R2_alg.jl index 88481fc9..6bcd6638 100644 --- a/src/R2_alg.jl +++ b/src/R2_alg.jl @@ -11,9 +11,6 @@ mutable struct R2Solver{R, S <: AbstractVector{R}} <: AbstractOptimizationSolver u_bound::S l_bound_m_x::S u_bound_m_x::S - Fobj_hist::Vector{R} - Hobj_hist::Vector{R} - Complex_hist::Vector{Int} end function R2Solver( @@ -36,24 +33,7 @@ function R2Solver( l_bound_m_x = similar(xk, 0) u_bound_m_x = similar(xk, 0) end - Fobj_hist = zeros(R, maxIter) - Hobj_hist = zeros(R, maxIter) - Complex_hist = zeros(Int, maxIter) - return R2Solver( - xk, - ∇fk, - mν∇fk, - xkn, - s, - has_bnds, - l_bound, - u_bound, - l_bound_m_x, - u_bound_m_x, - Fobj_hist, - Hobj_hist, - Complex_hist, - ) + return R2Solver(xk, ∇fk, mν∇fk, xkn, s, has_bnds, l_bound, u_bound, l_bound_m_x, u_bound_m_x) end """ @@ -96,9 +76,6 @@ In the second form, instead of `nlp`, the user may pass in ### Return values * `xk`: the final iterate -* `Fobj_hist`: an array with the history of values of the smooth objective -* `Hobj_hist`: an array with the history of values of the nonsmooth objective -* `Complex_hist`: an array with the history of number of inner iterations. """ function R2(nlp::AbstractNLPModel, args...; kwargs...) kwargs_dict = Dict(kwargs...) @@ -120,10 +97,6 @@ function R2(nlp::AbstractNLPModel, args...; kwargs...) set_residuals!(stats, zero(eltype(xk)), ξ) set_iter!(stats, k) set_time!(stats, outdict[:elapsed_time]) - set_solver_specific!(stats, :Fhist, outdict[:Fhist]) - set_solver_specific!(stats, :Hhist, outdict[:Hhist]) - set_solver_specific!(stats, :NonSmooth, outdict[:NonSmooth]) - set_solver_specific!(stats, :SubsolverCounter, outdict[:Chist]) return stats end @@ -142,17 +115,7 @@ function R2( solver = R2Solver(x0, options, similar(x0, 0), similar(x0, 0)) k, status, fk, hk, ξ = R2!(solver, f, ∇f!, h, options, x0; selected = selected) elapsed_time = time() - start_time - outdict = Dict( - :Fhist => solver.Fobj_hist[1:k], - :Hhist => solver.Hobj_hist[1:k], - :Chist => solver.Complex_hist[1:k], - :NonSmooth => h, - :status => status, - :fk => fk, - :hk => hk, - :ξ => ξ, - :elapsed_time => elapsed_time, - ) + outdict = Dict(:status => status, :fk => fk, :hk => hk, :ξ => ξ, :elapsed_time => elapsed_time) return solver.xk, k, outdict end @@ -172,17 +135,7 @@ function R2( solver = R2Solver(x0, options, l_bound, u_bound) k, status, fk, hk, ξ = R2!(solver, f, ∇f!, h, options, x0; selected = selected) elapsed_time = time() - start_time - outdict = Dict( - :Fhist => solver.Fobj_hist[1:k], - :Hhist => solver.Hobj_hist[1:k], - :Chist => solver.Complex_hist[1:k], - :NonSmooth => h, - :status => status, - :fk => fk, - :hk => hk, - :ξ => ξ, - :elapsed_time => elapsed_time, - ) + outdict = Dict(:status => status, :fk => fk, :hk => hk, :ξ => ξ, :elapsed_time => elapsed_time) return solver.xk, k, outdict end @@ -223,9 +176,6 @@ function R2!( l_bound_m_x = solver.l_bound_m_x u_bound_m_x = solver.u_bound_m_x end - Fobj_hist = solver.Fobj_hist - Hobj_hist = solver.Hobj_hist - Complex_hist = solver.Complex_hist if verbose == 0 ptf = Inf @@ -278,15 +228,12 @@ function R2!( while !(optimal || tired) k = k + 1 elapsed_time = time() - start_time - Fobj_hist[k] = fk - Hobj_hist[k] = hk # define model φk(d) = dot(∇fk, d) mk(d)::R = φk(d) + ψ(d)::R prox!(s, ψ, mν∇fk, ν) - Complex_hist[k] += 1 mks = mk(s) ξ = hk - mks + max(1, abs(hk)) * 10 * eps() sqrt_ξ_νInv = ξ ≥ 0 ? sqrt(ξ / ν) : sqrt(-ξ / ν) @@ -294,7 +241,7 @@ function R2!( if ξ ≥ 0 && k == 1 ϵ += ϵr * sqrt_ξ_νInv # make stopping test absolute and relative end - + if (ξ < 0 && sqrt_ξ_νInv ≤ neg_tol) || (ξ ≥ 0 && sqrt_ξ_νInv ≤ ϵ) optimal = true continue diff --git a/src/TRDH_alg.jl b/src/TRDH_alg.jl index 8fef5479..0642a804 100644 --- a/src/TRDH_alg.jl +++ b/src/TRDH_alg.jl @@ -43,9 +43,6 @@ In the second form, instead of `nlp`, the user may pass in ### Return values * `xk`: the final iterate -* `Fobj_hist`: an array with the history of values of the smooth objective -* `Hobj_hist`: an array with the history of values of the nonsmooth objective -* `Complex_hist`: an array with the history of number of inner iterations. """ function TRDH( nlp::AbstractNLPModel{R}, @@ -75,10 +72,6 @@ function TRDH( set_residuals!(stats, zero(eltype(xk)), ξ) set_iter!(stats, k) set_time!(stats, outdict[:elapsed_time]) - set_solver_specific!(stats, :Fhist, outdict[:Fhist]) - set_solver_specific!(stats, :Hhist, outdict[:Hhist]) - set_solver_specific!(stats, :NonSmooth, outdict[:NonSmooth]) - set_solver_specific!(stats, :SubsolverCounter, outdict[:Chist]) return stats end @@ -182,9 +175,6 @@ function TRDH( end end - Fobj_hist = zeros(maxIter) - Hobj_hist = zeros(maxIter) - Complex_hist = zeros(Int, maxIter) if verbose > 0 #! format: off if reduce_TR @@ -217,8 +207,6 @@ function TRDH( while !(optimal || tired) k = k + 1 elapsed_time = time() - start_time - Fobj_hist[k] = fk - Hobj_hist[k] = hk # model for prox-gradient step to update Δk if ||s|| is too small and ξ1 φ1(d) = ∇fk' * d @@ -226,7 +214,6 @@ function TRDH( if reduce_TR prox!(s, ψ, mν∇fk, ν) - Complex_hist[k] += 1 ξ1 = hk - mk1(s) + max(1, abs(hk)) * 10 * eps() sqrt_ξ_νInv = ξ1 ≥ 0 ? sqrt(ξ1 / ν) : sqrt(-ξ1 / ν) @@ -252,12 +239,11 @@ function TRDH( set_radius!(ψ, Δ_effective) end - # model with diagonal hessian + # model with diagonal hessian φ(d) = ∇fk' * d + (d' * (Dk.d .* d)) / 2 mk(d) = φ(d) + ψ(d) iprox!(s, ψ, ∇fk, Dk) - Complex_hist[k] += 1 sNorm = χ(s) xkn .= xk .+ s @@ -361,17 +347,8 @@ function TRDH( else :exception end - outdict = Dict( - :Fhist => Fobj_hist[1:k], - :Hhist => Hobj_hist[1:k], - :Chist => Complex_hist[1:k], - :NonSmooth => h, - :status => status, - :fk => fk, - :hk => hk, - :ξ => sqrt_ξ_νInv, - :elapsed_time => elapsed_time, - ) + outdict = + Dict(:status => status, :fk => fk, :hk => hk, :ξ => sqrt_ξ_νInv, :elapsed_time => elapsed_time) return xk, k, outdict end diff --git a/src/TR_alg.jl b/src/TR_alg.jl index e889cb4b..00778e63 100644 --- a/src/TR_alg.jl +++ b/src/TR_alg.jl @@ -39,10 +39,7 @@ The Hessian is accessed as an abstract operator and need not be the exact Hessia ### Return values -* `xk`: the final iterate -* `Fobj_hist`: an array with the history of values of the smooth objective -* `Hobj_hist`: an array with the history of values of the nonsmooth objective -* `Complex_hist`: an array with the history of number of inner iterations. +* `xk`: the final iterate. """ function TR( f::AbstractNLPModel, @@ -112,9 +109,6 @@ function TR( shifted(h, xk, max.(-Δk, l_bound - xk), min.(Δk, u_bound - xk), selected) : shifted(h, xk, Δk, χ) - Fobj_hist = zeros(maxIter) - Hobj_hist = zeros(maxIter) - Complex_hist = zeros(Int, maxIter) if verbose > 0 #! format: off @info @sprintf "%6s %8s %8s %8s %7s %7s %8s %7s %7s %7s %7s %1s" "outer" "inner" "f(x)" "h(x)" "√(ξ1/ν)" "√ξ" "ρ" "Δ" "‖x‖" "‖s‖" "‖Bₖ‖" "TR" @@ -142,8 +136,6 @@ function TR( while !(optimal || tired) k = k + 1 elapsed_time = time() - start_time - Fobj_hist[k] = fk - Hobj_hist[k] = hk # model for first prox-gradient step and ξ1 φ1(d) = ∇fk' * d @@ -195,8 +187,6 @@ function TR( subsolver_options.ϵa = ϵa_subsolver subsolver_options.Δk = Δk_subsolver - Complex_hist[k] = sum(outdict[:Chist]) - sNorm = χ(s) xkn .= xk .+ s fkn = obj(f, xkn) @@ -282,9 +272,5 @@ function TR( set_residuals!(stats, zero(eltype(xk)), sqrt_ξ1_νInv) set_iter!(stats, k) set_time!(stats, elapsed_time) - set_solver_specific!(stats, :Fhist, Fobj_hist[1:k]) - set_solver_specific!(stats, :Hhist, Hobj_hist[1:k]) - set_solver_specific!(stats, :NonSmooth, h) - set_solver_specific!(stats, :SubsolverCounter, Complex_hist[1:k]) return stats end diff --git a/test/runtests.jl b/test/runtests.jl index 70892408..ef2f5ad3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -26,14 +26,7 @@ for (mod, mod_name) ∈ ((x -> x, "exact"), (LSR1Model, "lsr1"), (LBFGSModel, "l out = solver(mod(bpdn), h, args..., options, x0 = x0) @test typeof(out.solution) == typeof(bpdn.meta.x0) @test length(out.solution) == bpdn.meta.nvar - @test typeof(out.solver_specific[:Fhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:Hhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(out.dual_feas) == eltype(out.solution) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:Hhist]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:SubsolverCounter]) - @test obj(bpdn, out.solution) == out.solver_specific[:Fhist][end] - @test h(out.solution) == out.solver_specific[:Hhist][end] @test out.status == :first_order end end @@ -50,15 +43,7 @@ for (mod, mod_name) ∈ ((LSR1Model, "lsr1"), (LBFGSModel, "lbfgs")) TR_out = TR(mod(bpdn), h, NormL2(1.0), options, x0 = x0) @test typeof(TR_out.solution) == typeof(bpdn.meta.x0) @test length(TR_out.solution) == bpdn.meta.nvar - @test typeof(TR_out.solver_specific[:Fhist]) == typeof(TR_out.solution) - @test typeof(TR_out.solver_specific[:Hhist]) == typeof(TR_out.solution) - @test typeof(TR_out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(TR_out.dual_feas) == eltype(TR_out.solution) - @test length(TR_out.solver_specific[:Fhist]) == length(TR_out.solver_specific[:Hhist]) - @test length(TR_out.solver_specific[:Fhist]) == - length(TR_out.solver_specific[:SubsolverCounter]) - @test obj(bpdn, TR_out.solution) == TR_out.solver_specific[:Fhist][end] - @test h(TR_out.solution) == TR_out.solver_specific[:Hhist][end] @test TR_out.status == :first_order end end @@ -77,17 +62,7 @@ for (h, h_name) ∈ ((NormL0(λ), "l0"), (NormL1(λ), "l1"), (IndBallL0(10 * com out = solver(bpdn_nls, h, args..., options, x0 = x0) @test typeof(out.solution) == typeof(bpdn_nls.meta.x0) @test length(out.solution) == bpdn_nls.meta.nvar - @test typeof(out.solver_specific[:Fhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:Hhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(out.dual_feas) == eltype(out.solution) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:Hhist]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:SubsolverCounter]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:NLSGradHist]) - @test out.solver_specific[:NLSGradHist][end] == - bpdn_nls.counters.neval_jprod_residual + bpdn_nls.counters.neval_jtprod_residual - 1 - @test obj(bpdn_nls, out.solution) == out.solver_specific[:Fhist][end] - @test h(out.solution) == out.solver_specific[:Hhist][end] @test out.status == :first_order end end @@ -102,18 +77,7 @@ for (h, h_name) ∈ ((NormL1(λ), "l1"),) LMTR_out = LMTR(bpdn_nls, h, NormL2(1.0), options, x0 = x0) @test typeof(LMTR_out.solution) == typeof(bpdn_nls.meta.x0) @test length(LMTR_out.solution) == bpdn_nls.meta.nvar - @test typeof(LMTR_out.solver_specific[:Fhist]) == typeof(LMTR_out.solution) - @test typeof(LMTR_out.solver_specific[:Hhist]) == typeof(LMTR_out.solution) - @test typeof(LMTR_out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(LMTR_out.dual_feas) == eltype(LMTR_out.solution) - @test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:Hhist]) - @test length(LMTR_out.solver_specific[:Fhist]) == - length(LMTR_out.solver_specific[:SubsolverCounter]) - @test length(LMTR_out.solver_specific[:Fhist]) == length(LMTR_out.solver_specific[:NLSGradHist]) - @test LMTR_out.solver_specific[:NLSGradHist][end] == - bpdn_nls.counters.neval_jprod_residual + bpdn_nls.counters.neval_jtprod_residual - 1 - @test obj(bpdn_nls, LMTR_out.solution) == LMTR_out.solver_specific[:Fhist][end] - @test h(LMTR_out.solution) == LMTR_out.solver_specific[:Hhist][end] @test LMTR_out.status == :first_order end end diff --git a/test/test_bounds.jl b/test/test_bounds.jl index fa21a0bf..eaec58d9 100644 --- a/test/test_bounds.jl +++ b/test/test_bounds.jl @@ -15,14 +15,7 @@ for (mod, mod_name) ∈ ((x -> x, "exact"), (LSR1Model, "lsr1"), (LBFGSModel, "l out = solver(mod(bpdn2), h, args..., options; x0 = x0) @test typeof(out.solution) == typeof(bpdn2.meta.x0) @test length(out.solution) == bpdn2.meta.nvar - @test typeof(out.solver_specific[:Fhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:Hhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(out.dual_feas) == eltype(out.solution) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:Hhist]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:SubsolverCounter]) - @test obj(bpdn2, out.solution) == out.solver_specific[:Fhist][end] - @test h(out.solution) == out.solver_specific[:Hhist][end] @test out.status == :first_order end end @@ -40,14 +33,7 @@ for (h, h_name) ∈ ((NormL0(λ), "l0"), (NormL1(λ), "l1")) out = solver(bpdn_nls2, h, args..., options, x0 = x0) @test typeof(out.solution) == typeof(bpdn_nls2.meta.x0) @test length(out.solution) == bpdn_nls2.meta.nvar - @test typeof(out.solver_specific[:Fhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:Hhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(out.dual_feas) == eltype(out.solution) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:Hhist]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:SubsolverCounter]) - @test obj(bpdn_nls2, out.solution) == out.solver_specific[:Fhist][end] - @test h(out.solution) == out.solver_specific[:Hhist][end] @test out.status == :first_order end @testset "bpdn-with-bounds-ls-$(solver_name)-$(h_name)-TRDH" begin @@ -65,14 +51,7 @@ for (h, h_name) ∈ ((NormL0(λ), "l0"), (NormL1(λ), "l1")) ) @test typeof(out.solution) == typeof(bpdn_nls2.meta.x0) @test length(out.solution) == bpdn_nls2.meta.nvar - @test typeof(out.solver_specific[:Fhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:Hhist]) == typeof(out.solution) - @test typeof(out.solver_specific[:SubsolverCounter]) == Array{Int, 1} @test typeof(out.dual_feas) == eltype(out.solution) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:Hhist]) - @test length(out.solver_specific[:Fhist]) == length(out.solver_specific[:SubsolverCounter]) - @test obj(bpdn_nls2, out.solution) == out.solver_specific[:Fhist][end] - @test h(out.solution) == out.solver_specific[:Hhist][end] @test out.status == :first_order end end