# ExperimentalNumericalFunction in NMinimize solution

I try to make a number of optimizations using this code:

Gmin = 0.3;
Gmax = 3;
Gd = 0.3;
Tmin = 3;
Tmax = 30;
Td = 3;
Vmin = 150;
Vmax = 1500;
Vd = 150;
sols = Flatten[
ParallelTable[{Gcur, Tcur, Vcur,
Quiet[NMinimize[{Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5],
Abs[0.055*(x1 + 11) + 0.065*(x2 - 13) + 0.068*(x3 - 47) +
0.071*(x4 - 50) + 0.07*(x5 - 43) + 0.852] <= Gcur &&
Abs[-8.567*(x1 + 11) - 9.057*(x2 - 13) - 9.154*(x3 - 47) -
8.937*(x4 - 50) - 8.608*(x5 - 43) - 1359.469] <= Tcur &&
Abs[55.818*(x1 + 11) + 62.22*(x2 - 13) + 64.286*(x3 - 47) +
64.945*(x4 - 50) + 63.306*(x5 - 43) + 4747.69] <=
Vcur}, {x1, x2, x3, x4, x5}(*,
Method->"DifferentialEvolution"*)]][]}
, {Gcur, Gmin, Gmax, Gd}, {Tcur, Tmin, Tmax, Td}, {Vcur, Vmin,
Vmax, Vd}
], 2]


As a result i have a nested list of solutions:

{{0.3, 3, 150, 1355.75}, {0.3, 3, 300, 1330.44}, ...}


Most of solutions are normal, but some look like:

{0.3,9,900,ExperimentalNumericalFunction[{Hold[Abs[-599.245]+Abs[-142.174]+Abs[1.74305]+Abs[307.535]+Abs[415.575]],Block},{0,{{1,0,Hold[-599.245],0,0},{1,1,Hold[-142.174],0,0},{1,2,Hold[1.74305],0,0},{1,3,Hold[307.535],0,0},{1,4,Hold[415.575],0,0}}},{{{1,5,817},{{Automatic,Automatic,None,1,Automatic},{Automatic,Automatic,None,1,Automatic}}}},{0,3,0},{908,MachinePrecision,{{Automatic},{Hold[Abs[-599.245]+Abs[-142.174]+Abs[1.74305]+Abs[307.535]+Abs[415.575]],Block}},True,{{Automatic,CleanUpRegisters->False,WarningMessages->False,EvaluateSymbolically->False,RuntimeErrorHandler->($Failed&)},Automatic,MVM},ExperimentalNumericalFunction,Automatic,None},{None,None,None}]}  What does it all mean? How can i avoid this? Thanks. • To break the silence: it could be a bug. To tell for sure, we'd need a better example which makes it easier to reproduce this. (I didn't reproduce it using your code because I ran out of patience and stopped it.) But people here confirming that it's a bug is still no help for your work. So the better way to proceed is probably to just report it to support at wolfram.com, preferably with an easier to replicate example, and hope that it'll be fixed by the next version ... – Szabolcs Feb 27 '14 at 3:19 • The problem is that this NumericalFunction thingie is undocumented and it's for internal use only. So most of us don't know much about it, and won't be able to make a good guess about what's going wrong (e.g. is related to parallelization or not?) – Szabolcs Feb 27 '14 at 3:23 • Thanks for reply. These calculations really take a lot of time (nearly 8 minutes on single corei7 machine), but i don't know what easier example to suggest. When i choose less iterations, there are no issues at all. I'll forward it to support. – shda Feb 27 '14 at 8:00 • I confirm this behavior in Mathematica 8.0.4 under Windows with Table instead of ParallelTable. So it is not related to parallel computing functionality. After a hour of waiting I have got two such objects: at {Gcur, Tcur, Vcur} = {0.3, 9, 900} and at {Gcur, Tcur, Vcur} = {0.3, 15, 150}. After restarting the kernel and evaluating {Gcur, Tcur, Vcur} = {0.3, 9, 900} and then Nminimize[...] I get a couple of error messages (first two are NMinimize::incst) and the object cited in the question. – Alexey Popkov Apr 25 '14 at 4:21 ## 1 Answer NMinimized is creating a seemingly malformed ExperimentalNumericalFunction expression internally, not catching it, and returning it as the minimum value. It certainly seems like a bug. ### The apparent misbehavior Below is a good ExperimentalNumericalFunction that represents the objective function. (Caveat: Because we're blocking it, it messes up NMinimize, but the function is well-formed.) Block[{ExperimentalNumericalFunction}, f = Last@Cases[ Trace[ Hold[ NMinimize[{Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5], Abs[0.055*(x1 + 11) + 0.065*(x2 - 13) + 0.068*(x3 - 47) + 0.071*(x4 - 50) + 0.07*(x5 - 43) + 0.852] <= Gcur && Abs[-8.567*(x1 + 11) - 9.057*(x2 - 13) - 9.154*(x3 - 47) - 8.937*(x4 - 50) - 8.608*(x5 - 43) - 1359.469] <= Tcur && Abs[55.818*(x1 + 11) + 62.22*(x2 - 13) + 64.286*(x3 - 47) + 64.945*(x4 - 50) + 63.306*(x5 - 43) + 4747.69] <= Vcur}, {x1, x2, x3, x4, x5}(*,Method\[Rule]"DifferentialEvolution"*)]] /. Thread[{Gcur, Tcur, Vcur} -> {0.1, 9, 900}] // ReleaseHold, TraceInternal -> True], _ExperimentalNumericalFunction, Infinity] // Quiet ] List @@ f (* ExperimentalNumericalFunction[{x1, x2, x3, x4, x5}, Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5], "-NumericalFunctionData-"] {{Hold[Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5]], Block}, {0, {{{}, 1, 0, Hold[x1], 0, 0}, {{}, 1, 1, Hold[x2], 0, 0}, (* N.B. *) {{}, 1, 2, Hold[x3], 0, 0}, {{}, 1, 3, Hold[x4], 0, 0}, {{}, 1, 4, Hold[x5], 0, 0}}}, {{{1, 5, 817}, {{Automatic, Automatic, None, 1, Automatic}, {Automatic, Automatic, None, 1, Automatic}}}}, {0, 3, {}, 0}, (* N.B. *) {924, MachinePrecision, {{Automatic}, {Hold[Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5]], Block}}, True, {{Automatic, "CleanUpRegisters" -> False, "WarningMessages" -> False, "EvaluateSymbolically" -> False, "RuntimeErrorHandler" -> ($Failed &)},
{},                                                                 (* N.B. *)
Automatic, "MVM"},
ExperimentalNumericalFunction, Automatic, None},
{None, None, None}
}
*)


