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 *) LibraryUnload[lib]