mathematical optimization - Is there any strategy to have a compiled version of FindFit or NonlinearModelFit?
Disclaimer: This is not a precise question with a definite answer.
I know that neither FindFit
nor NonlinearModelFit
is in the list returned by the command:
Compile`CompilerFunctions[] // Sort
But I am in the middle of refactoring a large Wolfram Language code base which uses FindFit
in many places. I need to write compiled versions of each of these functions, so that I may generate C code out of it, which will be built into a DLL and included in our one-step build process for our overall web application.
Since FindFit
and NonlinearModelFit
do not compile, I would like to come up with a substitute strategy. Short of trying to reimplement these functions, is there any way to generate the replacement rules returned by FindFit
, or the function generated by NonlinearModelFit
so that the code using these functions can be compiled?
Answer
No, it is not possible.
With code converted to a LibraryLink library by way of Compile
you are limited to using functions that either can be expressed directly in C, or exist in the runtime library; unfortunately, FindFit
is not included in either category. When present in code passed to Compile
, FindFit
results in a call back to the top level, and it is handled by a C implementation in the Mathematica runtime (i.e., the kernel), where it calls the same code exposed by FindMinimum
. NonlinearModelFit
is actually implemented entirely as top-level code (which in turn calls FindFit
for the actual fitting), and so its requirements are even further removed from what one can provide in LibraryLink libraries.
This situation exists for many Mathematica functions, and the requirement for the code to be interpretable by the compiler (with its strict limitations, many oddities, and occasional bugs) may make your task (with your current approach) more difficult to accomplish than simply rewriting from scratch in conventional C or C++. If this is not possible or desirable, for example due to the use of algorithms or features not available elsewhere, then you should probably consider having Mathematica available on the server, where you can call it via MathLink in a mixed C/Mathematica language implementation.
As far as your question is concerned, all that you really need to do a nonlinear fit is a reasonably robust minimization algorithm implemented in the compilable subset. Various options are available to you for this, including conjugate gradient methods (quasi-Newton methods unfortunately are not possible because Inverse
is not compilable, being itself implemented as a call to the MKL), differential evolution, or the Nelder-Mead downhill simplex algorithm. My favorite of these is the latter, because it is reasonably economical with objective function evaluations while not requiring the function to be differentiable, and it also has a straightforward procedural implementation involving not much more than simple arithmetic. For these reasons I already implemented it in compiled code, and in fact specifically for a fitting application. The same code may help you, if FindFit
is really the only thing you need to reproduce in C.
Comments
Post a Comment