When compare it with the solutions in the OP's output, we see there are three places where the expression does not conform to the above structure.

{foo, pt} =
Hold[NMinimize[{Abs[x1] + Abs[x2] + Abs[x3] + Abs[x4] + Abs[x5],
Abs[0.055*(x1 + 11) + 0.065*(x2 - 13) + 0.068*(x3 - 47) +
0.071*(x4 - 50) + 0.07*(x5 - 43) + 0.852] <= Gcur &&
Abs[-8.567*(x1 + 11) - 9.057*(x2 - 13) - 9.154*(x3 - 47) -
8.937*(x4 - 50) - 8.608*(x5 - 43) - 1359.469] <= Tcur &&
Abs[55.818*(x1 + 11) + 62.22*(x2 - 13) + 64.286*(x3 - 47) +
64.945*(x4 - 50) + 63.306*(x5 - 43) + 4747.69] <=
Vcur}, {x1, x2, x3, x4, x5}]] /.
Thread[{Gcur, Tcur, Vcur} -> {0.3, 9, 900}] // ReleaseHold //
Quiet;
foo

(*
ExperimentalNumericalFunction[
{Hold[Abs[-599.2446539346419] + Abs[-142.17435987634218] +
Abs[1.7430469375731925] + Abs[307.5351957153216] +
Abs[415.5751895785901]], Block},
{0,
{{1, 0, Hold[-599.2446539346419], 0, 0},  (* malformed variables *)
{1, 1, Hold[-142.17435987634218], 0, 0},
{1, 2, Hold[1.7430469375731925], 0, 0}, {1, 3, Hold[307.5351957153216], 0, 0},
{1, 4, Hold[415.5751895785901], 0, 0}}},
{{{1, 5, 817}, {{Automatic, Automatic, None, 1, Automatic}, {Automatic,
Automatic, None, 1, Automatic}}}},
{0, 3, 0},                                  (* missing output spec {} *)
{908,                                       (* different code *)
MachinePrecision,
{{Automatic}, {Hold[Abs[-599.2446539346419] + Abs[-142.17435987634218] +
Abs[1.7430469375731925] + Abs[307.5351957153216] +
Abs[415.5751895785901]], Block}},
True,
{{Automatic, "CleanUpRegisters" -> False,
"WarningMessages" -> False, "EvaluateSymbolically" -> False,
"RuntimeErrorHandler" -> ($Failed &)}, (* missing Compile RuntimeAttributes *) Automatic, "MVM"}, ExperimentalNumericalFunction, Automatic, None}, {None, None, None}] *)  If we fix these, we get a well-formed ExperimentalNumericalFunction: fooFixed = ExperimentalNumericalFunction[{Hold[ Abs[-599.2446539346419] + Abs[-142.17435987634218] + Abs[1.7430469375731925] + Abs[307.5351957153216] + Abs[415.5751895785901]], Block}, {0, {{{}, 1, 0, Hold[x1], 0, 0}, (* malformed variables *) {{}, 1, 1, Hold[x2], 0, 0}, {{}, 1, 2, Hold[x3], 0, 0}, {{}, 1, 3, Hold[x4], 0, 0}, {{}, 1, 4, Hold[x5], 0, 0}}}, {{{1, 5, 817}, {{Automatic, Automatic, None, 1, Automatic}, {Automatic, Automatic, None, 1, Automatic}}}}, {0, 3, {}, 0}, (* missing output spec {} *) {(*908*)924, (* unimportant here? *) MachinePrecision, {{Automatic}, {Hold[Abs[-599.2446539346419] + Abs[-142.17435987634218] + Abs[1.7430469375731925] + Abs[307.5351957153216] + Abs[415.5751895785901]], Block}}, True, {{Automatic, "CleanUpRegisters" -> False, "WarningMessages" -> False, "EvaluateSymbolically" -> False, "RuntimeErrorHandler" -> ($Failed &)},
{},                                      (* missing Compile RuntimeAttributes *)
Automatic, "MVM"},
ExperimentalNumericalFunction, Automatic, None},
{None, None, None}]

