Skip to content

Commit 738e71c

Browse files
SebastianM-CClaude
andcommitted
test(OptimizationIpopt): update tests for the new API
Co-authored-by: Claude <claude@anthropic.com>
1 parent ea28cc4 commit 738e71c

File tree

4 files changed

+119
-32
lines changed

4 files changed

+119
-32
lines changed

lib/OptimizationIpopt/test/additional_tests.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ end
220220
@testset "BFGS approximation" begin
221221
optfunc = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
222222
prob = OptimizationProblem(optfunc, x0, p)
223-
sol = solve(prob, IpoptOptimizer();
224-
hessian_approximation = "limited-memory")
223+
sol = solve(prob, IpoptOptimizer(
224+
hessian_approximation = "limited-memory"))
225225

226226
@test SciMLBase.successful_retcode(sol)
227227
@test sol.u [1.0, 1.0] atol=1e-4
@@ -230,9 +230,9 @@ end
230230
@testset "SR1 approximation" begin
231231
optfunc = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
232232
prob = OptimizationProblem(optfunc, x0, p)
233-
sol = solve(prob, IpoptOptimizer();
233+
sol = solve(prob, IpoptOptimizer(
234234
hessian_approximation = "limited-memory",
235-
limited_memory_update_type = "sr1")
235+
limited_memory_update_type = "sr1"))
236236

237237
@test SciMLBase.successful_retcode(sol)
238238
@test sol.u [1.0, 1.0] atol=1e-4

lib/OptimizationIpopt/test/advanced_features.jl

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ using SparseArrays
2121
prob = OptimizationProblem(optfunc, x0, p)
2222

2323
# Test with tight tolerances
24-
sol = solve(prob, IpoptOptimizer();
25-
reltol = 1e-10,
24+
sol = solve(prob, IpoptOptimizer(
2625
acceptable_tol = 1e-8,
27-
acceptable_iter = 5)
26+
acceptable_iter = 5);
27+
reltol = 1e-10)
2828

2929
@test SciMLBase.successful_retcode(sol)
3030
@test sol.u [1.0, 1.0] atol=1e-8
@@ -46,8 +46,8 @@ using SparseArrays
4646
lcons = [0.0, 0.0],
4747
ucons = [0.0, 0.0])
4848

49-
sol = solve(prob, IpoptOptimizer();
50-
constr_viol_tol = 1e-8)
49+
sol = solve(prob, IpoptOptimizer(
50+
constr_viol_tol = 1e-8))
5151

5252
@test SciMLBase.successful_retcode(sol)
5353
@test sol.u[1] + sol.u[2] 2.0 atol=1e-7
@@ -64,9 +64,11 @@ using SparseArrays
6464
prob = OptimizationProblem(optfunc, [0.1, 0.1], nothing)
6565

6666
# Run with derivative test level 1 (first derivatives only)
67-
sol = solve(prob, IpoptOptimizer();
68-
derivative_test = "first-order",
69-
derivative_test_tol = 1e-4)
67+
sol = solve(prob, IpoptOptimizer(
68+
additional_options = Dict(
69+
"derivative_test" => "first-order",
70+
"derivative_test_tol" => 1e-4
71+
)))
7072

7173
@test SciMLBase.successful_retcode(sol)
7274
end
@@ -92,8 +94,8 @@ using SparseArrays
9294
prob = OptimizationProblem(optfunc, x0, p)
9395

9496
# Test with different linear solver strategies
95-
sol = solve(prob, IpoptOptimizer();
96-
linear_solver = "mumps") # or "ma27", "ma57", etc. if available
97+
sol = solve(prob, IpoptOptimizer(
98+
linear_solver = "mumps")) # or "ma27", "ma57", etc. if available
9799

98100
@test SciMLBase.successful_retcode(sol)
99101
# Check that odd indices are close to 1
@@ -117,8 +119,8 @@ using SparseArrays
117119
ucons = [0.0])
118120

119121
# Solve with automatic scaling
120-
sol = solve(prob, IpoptOptimizer();
121-
nlp_scaling_method = "gradient-based")
122+
sol = solve(prob, IpoptOptimizer(
123+
nlp_scaling_method = "gradient-based"))
122124

