# Rationale for black-box optim

Since Julia have powerful auto-differentiation library (such as `Zygote.jl`) and useful Optimization (convex or not) packages such as `JuMP.jl`, one may think a black-box optimization is not useful in almost any case. However, even within the pure-Julia ecosystem, one might find the function at hand having noisy/spiky differential, or, takes too long to compute not mentioning the differentials.

Another place a black-box optimization may come handy is when dealing with external programs, especially those closed source once or legacy (read: fossil) softwares.

# A short example

Say we have some compiled `C` program with the following function:

``````// ./test.c
#include <math.h>

double parab(double x){
return pow((3+x), 2);
}``````

we can compile a shared library:

``````gcc  -c -Wall -fPIC test.c -o test.o
gcc  -shared -fPIC -o test.so test.o

# gives us a ./test.so``````

We can use `@ccall` to access this function:

``````julia> @ccall "./test".parab(2.0::Float64)::Float64
25.0``````

Now, we wrap this into a function:[1]

``````julia> parab_c(x) = @ccall "./test".parab(x[1]::Float64)::Float64
parab_c (generic function with 1 method)``````

then we can black-box optimize it!

``````using BlackBoxOptim
julia> res = bboptimize(parab_c; SearchRange=(-5.0, 5.0), NumDimensions=1)
...
julia> best_candidate(res)
1-element Array{Float64,1}:
-3.0``````

In fact, we would realize that we don't care how the external program is invoked, as long as the returned 'stuff' is stable; you might as well just parse the `stdout` of some weird external program into numbers and feed it into `bboptimize`.

 [1] `BlackBoxOptim.jl` expects the function to take an `Array` even though your function may be a scalar one.