This package is registered in HolyLabRegistry---you'll likely want to add that as an additional registry.
QuadDIRECT is an algorithm for global optimization without requiring derivatives. It was inspired by DIRECT and MCS:
DIRECT: Jones, Donald R., Cary D. Perttunen, and Bruce E. Stuckman. "Lipschitzian optimization without the Lipschitz constant." Journal of Optimization Theory and Applications 79.1 (1993): 157-181.
MCS: Huyer, Waltraud, and Arnold Neumaier. "Global optimization by multilevel coordinate search." Journal of Global Optimization 14.4 (1999): 331-355.
There is no formal published description (yet), but it expands upon DIRECT by:
Unlike MCS,
As a simple demonstration, consider the "6-hump camel function":
julia> function camel(x)
# 6-hump camel function. Typically evaluated over [-3,3] × [-2,2].
x1, x2 = x[1], x[2]
x1s = x1*x1
x2s = x2*x2
return (4 - 2.1*x1s + x1s*x1s/3)*x1s + x1*x2 + (-4 + 4*x2s)*x2s
end
Here the value scale was cut off at 5 so that the structure of the minima can be seen. You can explore this function with
julia> using QuadDIRECT
julia> lower, upper = [-3,-2], [3,2] # domain over which we allow solutions
([-3, -2], [3, 2])
julia> splits = ([-2, 0, 2], [-1, 0, 1]) # initial locations to evaluate function
([-2, 0, 2], [-1, 0, 1])
julia> root, x0 = analyze(camel, splits, lower, upper)
(BoxRoot@[NaN, NaN], [0.0, 0.0])
This creates a tree structure (currently) with a few hundred boxes, each corresponding to a single function evaluation:
You can see that it has concentrated its function evaluations near the local minima,
and that all of the minima were explored.
This plot was generated by utilities in QuadDIRECT/src/plotting.jl
, which have to be
loaded separatedly from the QuadDIRECT
module.
You can inspect the minimum like this:
julia> box = minimum(root)
Box-1.0316284406055976@[0.0898781, -0.71269]
julia> value(box)
-1.0316284406055976
julia> position(box, x0)
2-element Array{Float64,1}:
0.0898781
-0.71269
These match the known global optima to reasonably high precision.
There's also a convenience function minimize
which just returns the location and value of the
minimum.
For more examples, see the demo
directory.
In global optimization, "convergence" is a tricky subject: if the function might be non-convex,
there is no principled way to say you're done---that your best minimum so far is the
best minimum there is---without some additional information about the function. QuadDIRECT
terminates if no further improvements have been made after ndims
iterations. If you're
benchmarking QuadDIRECT, here are a few tips:
fvalue
option for analyze
.fc = CountedFunction(f)
and then use numevals(fc)
to see how many evaluations were used. This is slightly more
accurate than length(leaves(root))
because there are a few cases where the function value
is not stored in the tree structure.LoggedFunction
to keep a record of every function value computed. The latter is
particularly useful if you want to ask how many evaluations were required to reach a value of particular quality.