123125
@test SciMLBase.successful_retcode(sol)
124126
# Check constraint satisfaction
@@ -145,8 +147,10 @@ using SparseArrays
145147
lcons = [0.0, 0.0],
146148
ucons = [0.0, 0.0])
147149

148-
sol = solve(prob, IpoptOptimizer();
149-
required_infeasibility_reduction = 0.9)
150+
sol = solve(prob, IpoptOptimizer(
151+
additional_options = Dict(
152+
"required_infeasibility_reduction" => 0.9
153+
)))
150154

151155
if SciMLBase.successful_retcode(sol)
152156
# Check constraint satisfaction if successful
@@ -167,16 +171,16 @@ using SparseArrays
167171
prob = OptimizationProblem(optfunc, x0, p)
168172

169173
# Test adaptive mu strategy
170-
sol = solve(prob, IpoptOptimizer();
174+
sol = solve(prob, IpoptOptimizer(
171175
mu_strategy = "adaptive",
172-
mu_init = 0.1)
176+
mu_init = 0.1))
173177

174178
@test SciMLBase.successful_retcode(sol)
175179
@test sol.u [1.0, 1.0] atol=1e-4
176180

177181
# Test monotone mu strategy
178-
sol2 = solve(prob, IpoptOptimizer();
179-
mu_strategy = "monotone")
182+
sol2 = solve(prob, IpoptOptimizer(
183+
mu_strategy = "monotone"))
180184

181185
@test SciMLBase.successful_retcode(sol2)
182186
@test sol2.u [1.0, 1.0] atol=1e-4
@@ -194,8 +198,10 @@ using SparseArrays
194198
lb = [-Inf, 2.0, -Inf],
195199
ub = [Inf, 2.0, Inf])
196200

197-
sol = solve(prob, IpoptOptimizer();
198-
fixed_variable_treatment = "make_parameter")
201+
sol = solve(prob, IpoptOptimizer(
202+
additional_options = Dict(
203+
"fixed_variable_treatment" => "make_parameter"
204+
)))
199205

200206
@test SciMLBase.successful_retcode(sol)
201207
@test sol.u [1.0, 2.0, 3.0] atol=1e-6
@@ -213,9 +219,9 @@ using SparseArrays
213219
prob = OptimizationProblem(optfunc, zeros(n), nothing;
214220
sense = Optimization.MaxSense)
215221

216-
sol = solve(prob, IpoptOptimizer();
222+
sol = solve(prob, IpoptOptimizer(
217223
acceptable_tol = 1e-4,
218-
acceptable_iter = 10,
224+
acceptable_iter = 10);
219225
maxiters = 50)
220226

221227
@test SciMLBase.successful_retcode(sol)
@@ -240,7 +246,7 @@ end
240246
end
241247

242248
@testset "Timing statistics" begin
243-
sol = solve(prob, IpoptOptimizer(); print_timing_statistics = "yes")
249+
sol = solve(prob, IpoptOptimizer(print_timing_statistics = "yes"))
244250
@test SciMLBase.successful_retcode(sol)
245251
end
246252
end

lib/OptimizationIpopt/test/problem_types.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ using SparseArrays
155155
lb = [0.0, 0.0, -1.0], # a, b > 0
156156
ub = [10.0, 10.0, 1.0])
157157

158-
sol = solve(prob, IpoptOptimizer(), tol=1e-10, acceptable_tol=1e-10)
158+
sol = solve(prob, IpoptOptimizer(
159+
acceptable_tol = 1e-10);
160+
reltol = 1e-10)
159161

160162
@test SciMLBase.successful_retcode(sol)
161163
# Parameters should be close to true values (within noise)
@@ -320,8 +322,8 @@ end
320322
lb = fill(-2π, n),
321323
ub = fill(2π, n))
322324

323-
sol = solve(prob, IpoptOptimizer();
324-
hessian_approximation = "limited-memory")
325+
sol = solve(prob, IpoptOptimizer(
326+
hessian_approximation = "limited-memory"))
325327

326328
@test SciMLBase.successful_retcode(sol)
327329
end

