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

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.

Perhaps this

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?

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.

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
:frowning:
Thanks
G>

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.

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