I have a function in about 3–7 variables (varies, ideally 7) and I am looking for a root.
It is best to treat the function as a “black box”, just delivering values and not derivatives, though I will try to make it work with ForwardDiff at some point, currently that is conceptually challenging. A function evaluation takes about 0.1s–0.5s, depending on problem size. I may be able to micro-optimize this by a factor of, say, 5, but that is costly.
NLsolve.nlsolve(f, ...) finds the global root reasonably robustly 99% of the time.
Optim.optimize(x -> sum(abs2, f(x)), ...) converges to a point that is not a root, usually.
The docs are about to be refreshed once we work out how to deploy them.
If your function is polynomial, you can try HomotopyContinuation.jl.
If it is Julia code and only uses “standard” functions like sin, and no control flow, you can try IntervalRootFinding.jl.
In your problem statement, I don’t understand what you mean by “robust”, nor the “global root”. If you actually have an optimisation problem, rather than a root finding problem, and with the same caveats as before, you can try IntervalOptimisation.jl (or indeed any of the optimization packages available through JuMP).
“Robust” refers to the fact that it should handle functions with minor local jumps. Theoretically the function is continuous; our solution methodology sometimes introduces jumps, no matter how hard we try to smooth them out. It is a market clearing and aggregate resource constraint from an economic model.
“Global root” was an unfortunate term, too. Occasionally we have multiple roots, some of them we can rule out as spurious knife-edge cases ex post.