lib/OptimizationIpopt/test/runtests.jl

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ callback = function (state, l)
1919
return false
2020
end
2121

22-
sol = solve(prob, IpoptOptimizer(); callback, hessian_approximation = "exact")
22+
sol = solve(prob, IpoptOptimizer(hessian_approximation = "exact"); callback)
2323
@test SciMLBase.successful_retcode(sol)
2424
@test sol [1, 1]
2525

26-
sol = solve(prob, IpoptOptimizer(); callback, hessian_approximation = "limited-memory")
26+
sol = solve(prob, IpoptOptimizer(hessian_approximation = "limited-memory"); callback)
2727
@test SciMLBase.successful_retcode(sol)
2828
@test sol [1, 1]
2929

@@ -75,6 +75,7 @@ include("additional_tests.jl")
7575
include("advanced_features.jl")
7676
include("problem_types.jl")
7777

78+
7879
@testset "tutorial" begin
7980
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
8081
x0 = zeros(2)
@@ -115,3 +116,81 @@ end
115116
@test sol.u [2.0] # ≈ [2]
116117
end
117118
end
119+
120+
@testset "Additional Options and Common Interface" begin
121+
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
122+
x0 = zeros(2)
123+
p = [1.0, 100.0]
124+
125+
@testset "additional_options dictionary" begin
126+
optfunc = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
127+
prob = OptimizationProblem(optfunc, x0, p)
128+
129+
# Test with various option types
130+
opt = IpoptOptimizer(
131+
additional_options = Dict(
132+
"derivative_test" => "first-order", # String
133+
"derivative_test_tol" => 1e-4, # Float64
134+
"derivative_test_print_all" => "yes" # String
135+
)
136+
)
137+
sol = solve(prob, opt)
138+
@test SciMLBase.successful_retcode(sol)
139+
140+
# Test options not in struct fields
141+
opt2 = IpoptOptimizer(
142+
additional_options = Dict(
143+
"fixed_variable_treatment" => "make_parameter",
144+
"required_infeasibility_reduction" => 0.9,
145+
"alpha_for_y" => "primal"
146+
)
147+
)
148+
sol2 = solve(prob, opt2)
149+
@test SciMLBase.successful_retcode(sol2)
150+
end
151+
152+
@testset "Common interface arguments override" begin
153+
optfunc = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
154+
prob = OptimizationProblem(optfunc, x0, p)
155+
156+
# Test that reltol overrides default tolerance
157+
sol1 = solve(prob, IpoptOptimizer(); reltol = 1e-12)
158+
@test SciMLBase.successful_retcode(sol1)
159+
@test sol1.u [1.0, 1.0] atol=1e-10
160+
161+
# Test that maxiters limits iterations
162+
sol2 = solve(prob, IpoptOptimizer(); maxiters = 5)
163+
# May not converge with only 5 iterations
164+
@test sol2.stats.iterations <= 5
165+
166+
# Test verbose levels
167+
for verbose in [false, true, 0, 3, 5]
168+
sol = solve(prob, IpoptOptimizer(); verbose = verbose, maxiters = 10)
169+
@test sol isa SciMLBase.OptimizationSolution
170+
end
171+
172+
# Test maxtime
173+
sol3 = solve(prob, IpoptOptimizer(); maxtime = 10.0)
174+
@test SciMLBase.successful_retcode(sol3)
175+
end
176+
177+
@testset "Priority: struct < additional_options < solve args" begin
178+
optfunc = OptimizationFunction(rosenbrock, Optimization.AutoZygote())
179+
prob = OptimizationProblem(optfunc, x0, p)
180+
181+
# Struct field is overridden by solve argument
182+
opt = IpoptOptimizer(
183+
acceptable_tol = 1e-4, # Struct field
184+
additional_options = Dict(
185+
"max_iter" => 100 # Will be overridden by maxiters
186+
)
187+
)
188+
189+
sol = solve(prob, opt;
190+
maxiters = 50, # Should override additional_options
191+
reltol = 1e-10) # Should set tol
192+
193+
@test sol.stats.iterations <= 50
194+
@test SciMLBase.successful_retcode(sol)
195+
end
196+
end

0 commit comments

Comments
 (0)