NLopt.jl
NLopt.jl copied to clipboard
Problems with LN_PRAXIS, GN_DIRECT and others...
I've been experimenting with this package to compare some optimization methods (global/ local and with/without derivatives). I apologize if this is a dumb comment (since it's my first experience with NLopt), but I ran into some difficulties.
My first objective was to follow README.md and find a minimizer of the Himmelblau function. Here is what I tried:
using NLopt
count = 0 # keep track of # function evaluations
function Himmelblau(x::Vector,grad::Vector=[])
if !isempty(grad)&& length(grad)>0
grad[1] = 4*(x[1]^2+x[2]-11)*x[1]+2*(x[1]+x[2]^2-7)
grad[2] = 2*(x[1]^2+x[2]-11)+4*(x[1]+x[2]^2-7)*x[2]
end
global count
count::Int += 1
(x[1]^2 + x[2] - 11)^2 + (x[1] + x[2].^2 - 7).^2
end
opt = Opt(:GN_DIRECT, 2) # throws error
# opt = Opt(:LD_MMA, 2) # works fine
min_objective!(opt, Himmelblau)
x0 = [-0.1;-1]
(minf,minx,ret) = NLopt.optimize(opt,x0)
running this code, I get the following error (that I have a hard time understanding):
LoadError: ArgumentError: invalid NLopt arguments
while loading In[50], in expression starting on line 20
in chk(::Int32) at ~/.julia/v0.5/NLopt/src/NLopt.jl:259
in chks(::Int32) at ~/.julia/v0.5/NLopt/src/NLopt.jl:276
in optimize!(::NLopt.Opt, ::Array{Float64,1}) at~/.julia/v0.5/NLopt/src/NLopt.jl:529
in optimize(::NLopt.Opt, ::Array{Float64,1}) at ~/.julia/v0.5/NLopt/src/NLopt.jl:532
Is this a bug, or am I using NLopt incorrectly? If we get this to work, can I add this example (I have a longer ipynb with plots) to this repository?
According to the NLopt documentation link: "Most of the above algorithms only handle bound constraints, and in fact require finite bound constraints (they are not applicable to unconstrained problems)."
So I would guess that you need to add constraints to your optimization. This README specifies how to do that, specifically:
lower_bounds!(opt::Opt, lb::AbstractVector)
upper_bounds!(opt::Opt, ub::AbstractVector)
thanks for this, @stevenjgilmore ! Actually adding bound constraints makes a lot of sense here. I now add
lb = -4.*ones(2)
ub = 4.*ones(2)
lower_bounds!(opt,lb)
upper_bounds!(opt,ub)
to my example right before calling optimize. The previous error disappeared but now I get a Segmentation fault
signal (11): Segmentation fault: 11
while loading no file, in expression starting on line 0
unknown function (ip: 0xffffffffffffffff)
Allocations: 3345662 (Pool: 3344657; Big: 1005); GC: 4
Segmentation fault: 11
This seems to already be an open issue: #64
Unfortunately it's unresolved. I'd recommend using a different algorithm for now
Closing as stale, and because the error has since been improved. It is now:
julia> using NLopt
julia> count = 0 # keep track of # function evaluations
0
julia> function Himmelblau(x::Vector,grad::Vector=[])
if !isempty(grad)&& length(grad)>0
grad[1] = 4*(x[1]^2+x[2]-11)*x[1]+2*(x[1]+x[2]^2-7)
grad[2] = 2*(x[1]^2+x[2]-11)+4*(x[1]+x[2]^2-7)*x[2]
end
global count
count::Int += 1
(x[1]^2 + x[2] - 11)^2 + (x[1] + x[2].^2 - 7).^2
end
Himmelblau (generic function with 2 methods)
julia> opt = Opt(:GN_DIRECT, 2) # throws error
Opt(GN_DIRECT, 2)
julia> # opt = Opt(:LD_MMA, 2) # works fine
min_objective!(opt, Himmelblau)
julia> x0 = [-0.1;-1]
2-element Vector{Float64}:
-0.1
-1.0
julia> (minf,minx,ret) = NLopt.optimize(opt,x0)
ERROR: ArgumentError: invalid NLopt arguments: finite domain required for global algorithm
Stacktrace:
[1] chk(o::Opt, result::Result)
@ NLopt ~/.julia/dev/NLopt/src/NLopt.jl:212
[2] optimize!(o::Opt, x::Vector{Float64})
@ NLopt ~/.julia/dev/NLopt/src/NLopt.jl:624
[3] optimize(o::Opt, x::Vector{Float64})
@ NLopt ~/.julia/dev/NLopt/src/NLopt.jl:628
[4] top-level scope
@ REPL[10]:1