This is a rather common issue that comes up with many numerical functions (FindRoot
, NIntegrate
, FindMaximum
, NMaximize
, etc.) It is also explained in this Wolfram Knowledge Base article. Sometimes you want to pass these functions an expression that has a symbolic parameter, and compute the result for different values of that parameter.
Example:
fun[a_] := Block[{b}, b /. NMinimize[(a^2 + b)^2, {b}][[2]]]
This will work nicely if you call it with a numeric argument: fun[3]
. But it will cause an error in NMinimize
if you call it with a symbolic parameter: fun[a]
(for obvious reasons).
The solution is:
Clear[fun]
fun[a_?NumericQ] := Block[{b}, b /. NMinimize[(a^2 + b)^2, {b}][[2]]]
NMaximize[fun[a], {a}]
(Be sure to evaluate Clear[...]
to get rid of the previous definition of fun
!)
This ensures that fun
will only evaluate for numerical arguments, i.e. fun[a]
won't evaluate inside NMaximize
before NMaximize
actually substitutes a number for a
.
And this is also the answer to your specific question: make the inner NMinimize
expression a separate function, and make sure it only evaluates for numerical arguments.
Requested edit
An important related point is: how can we match only numerical quantities using a pattern? One might think of using _Real
(as in the comment below). The problem with this is that it will only match numbers whose Head
is Real
. This excludes integers (such as 1,2,3
), rationals (2/3, 4/5
), constants (such as Pi
or E
), or expressions like Sqrt[2]
.
The only robust solution is using NumericQ[]
(x_ ? NumericQ
in a pattern). NumericQ
will return True
for anything that gives a number when N[]
is applied to it.
There's another related function, NumberQ[]
, which gives True
only for objects with Integer
, Rational
, Real
or Complex
, but not for constant or expressions (Pi
or Sin[3]
).