0

when I use contourplot, the system will simplify the expression first with its parameters holded. However some expressions can not be simplified first without inputting parameters, for example,

g[x_, y_, z_] := x + y + z;
f[x_, y_] := z /. FindRoot[g[x, y, z], {z, 0}];
ContourPlot[f[x, y] == 1, {x, -1, 1}, {y, -1, 1}]

will give warning informations

FindRoot::nlnum: The function value {0. +x+y} is not a list of numbers with dimensions {1} at {z} = {0.}. >>
ReplaceAll::reps: {FindRoot[g[x,y,z],{z,0}]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. >>
General::stop: Further output of FindRoot::nlnum will be suppressed during this calculation. >>
ReplaceAll::reps: {FindRoot[g[x,y,z],{z,0}]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. >>
General::stop: Further output of ReplaceAll::reps will be suppressed during this calculation. >>

whereas the output plot is right

enter image description here

but the following code will not generate warning information

g[x_, y_, z_] := x + y + z;
f[x_, y_] := z /. FindRoot[g[x, y, z], {z, 0}];
ContourPlot[f[x, y], {x, -1, 1}, {y, -1, 1}]

Question: how can I use the first example to generate the right plot without warning?Thanks a lot!

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
schwang
  • 21
  • 4

2 Answers2

2

You need to restrict your function defintion to numeric values:

g[x_, y_, z_] := x + y + z;
f[x_?NumericQ, y_?NumericQ] := z /. FindRoot[g[x, y, z], {z, 0}];
ContourPlot[f[x, y] == 1, {x, -1, 1}, {y, -1, 1}]

Otherwise Mathematica will consider f as an analytical function and will use as such. But FindRoot only works numerically.

Edit: Of course you need to clear your function defintion before it can work.

Clear[f]

We can have a function that is defined for analytical values and the same time for numerical values.

Example to see what can happen:

h[x_] := x^4;
h[x_?NumericQ] := x^2;
h[a] /. a -> 2
h[2]

yields

16

4

You can check the function definitions by using ?functionName (here ?f)

Philipp
  • 641
  • 3
  • 8
  • Have you restarted the kernel? You may have the previous definitions of f still loaded. f[x_,y_] and f[x_?NumericQ, y_?NumericQ] are independent signatures so defining the second does not overwrite the first. – Ymareth Jan 21 '15 at 11:28
  • Restarting the kernel is not neccessary. Cleaning the function definitions suffices. BTW: The comment we are talking about is vanished by now. – Philipp Jan 21 '15 at 11:31
  • Oh,it works.Thank you so much. – schwang Jan 21 '15 at 11:31
2

While I think the basic answer to this question has been given before in User-defined functions, numerical approximation, and NumericQ and its linked questions, the underlying mathematics problem has a different approach. The ContourPlot of $f(x,y)=a$ where $f$ is defined implicitly by $g(x, y, f(x, y)) = 0$ may be obtained by plotting the contour $g(x, y, a) = 0$.

There is a significant difference in these approaches. ContourPlot will plot all functions $f$ defined by $g(x, y, f(x, y)) = 0$ over the plot domain. FindRoot will find just one value for a given input $(x,y)$; moreover, the values are not guaranteed to lie on the same branch and the plot may appear discontinuous, nor is a found root guaranteed to be the root closest to the starting point passed to FindRoot.

For the OP's example problem, the code would be

ContourPlot[g[x, y, 1] == 0, {x, -1, 1}, {y, -1, 1}]

An example to chosen to force the failure of FindRoot

g[x_, y_, z_] := x + y + Sin[z] + (z - 1) Sin[1/((z - 1)^2 + 10^-6)]

Mathematica graphics

Michael E2
  • 235,386
  • 17
  • 334
  • 747