3
$\begingroup$

I am having trouble with a numerical exercise. Here's a simplified version of my problem.

I define two functions to find the solution to two constrained maximization problems:

g[a_,b_,x_]:=NArgMax[{h2[a,b,x,y], CONSTRAINT[a,b,x,y]},{y}][[1]]
f[a_,b_,y_]:=NArgMax[{h1[a,b,x,y], CONSTRAINT[a,b,x,y]},{x}][[1]]

In the above definitions h1(.) and h2(.) are "well-behaved" objective functions, "a" and "b" are parameters and CONSTRAINT[a,b,x,y] is a given inequality involving the parameters and choice variables.

With these functions, I would like to find a fixed point, say, xstar:

FindRoot[{xstar==f[a, b, g[a,b,xstar] ]}, {xstar, 0}]

When I try to run FindRoot with actual numbers for "a" and "b" I get an error saying that the constraint in the maximization problem is not valid. I think the problem is that it attempts to make a symbolic evaluation. I hence tried defining the functions as g[a_,b_,x_?NumberQ] and f[a_,b_,x_?NumberQ], but it didn't work.

However, when I defined:

G[x_?NumberQ]:=g[a,b,x]
F[y_?NumberQ]:=f[a,b,y]

and then fixed values for the parameters by setting them equal to a given number (e.g. a=b=0.1),then it did work.

It seems then that I am doing something wrong when I use ?NumberQ in the original function to avoid symbolic evaluation... Any ideas on why it is wrong and how to solve it?

I would like to make a plot for different values of "a" and "b", so running the simulations one by one (as in the solution I mention above that works, by redefining the function only in terms of one variable) is extremely inefficient... and I'm sure there's a smarter way of doing it ! ;)

Here is a complete example using the above notation:

h1[a_, b_, x_, y_] := PDF[BinormalDistribution[{a, b}, {1, 1}, .5], {x, y}]
h2[a_, b_, x_, y_] := PDF[BinormalDistribution[{a, b}, {.5, .5}, .7], {x, y}]
CONSTRAINT[a_, b_, x_, y_] := CDF[BinormalDistribution[{a, b}, {1, 1}, .5], {x, y}]
g[a_, b_, x_] := NArgMax[{h2[a, b, x, y], CONSTRAINT[a, b, x, y] < .5}, {y}][[1]]
f[a_, b_, y_] := NArgMax[{h1[a, b, x, y], CONSTRAINT[a, b, x, y] < .5}, {x}][[1]]

FindRoot[{xstar == f[1, 1, g[1, 1, xstar]]}, {xstar, 0}]
$\endgroup$
5
  • $\begingroup$ What happens if you replace NumberQ with NumericQ? $\endgroup$ Sep 10, 2012 at 10:57
  • $\begingroup$ ...same error message $\endgroup$
    – OO_SE
    Sep 10, 2012 at 11:10
  • $\begingroup$ The problem is your CONSTRAINT because functions like NArgMax, FindMinimum, ... really like to have explicit (in)equalities there. Can your CONSTRAINS be evaluated without numerical values? Then NArgMax[Evaluate@{h2[a,b,x,y], CONSTRAINT[a,b,x,y]},{y}] might help. $\endgroup$
    – halirutan
    Sep 10, 2012 at 11:25
  • 3
    $\begingroup$ @EOO Can you maybe give a small, complete example? $\endgroup$
    – halirutan
    Sep 10, 2012 at 11:44
  • $\begingroup$ Thanks, yes; the problem is that the constraint is nonalgebraic. I edited the question above and included a complete example at the end. $\endgroup$
    – OO_SE
    Sep 10, 2012 at 13:44

1 Answer 1

3
$\begingroup$

As we found out in the comments, your original error message came from CONSTRAINT not being an (in)equality. After changing this and adding ?NumericQ to your functions, you can easily (but slowly) create a table of your roots depending on a

h1[a_, b_, x_, y_] := PDF[BinormalDistribution[{a, b}, {1, 1}, .5], {x, y}]
h2[a_, b_, x_, y_] := PDF[BinormalDistribution[{a, b}, {.5, .5}, .7], {x, y}]
CONSTRAINT[a_, b_, x_, y_] := CDF[BinormalDistribution[{a, b}, {1, 1}, .5], {x, y}]
g[a_, b_, x_?NumericQ] := NArgMax[{h2[a, b, x, y], CONSTRAINT[a, b, x, y] < .5}, {y}][[1]]
f[a_, b_, y_?NumericQ] := NArgMax[{h1[a, b, x, y], CONSTRAINT[a, b, x, y] < .5}, {x}][[1]]

data = Table[{a, xstar /. FindRoot[{xstar == f[a, 1, g[a, 1, xstar]]}, 
  {xstar, 0}]}, {a, .5, 1, .1}];
ListLinePlot[data]

Mathematica graphics

As your question was about NumberQ, let me point out that it makes in this example no difference whether you use NumberQ or NumericQ. One important thing about NumberQ is that for instance NumberQ[Pi] returns false. So if you define a numerical function with a NumberQ pattern, someone who calls your function with Pi, Sqrt[2], etc will not get an answer. This is usually not wanted.

What you want to say in most cases is the function can be used for arguments which can be transformed with N into a numerical expression. This is what NumericQ does and therefore I would suggest to stick with it.

$\endgroup$
2
  • $\begingroup$ Thanks. I had tried what you suggest and it didn't work --in fact, when I copy/pasted your code and ran it, it didn't work at first... It turns out (I just realize) that the introduction of ?NumberQ in the definition of the function has to be done on a clean function (it doesn't replace an existing definition). In the end, the solution is indeed to use f[a_, b_, x_?NumericQ] BUT clearing f[] beforehand (don't know if this is obvious but it cost me a lot of time). $\endgroup$
    – OO_SE
    Sep 10, 2012 at 15:19
  • $\begingroup$ @EOO It's ok, that you missed it. A common mistake and a lot people (including me) stumbled over this several times. The function definition is not overwritten, because you changed the call pattern. You could have checked ??f to see all definitions. $\endgroup$
    – halirutan
    Sep 10, 2012 at 15:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.