Dear Oyibo, first of all, I should say that I'm not convinced that the example contained in the matecdev site is a good example. Whilst I haven't checked it seems that using `interpolate.LSQUnivariateSpline` may achieve what that poster was trying to accomplish, and would be much faster than the python code presented.
Most of the answer to your question is pretty much contained in https://github.com/scipy/scipy/issues/11783. In terms of speed the most important thing is to ensure that the objective function calculates quickly. This typically involves moving calculations from Python to C/Cython, etc. Only once this has been investigated is it worth looking into optimiser overhead. This overhead is often (but not always) much smaller than the time required for objective function calculation. Such overhead includes objective function call time, or overhead from the optimiser itself. There is a wide heterogeneity of code design in scipy.optimise. Some work: A) in pure python (e.g. BFGS, nelder-mead) B) in C/Fortran where you supply a callback function for the native code to call (e.g. tnc, leastsq) C) in C/Fortran but where iteration is controlled by python and the native code expects a objective/gradient function updates each time it's called (L-BFGS-B). Using LowlevelCallable would not furnish any gains for case A. Rewriting of those codes to cython would be a lot of work for an uncertain amount of gain. Using LowlevelCallable for case B would likely furnish the most gain. Using LowlevelCallable for case C would probably involve rewriting so that all iteration occurred from Cython/C, but the level of gain is still uncertain. There remain further issues. Let's take `tnc` as an example (case B). For that minimiser it's necessary to supply both objective AND gradient evaluations. The user must supply the first, but if the user cannot supply the gradient then `minimize` is asked to estimate it via numerical differentiation. Estimating the gradient with numerical differentiation occurs in Python. This kind of setup is taken care of by using the `optimize._differentiable_functions.ScalarFunction` object. Thus, a LowlevelCallable that only furnishes objective evaluations is not much use, because the numerical differentiation (in Python) is still required to evaluate gradients, which requires at least N objective calls (from Python to whatever the objective is contained in). In order for this to be fully streamlined the numerical differentiation code would also have to be written in cython/c. Note that the user can either supply the objective function, separate objective and gradient functions, or a combined objective and gradient function. All those different cases have to be catered for. Moreover, for each of those cases one would either be supplying a `LowlevelCallable` or Python function. Last, but not least, most minimisers often ask numpy to perform operations, so porting minimisers to cython will still have python calls. Thus, it's a large task just to amend a *single* minimiser. There are lots of minimisers and one would want to do this in a uniform manner across them all. Given the width of such a project, one would want to conclusively know that it would be worth it, and that's definitely not clear. Andrew.
_______________________________________________ SciPy-Dev mailing list -- scipy-dev@python.org To unsubscribe send an email to scipy-dev-le...@python.org https://mail.python.org/mailman3/lists/scipy-dev.python.org/ Member address: arch...@mail-archive.com