fooFixed[{0, 0, 0, 0, 0}]

(*
ExperimentalNumericalFunction[{x1, x2, x3, x4, x5},
Abs[-599.245] + Abs[-142.174] + Abs[1.74305] + Abs[307.535] + Abs[415.575],
"-NumericalFunctionData-"]

1466.27
*)


Notes:

1. I am assuming the value of the ExperimentalNumericalFunction is the minimum found by NMinimize.

2. The minimum value returned is different in the different versions! Perhaps specifying the initial points, as suggested in the suppressed warning NMinimize::incst, would help.

3. If I apply FindMinimum to either the good or the buggy case above (Gcur -> 0.1 or Gcur -> 0.3), it returns a smaller minimum.

4. The structure of ExperimentalNumericalFunction changed between V8.0.4 and V9.0.1. The same sort of errors occur in both versions, and the same sort of fix can be performed. The code will be different, of course.

5. The code, 924 v. 908, does not make a difference in fooFixed[{0, 0, 0, 0, 0}]. How it affects other uses I do not know.

### Simpler fix

Note that the first held expression is the formula for the function. One can evaluate the malformed ExperimentalNumericalFunction as follows:

foo /. ef_ExperimentalNumericalFunction :> ReleaseHold @ ef[[1, 1]] /. pt


or simply

ReleaseHold @ foo[[1,1]] /. pt
(* 1466.27 *)


In the OP's case the functions are constant, so that substituting (/. pt) the values of x1 etc is unnecessary. The OP's solution list can be fixed thus:

sol /. ef_ExperimentalNumericalFunction :> ReleaseHold @ ef[[1, 1]]
`