From ed163443248c09b251850fca35bf38c0c85a0cdc Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Fri, 16 Aug 2024 15:14:05 +1200 Subject: [PATCH] Remove chk from optimize to allow failures to return to the user (#221) Co-authored-by: Vaibhavdixit02 --- src/NLopt.jl | 13 +++++++++++-- test/C_API.jl | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/NLopt.jl b/src/NLopt.jl index 7d8913f..bf67372 100644 --- a/src/NLopt.jl +++ b/src/NLopt.jl @@ -890,8 +890,17 @@ function optimize!(o::Opt, x::Vector{Cdouble}) x, opt_f, ) - chk(o, ret) - return (opt_f[1], x, Symbol(ret)) + # We do not need to check the value of `ret`, except if it is a FORCED_STOP + # with a Julia-related exception from a callback + if ret == FORCED_STOP + global nlopt_exception + e = nlopt_exception + nlopt_exception = nothing + if e !== nothing && !(e isa ForcedStop) + throw(e) + end + end + return opt_f[1], x, Symbol(ret) end function optimize(o::Opt, x::AbstractVector{<:Real}) diff --git a/test/C_API.jl b/test/C_API.jl index bb92a21..b394d1e 100644 --- a/test/C_API.jl +++ b/test/C_API.jl @@ -181,6 +181,33 @@ function test_tutorial() return end +# It's not obvious why this test returns FAILURE. If it breaks in future, look +# for something else. +function test_return_FAILURE_from_optimize() + function objective_fn(x, grad) + if length(grad) > 0 + grad[1] = -2 * (1 - x[1]) - 400 * x[1] * (x[2] - x[1]^2) + grad[2] = 200 * (x[2] - x[1]^2) + end + return (1 - x[1])^2 + 100 * (x[2] - x[1]^2)^2 + end + function eq_constraint_fn(h, x, J) + if length(J) > 0 + J[1, 1] = 2x[1] + J[2, 1] = 2x[2] + end + h[1] = x[1]^2 + x[2]^2 - 1.0 + return + end + opt = Opt(:AUGLAG, 2) + opt.local_optimizer = Opt(:LD_LBFGS, 2) + opt.min_objective = objective_fn + equality_constraint!(opt, eq_constraint_fn, [1e-8]) + _, _, ret = optimize(opt, [0.5, 0.5]) + @test ret == :FAILURE + return +end + end # module TestCAPI.runtests()