Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/AL_alg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ where y is an estimate of the Lagrange multiplier vector for the constraints lco

For advanced usage, first define a solver "ALSolver" to preallocate the memory used in the algorithm, and then call `solve!`:

solver = ALSolver(reg_nlp)
solver = ALSolver(reg_nlp; subsolver = R2Solver)
solve!(solver, reg_nlp)

stats = GenericExecutionStats(reg_nlp.model)
Expand All @@ -108,7 +108,7 @@ If adopted, the Hessian is accessed as an abstract operator and need not be the
- `max_iter::Int = 10000`: maximum number of iterations;
- `max_time::Float64 = 30.0`: maximum time limit in seconds;
- `max_eval::Int = -1`: maximum number of evaluation of the objective function (negative number means unlimited);
- `subsolver::AbstractOptimizationSolver = has_bounds(nlp) ? TR : R2`: the procedure used to compute a step (e.g. `PG`, `R2`, `TR` or `TRDH`);
- `subsolver::AbstractOptimizationSolver = R2Solver`: the procedure used to compute a step (e.g. `R2Solver`, `R2NSolver`, `R2DHSolver`, `TRSolver` or `TRDHSolver`);
- `subsolver_logger::AbstractLogger`: a logger to pass to the subproblem solver;
Comment thread
dpo marked this conversation as resolved.
- `init_penalty::T = T(10)`: initial penalty parameter;
- `factor_penalty_up::T = T(2)`: multiplicative factor to increase the penalty parameter;
Expand Down Expand Up @@ -148,7 +148,7 @@ mutable struct ALSolver{T, V, M, Pb, ST} <: AbstractOptimizationSolver
sub_stats::GenericExecutionStats{T, V, V, T}
end

function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; kwargs...) where {T, V}
function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; subsolver = R2Solver, kwargs...) where {T, V}
nlp = reg_nlp.model
nvar, ncon = nlp.meta.nvar, nlp.meta.ncon
x = V(undef, nvar)
Expand All @@ -157,7 +157,7 @@ function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; kwargs...) where {
has_bnds = has_bounds(nlp)
sub_model = AugLagModel(nlp, V(undef, ncon), T(0), x, T(0), cx)
sub_problem = RegularizedNLPModel(sub_model, reg_nlp.h, reg_nlp.selected)
sub_solver = R2Solver(reg_nlp; kwargs...)
sub_solver = subsolver(sub_problem; kwargs...)
sub_stats = RegularizedExecutionStats(sub_problem)
Comment thread
MaxenceGollier marked this conversation as resolved.
M = typeof(nlp)
ST = typeof(sub_solver)
Expand All @@ -182,8 +182,10 @@ end
"AL(::Val{:equ}, ...) should only be called for equality-constrained problems with bounded variables. Use AL(...)",
)
end
solver = ALSolver(reg_nlp)
solve!(solver, reg_nlp; kwargs...)
kwargs_dict = Dict(kwargs...)
subsolver = pop!(kwargs_dict, :subsolver, R2Solver)
solver = ALSolver(reg_nlp, subsolver = subsolver)
solve!(solver, reg_nlp; kwargs_dict...)
end

function SolverCore.solve!(
Expand Down
9 changes: 8 additions & 1 deletion test/test_AL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ problem_list = [:hs8]
for problem in problem_list
nlp = eval(problem)(backend = :optimized)
for h in (NormL1(1.0),)
stats = AL(nlp, h, atol = 1e-3, verbose = 1)
stats = AL(nlp, h, subsolver = R2Solver, atol = 1e-3, verbose = 1, subsolver_max_iter = 1000)
@test stats.status == :first_order
@test stats.primal_feas <= 1e-2
@test stats.dual_feas <= 1e-2
@test length(stats.solution) == nlp.meta.nvar
@test typeof(stats.solution) == typeof(nlp.meta.x0)

stats = AL(LBFGSModel(nlp), h, subsolver = R2NSolver, atol = 1e-3, verbose = 1, subsolver_max_iter = 1000)
@test stats.status == :first_order
@test stats.primal_feas <= 1e-2
@test stats.dual_feas <= 1e-2
Expand Down
Loading