Skip to content

Commit cc253ef

Browse files
authored
Add scripts to reproduce paper results (#96)
1 parent f23632b commit cc253ef

7 files changed

Lines changed: 459 additions & 0 deletions
237 KB
Binary file not shown.

paper/Project.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[deps]
2+
CUTEst = "1b53aba6-35b6-5f92-a507-53c67d53f819"
3+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
4+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
5+
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
6+
NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6"
7+
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
8+
SolverBenchmark = "581a75fa-a23a-52d0-a590-d6201de2218a"
9+
10+
[compat]
11+
DataFrames = "1.3"

paper/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Scalable Adaptive Cubic Regularization Methods
2+
3+
This folder contains a set of scripts to reproduce the results in
4+
5+
> Dussault, J.-P., Migot, T. & Orban, D. (2023).
6+
> Scalable adaptive cubic regularization methods.
7+
> Mathematical Programming.
8+
> [10.1007/s10107-023-02007-6](https://doi.org/10.1007/s10107-023-02007-6)
9+
10+
There are three scripts:
11+
12+
- `make_problem_cutest_list.jl`: generate a data file with the list of problems solved;
13+
- `benchmark_arctr.jl`: run the benchmark comparing ST_TR and ARCqK, and store the result in a JLD2 file;
14+
- `figure_solvers.jl`: generates a set of plots.
15+
16+
The result file `2022-05-16_ST_TROp_ARCqKOpShift05_cutest_277_1000000.jld2` can be accessed without reproducing the benchmark.

paper/benchmark_arctr.jl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Pkg;
2+
Pkg.activate("");
3+
using AdaptiveRegularization, CUTEst, Dates, NLPModels, SolverBenchmark
4+
5+
nmax = 1000000
6+
problems = readlines("paper/list_problems_$nmax.dat")
7+
cutest_problems = (CUTEstModel(p) for p in problems)
8+
9+
unsolved_problems = [
10+
"CYCLOOCFLS",
11+
"SBRYBND",
12+
"BA-L49LS",
13+
"NONMSQRT",
14+
"BA-L73LS",
15+
"INDEF",
16+
"BA-L21LS",
17+
"FLETCBV3",
18+
"FLETCHBV",
19+
"BA-L16LS",
20+
"BA-L52LS",
21+
]
22+
23+
max_time = 3600.0
24+
max_ev = typemax(Int)
25+
max_iter = typemax(Int)
26+
atol = 1e-5
27+
rtol = 1e-6
28+
29+
eL = 10.0
30+
eU = 20.0
31+
ψ = 10 ^ (1 // 2)
32+
shifts = 10.0 .^ (collect(-eL:0.5:eU))
33+
34+
ζ = 0.5
35+
36+
γ₁ = 0.1
37+
γ₂ = 5
38+
η₁ = 0.1
39+
η₂ = 0.75
40+
TR = TrustRegion(
41+
10;
42+
acceptance_threshold = η₁,
43+
increase_threshold = η₂,
44+
increase_factor = γ₂,
45+
decrease_factor = γ₁,
46+
)
47+
48+
solvers = Dict(
49+
:ARCqKOp =>
50+
nlp -> ARCqKOp(
51+
nlp,
52+
TR = TR,
53+
shifts = shifts,
54+
verbose = false,
55+
atol = atol,
56+
rtol = rtol,
57+
max_time = max_time,
58+
max_iter = max_iter,
59+
ζ = ζ,
60+
),
61+
:ST_TROp =>
62+
nlp -> ST_TROp(
63+
nlp,
64+
TR = TR,
65+
verbose = false,
66+
atol = atol,
67+
rtol = rtol,
68+
max_time = max_time,
69+
max_iter = max_iter,
70+
ζ = ζ,
71+
),
72+
)
73+
74+
# Skipping unsolved problems to solve time :-)
75+
stats = bmark_solvers(solvers, cutest_problems, skipif = prob -> (prob.meta.name in unsolved_problems))
76+
77+
using JLD2
78+
@save "paper/$(today())_$(prod(String.(keys(solvers)) .* "_"))cutest_$(string(length(problems)))_$(nmax).jld2" stats

paper/figures_solvers.jl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using Pkg;
2+
Pkg.activate("paper");
3+
using JLD2, Plots, SolverBenchmark, DataFrames
4+
5+
name = "2022-05-16_ST_TROp_ARCqKOpShift05_cutest_277_1000000"
6+
@load "paper/$name.jld2" stats
7+
8+
solved(df) = (df.status .== :first_order) .| (df.status .== :unbounded)
9+
10+
for solver in keys(stats)
11+
open("paper/$(name)_result_$(solver).dat", "w") do io
12+
print(
13+
io,
14+
stats[solver][
15+
!,
16+
[
17+
:name,
18+
:nvar,
19+
# :ncon,
20+
:status,
21+
:objective,
22+
:elapsed_time,
23+
:iter,
24+
# :primal_feas,
25+
:dual_feas,
26+
:neval_obj,
27+
:neval_grad,
28+
:neval_hprod,
29+
:neval_hess,
30+
],
31+
],
32+
)
33+
end
34+
end
35+
36+
nmins = [0, 100, 1000, 10000]
37+
for nmin in nmins
38+
# Same figure with minimum number of variables
39+
stats2 = copy(stats)
40+
for solver in keys(stats)
41+
stats2[solver] = stats[solver][stats[solver].nvar.>=nmin, :]
42+
end
43+
44+
nb_problems = length(stats2[first(keys(stats))][!, :name])
45+
46+
# Figures comparing two results:
47+
costs_all = [
48+
df -> .!solved(df) * Inf + df.elapsed_time,
49+
df -> .!solved(df) * Inf + df.neval_obj,
50+
df -> .!solved(df) * Inf + df.neval_grad,
51+
df -> .!solved(df) * Inf + df.neval_hprod,
52+
]
53+
costnames_all = [
54+
"elapsed time",
55+
"objective evals",
56+
"gradient evals",
57+
"hessian-vector products",
58+
]
59+
p = profile_solvers(stats2, costs_all, costnames_all, height = 400, width = 400, margin=5Plots.mm)
60+
png(p, "paper/$(name)_all($(nb_problems))_min_$(nmin)")
61+
end

0 commit comments

Comments
 (0)