7
$\begingroup$

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?

$\endgroup$
  • $\begingroup$ @OleksandrR. Please post this as an answer, and I would gladly accept it. "Not possible" is a perfectly valid answer. $\endgroup$ – Shredderroy Jan 25 '15 at 4:00
18
+500
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ Thank you very much for the Github link to your code. Do you also have sample code to demonstrate the usage of your NelderMeadMinimize function? I see some code at the bottom of the notebook, but I am having a bit of trouble using your function to fit a simple test function like x^2. $\endgroup$ – Shredderroy Jan 25 '15 at 6:37
  • $\begingroup$ @Shredderroy there are several examples of that nature (as well as fitting examples) in the body of the answer. The examples in the notebook are intended mainly as tests and not to be particularly explicative. In your case you would just type NelderMeadMinimize[x^2, x]. Please note that NelderMeadMinimize generates compiled code but by itself is not compilable--see the text of the answer for details of how to use its output in other compiled contexts. I suppose this is not of general interest to most people, but please feel free to ask about this in the chat. $\endgroup$ – Oleksandr R. Jan 25 '15 at 16:12
  • $\begingroup$ Thank you very much for your tremendous help. If I could up-vote your answer many times,I would. $\endgroup$ – Shredderroy Jan 25 '15 at 23:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.