Re: FindMinimum v. NMinimize and an external program

• To: mathgroup at smc.vnet.net
• Subject: [mg125177] Re: FindMinimum v. NMinimize and an external program
• From: Szabolcs <szhorvat at gmail.com>
• Date: Sun, 26 Feb 2012 04:20:37 -0500 (EST)
• Delivered-to: l-mathgroup@mail-archive0.wolfram.com
• References: <jia0qc\$1c4\$1@smc.vnet.net>

```On Saturday, 25 February 2012 08:58:20 UTC+2, Ian  wrote:
> Can anyone say whether the following behavior is expected and why? I'd like to avoid learning how to use MathLink, but I need to use FindMinimum on a large external calculation and my way is broken.
>
> Say there's a command line program called 'prog' that calculates y = (x-1)^2, reading x from a named pipe called 'in' and writing y to a named pipe called 'out'. Mathematica interacts with prog by reading and writing to the pipes. Like ...
>
> > in = OpenWrite["in"];
> > f[x_?NumericQ]:=(Write[in, CForm[x]]; First[ReadList["!cat out", Number]])
>
> Calling NMinimize on f gives the correct answer, but FindMinimum doesn't. Specifically, FindMinimum[f[x], {x, 0}] returns the message FindMinimum::fmgz. That is, Mathematica thinks the gradient is zero.
>
> I can't find a reason the two functions should behave differently. Any thoughts?
>
> A couple details for the DIYers. Here's prog:
> #include <stdio.h>
> #include <math.h>
> int main()
> {
>     FILE * io;
>     int j;
>     double x,y;
>
>     while((j = scanf("%lf", &x)) != EOF)
>     {
>         y = pow((x-1.0), 2);
>         io = fopen("out", "w");
>         fprintf(io, "%e\n", y);
>         fclose(io);
>     }
>     return;
> }
>
> Run prog with a redirect for stdin, as in
> /prog < in

Here's an actual example of using LibraryLink for your test function.   Just copy and paste all the code as it is and evaluate it.  The C code is included as strings for simplicity.

<< CCompilerDriver`

boilerplate =
"
#include \"WolframLibrary.h\"

DLLEXPORT mint WolframLibrary_getVersion(){
return WolframLibraryVersion;
}

DLLEXPORT int WolframLibrary_initialize( WolframLibraryData \
libData) {
return 0;
}

DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData \
libData) {
return;
}

DLLEXPORT int constantzero(WolframLibraryData libData, mint Argc, \
MArgument *Args, MArgument Res){
MArgument_setInteger(Res, 0);
return LIBRARY_NO_ERROR;
}
";

source =
"
#include <math.h>

DLLEXPORT int fun(WolframLibraryData libData,
mint Argc, MArgument *Args, MArgument Res) {
mreal R0;
mreal R1;
R0 = MArgument_getReal(Args[0]);
R1 = pow((R0-1),2);
MArgument_setReal(Res, R1);
return LIBRARY_NO_ERROR;
}

";

lib = CreateLibrary[boilerplate <> source, "test"]

fun = LibraryFunctionLoad[lib, "fun", {Real}, Real]

NMinimize[fun[x], x]

(* release lib so we can recompile if we want *)