Message Boards Message Boards

interface to external program / command line and optimisation [beginner]

Posted 9 years ago

Trying to: -1- define a function which takes a number [step 1], write to a file [step 2], runs an external bash script [step 3], read a text file and return the result as a number [step 4] -2- trying to optimise this function with NMinimize

Here is the code of the function:

f[x_] := CompoundExpression[SetDirectory["~/Desktop/test"];

  Print[x]; (*this is for debugging*)

  Export["in.data", N[x], 
   "Text"]; (*this saves the value x in a text file*)
  Run["~/Desktop/test/run.sh"]; (*this runs a shell script which \
takes the text file, 
  read it and makes the square of the number in in, 
  a place holder for more to come*)

  N[ToExpression[
    Import["out.data"]]](*this reads the number from the script \
output and convert to number*) ]

If I use: f[10], all if fine. the result is 100.

However if I use:

NMinimize[{f[y], 0 < y < 10}, {y}, Method -> "SimulatedAnnealing"]

The results is nonsense as the function writes "y" in the first text file as symbolic form.

Any idea on how to make this work? Thanks G.

POSTED BY: geotrupes a
6 Replies
Posted 9 years ago

Perhaps this

POSTED BY: Bill Simpson
Posted 9 years ago

You think you are seeing this behaving as you expect

In[1]:= f[x_?NumericQ] := RunProcess[{"echo", ToString[InputForm[x^2, NumberMarks->False]]},"StandardOutput"];
   f[3]

but if you then do this

Print[FullForm[%]]

I believe you will understand that your function is returning a string, not a numeric value, and trying to "minimize a string" isn't going to work.

If you are running Windows then

f[x_?NumericQ] := ToExpression[StringDrop[RunProcess[{"echo", ToString[InputForm[x^2, NumberMarks->False]]}, "StandardOutput"], -2]];
Print[FullForm[f[3]]]

might be closer to what you want. And if you aren't running Windows then the StringDrop may need to be adjusted to match your local conventions.

I think there should be a much better way of doing what you are trying to do.

POSTED BY: Bill Simpson
Posted 9 years ago

Thank you Bill, tried and it works

f[x_?NumericQ] := CompoundExpression[
  SetDirectory["~/Desktop/test"];
  Print[N[x]]; 
  Export["in.data", N[x], "Text"];
  Run["~/Desktop/test/run.sh"]; 
  result = N[ToExpression[Import["out.data"]]] ;
  Run["rm *.data"];
  Print[result]

There are few issues to resolve but this is great.

THANK YOU! G.

PS do you happen to know if this is running in a multicore fashion?

POSTED BY: geotrupes a
Posted 9 years ago

I seem to be stuck. When I evaluate the function on its own all is fine. Even when the optimisation starts, but gets stack after 2 cycles. It looks like there is a multicore batch happening, therefore the output is messed up.

I tried switching off cores and nothing happens. I also tried to change the code so an index keeps each run separate, but at no avail.

here is the modified text:

f[x_?NumericQ] := CompoundExpression[
  SetDirectory["~/Desktop/test"]; 
  index = ToExpression[Import["index.ini"]];
  (* *)Print[index];(* Print[N[x]]; *)
  indexname = ToString[index]; 
  Export["in." <> indexname <> ".data", N[x], "Text"];
  Run["~/Desktop/test/run.sh " <> indexname]; 
  result = N[ToExpression[Import["out." <> indexname <> ".data"]]];
  Run["rm *.data"];
  index = index + 1;
  Print[index];
  Export["index.ini", indexname, "Text"];
  Print[result];
  ]

and here is the crash.

NMinimize[{f[y], 0 < y < 10}, {y}, Method -> "SimulatedAnnealing"]

0

1

0.20914

0

1

0.20914

NMinimize::nnum: The function value Null is not a number at {y} = {0.457318}. >>

0

1

0.20914

0

1

0.20914

NMinimize::nnum: The function value Null is not a number at {y} = {0.457318}. >>

0

1

0.20914

0

1

0.20914

NMinimize::nnum: The function value Null is not a number at {y} = {0.457318}. >>

General::stop: Further output of NMinimize::nnum will be suppressed during this calculation. >>

0

1

0.20914

0

1

0.20914

NMinimize[{f[y], 0 < y < 10}, {y}, Method -> "SimulatedAnnealing"]

any idea? Thanks G.

POSTED BY: geotrupes a
Posted 9 years ago

Ok, I tried a simpler function. Using echo to print a square, made in Mathematica.

See this:

f[x_?NumericQ] := 
  RunProcess[{"echo", ToString[InputForm[x^2, NumberMarks -> False]]}, 
   "StandardOutput"];

It works for a single value of x, but then NMinimize complains that:

NMinimize[{f[y], 1 < y < 10}, {y}, Method -> "RandomSearch"]


NMinimize::nnum: The function value 1.9925755057065486`
 is not a number at {y} = {1.41159}. >>

What is the issue? I must confess to be rather lost at this stage :-( Thanks G>

POSTED BY: geotrupes a
Posted 9 years ago

The ToExpression solves the issue and all works!! I am very new to Mathematica an trying to run without knowing how to walk :-) If there is a better way and you have some idea please shoot! Thank you, G>

POSTED BY: geotrupes a
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract