How do I use NMaximize on a Function that contains LinearProgramming?

I am trying to maximize a function that effectively has variable matrix elements that need to be optimized using Linear Programming.

Here is my function:

TestFunc[x1_, x2_] := (
toymat =
Transpose[{{-1., -1., 1., 0., 0.}, {0., -1., -1., 1., 0.}, {0.,
0., -x1, -x2, 1.}, {1., 0., 0., 0., 0.}, {0., 1., 0., 0.,
0.}, {0., 0., 0., 0., -1.}}];
ss = Table[{0, 0}, {5}];
objective = {0, 0, 0, 0, 0, 1};
constraints = Table[{0, 100}, {Range[6]}];
result = LinearProgramming[-objective, toymat, ss, constraints];
Return[result[[6]]];)

In[87]:= TestFunc[1., 1.]
Out[87]= 33.3333


I would like to optimize the result of this function using NMinimize to find the global maximum with respect to the two array elements (subject to other constraints). I try the following:

NMaximize[{TestFunc[pp, rr], 0.01 <= pp <= 5.0, 0.01 <= rr <= 5.0}, {pp, rr}]


Resulting in the following error:

LinearProgramming::lpnn: Input data to linear programming algorithm {{0,0,0,0,0,-1},{{}},{},{{-1.,0.,0.,1.,0.,0.},{-1.,-1.,0.,0.,1.,0.},{1.,-1.,-pp,0.,0.,0.},{0.,1.,-rr,0.,0.,0.},{0.,0.,1.,0.,0.,-1.}},{0,0,0,0,0},{0,0,0,0,0,0},{100,100,100,100,100,100}} contains elements that are empty matrices, invalid vectors or matrices, or not real numbers.

LinearProgramming::lpnn: Input data to linear programming algorithm {{0,0,0,0,0,-1},{{}},{},{{-1.,0.,0.,1.,0.,0.},{-1.,-1.,0.,0.,1.,0.},{1.,-1.,-pp,0.,0.,0.},{0.,1.,-rr,0.,0.,0.},{0.,0.,1.,0.,0.,-1.}},{0,0,0,0,0},{0,0,0,0,0,0},{100,100,100,100,100,100}} contains elements that are empty matrices, invalid vectors or matrices, or not real numbers.

LinearProgramming::lpnn: Input data to linear programming algorithm {{0,0,0,0,0,-1},{{}},{},{{-1.,0.,0.,1.,0.,0.},{-1.,-1.,0.,0.,1.,0.},{1.,-1.,-pp,0.,0.,0.},{0.,1.,-rr,0.,0.,0.},{0.,0.,1.,0.,0.,-1.}},{0,0,0,0,0},{0,0,0,0,0,0},{100,100,100,100,100,100}} contains elements that are empty matrices, invalid vectors or matrices, or not real numbers.

It appears that NMaximize is not passing numerical values to LinearProgramming. There is apparently something going on "under the hood" that I do not understand. My problem involves more complex matrices and relations between the matrix elements, and I tried to reduce the error to a toy system for clarity. I was able to use an empirical grid-search over the space for the matrix elements, but this seems obtuse and inefficient.

Any insights or suggestions would be appreciated!

• Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. Jun 25, 2018 at 20:29
• In the help for LinearProgramming It looks as though for this particular problem the LinearProgramming algorithm does not accept parameters which is causing the problem. The help states "All entries in the vectors c and b and the matrix m must be real numbers." Not too sure whether this helps, but maybe someone else finds a workaround. Jun 25, 2018 at 20:32

Many Mathematica functions will attempt symbolic simplifications before anything else. You can prevent this with numerical functions by defining the function to only take numerical parameters, such as by changing

TestFunc[x1_, x2_] := ...


To:

TestFunc[x1_?NumericQ, x2_?NumericQ] := ...


This will still throw a warning, but it will just be about convergence. You may wish to examine:

ContourPlot[TestFunc[x, y], {x, 0.01, 5}, {y, 0.01, 5}]


To determine whether or not you wish to be concerned about the convergence warning. In this case, it looks like there is a large region of your input domain where your function is maximized.

• Thank you. I tried this, but to no avail. I have also tried forcing with Evaluate. Jun 26, 2018 at 12:21
• The "real" function I am trying to maximize does have a local max, unlike this toy function. I just need to figure out how to get these two functions to work together. Jun 26, 2018 at 12:23

Successful workaround, both of the following are required:

TestFunc[x1_?NumericQ, x2_?NumericQ] := ...


as suggested by eyorble, and

With[{p = p1, r = r1},
NMaximize[{TestFunc[p, r], 0.01 <= p <= 4.0, 0.01 <=r<=4.0}, {p, r}]]


(warning about convergence thrown, but that's ok. "Real" Function works!). Onward.