Skip to content

Commit 337245a

Browse files
add option to change subsolver in AL (#310)
1 parent 3afbc9b commit 337245a

2 files changed

Lines changed: 16 additions & 7 deletions

File tree

src/AL_alg.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ where y is an estimate of the Lagrange multiplier vector for the constraints lco
8181
8282
For advanced usage, first define a solver "ALSolver" to preallocate the memory used in the algorithm, and then call `solve!`:
8383
84-
solver = ALSolver(reg_nlp)
84+
solver = ALSolver(reg_nlp; subsolver = R2Solver)
8585
solve!(solver, reg_nlp)
8686
8787
stats = GenericExecutionStats(reg_nlp.model)
@@ -108,7 +108,7 @@ If adopted, the Hessian is accessed as an abstract operator and need not be the
108108
- `max_iter::Int = 10000`: maximum number of iterations;
109109
- `max_time::Float64 = 30.0`: maximum time limit in seconds;
110110
- `max_eval::Int = -1`: maximum number of evaluation of the objective function (negative number means unlimited);
111-
- `subsolver::AbstractOptimizationSolver = has_bounds(nlp) ? TR : R2`: the procedure used to compute a step (e.g. `PG`, `R2`, `TR` or `TRDH`);
111+
- `subsolver::AbstractOptimizationSolver = R2Solver`: the procedure used to compute a step (e.g. `R2Solver`, `R2NSolver`, `R2DHSolver`, `TRSolver` or `TRDHSolver`);
112112
- `subsolver_logger::AbstractLogger`: a logger to pass to the subproblem solver;
113113
- `init_penalty::T = T(10)`: initial penalty parameter;
114114
- `factor_penalty_up::T = T(2)`: multiplicative factor to increase the penalty parameter;
@@ -148,7 +148,7 @@ mutable struct ALSolver{T, V, M, Pb, ST} <: AbstractOptimizationSolver
148148
sub_stats::GenericExecutionStats{T, V, V, T}
149149
end
150150

151-
function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; kwargs...) where {T, V}
151+
function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; subsolver = R2Solver, kwargs...) where {T, V}
152152
nlp = reg_nlp.model
153153
nvar, ncon = nlp.meta.nvar, nlp.meta.ncon
154154
x = V(undef, nvar)
@@ -157,7 +157,7 @@ function ALSolver(reg_nlp::AbstractRegularizedNLPModel{T, V}; kwargs...) where {
157157
has_bnds = has_bounds(nlp)
158158
sub_model = AugLagModel(nlp, V(undef, ncon), T(0), x, T(0), cx)
159159
sub_problem = RegularizedNLPModel(sub_model, reg_nlp.h, reg_nlp.selected)
160-
sub_solver = R2Solver(reg_nlp; kwargs...)
160+
sub_solver = subsolver(sub_problem; kwargs...)
161161
sub_stats = RegularizedExecutionStats(sub_problem)
162162
M = typeof(nlp)
163163
ST = typeof(sub_solver)
@@ -182,8 +182,10 @@ end
182182
"AL(::Val{:equ}, ...) should only be called for equality-constrained problems with bounded variables. Use AL(...)",
183183
)
184184
end
185-
solver = ALSolver(reg_nlp)
186-
solve!(solver, reg_nlp; kwargs...)
185+
kwargs_dict = Dict(kwargs...)
186+
subsolver = pop!(kwargs_dict, :subsolver, R2Solver)
187+
solver = ALSolver(reg_nlp, subsolver = subsolver)
188+
solve!(solver, reg_nlp; kwargs_dict...)
187189
end
188190

189191
function SolverCore.solve!(

test/test_AL.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@ problem_list = [:hs8]
55
for problem in problem_list
66
nlp = eval(problem)(backend = :optimized)
77
for h in (NormL1(1.0),)
8-
stats = AL(nlp, h, atol = 1e-3, verbose = 1)
8+
stats = AL(nlp, h, subsolver = R2Solver, atol = 1e-3, verbose = 1, subsolver_max_iter = 1000)
9+
@test stats.status == :first_order
10+
@test stats.primal_feas <= 1e-2
11+
@test stats.dual_feas <= 1e-2
12+
@test length(stats.solution) == nlp.meta.nvar
13+
@test typeof(stats.solution) == typeof(nlp.meta.x0)
14+
15+
stats = AL(LBFGSModel(nlp), h, subsolver = R2NSolver, atol = 1e-3, verbose = 1, subsolver_max_iter = 1000)
916
@test stats.status == :first_order
1017
@test stats.primal_feas <= 1e-2
1118
@test stats.dual_feas <= 1e-2

0 commit comments

Comments
 (0)