# Given an implicit solution, how to plot transformation of this implicit solution?

I have a function, which gives an implicit solution of a variable $y$ as a function of $x$. Moreover, I have a function $f$ which depends on $y$. How to plot a ratio of $f/y$, given that $y$ is only given in an implicit form?

Edit

Let me be more specific. First, I have a polynomial $G(y,x)=0$, which defines implicitly $y$ as function of $x$, let's call it $y=g(x)$. Second, I have a function $f(y)$. I want to plot a ratio $f(y)/y$ as a function of $x$ or, using $y=(g(x))$, $f(g(x))/g(x)$. How to plot it given that $y=g(x)$ is given implicitly by a polynomial?

-
If you show a simple version of the problem (with code), I'm sure someone can help. – bill s Oct 15 '13 at 23:01
I have formatted your questions. Have you read this? – Hector Oct 16 '13 at 5:09

Let us say that $y$ is implicitly defined by $\sin(\sqrt{3 x^2 + 2 y})=1/2$ and that $f(x,y)=x^2 + y^2$. The places where $x$ and $y$ satisfy the first equation can be found by

ContourPlot[Sin[Sqrt[3 x^2 + 2 y]] == .5, {x, -5, 5}, {y, -5, 5}]


The following code isolates narrow bands from the 3D graph around the region where $\sin(\sqrt{3 x^2 + 2 y})=1/2$:

f[x_, y_] := x^2 + y^2;
Plot3D[f[x, y]/y, {x, -5, 5}, {y, -5, 5},
RegionFunction -> Function[{x, y},
If[3 x^2 + 2 y >= 0, -0.1 < Sin[Sqrt[3 x^2 + 2 y]] - .5 < 0.1, False]],
PlotPoints -> 80, Filling -> Axis]


Update

Using Solve might not give you the correct picture in cases where $G(x,y)=0$ does not define a function. Implicit functions might not be functions in the strict meaning of that word. Consider for example $G(x,y)=3 (x - y)^3 - (x - y) (x + 3 y) + (x + 3 y)^2 + (x - y)^5 (x + 3 y)^2 - 70$.

The following code shows in red the function obtained with Solve and the output of ContourPlot in blue.

G = 3 (x - y)^3 - (x - y) (x + 3 y) + (x + 3 y)^2 + (x - y)^5 (x + 3 y)^2 == 70;
s = Solve[G, y][[1, 1, 2]];
g1 = Plot[s, {x, -10, 10}, PlotRange -> {-3, 3}, PlotStyle -> {Thick, Red}];
g2 = ContourPlot[3 (x - y)^3 - (x - y) (x + 3 y) + (x +
3 y)^2 + (x - y)^5 (x + 3 y)^2 == 70, {x, -10, 10}, {y, -3, 3},
ContourStyle -> {Thick, Blue}];
Show[{g1, g2}]


-
thanks but I think I should have been more specific in my question, see the edited comment and please tell me what you think. – bbq Oct 16 '13 at 5:03
@bbq: I think my post still answers your question. In general, the subset of the plane $(x,y)$ that satisfies $y=g(x)$ will not be a straight line. Try ContourPlot[ x^2 + 3 y^3 - x y + y^5 x^2 == 70, {x, -10, 10}, {y, -3, 3}] – Hector Oct 16 '13 at 5:15
that helps a lot, thanks one more question: what if G(y;x) in my example is so complicated that Solve cannot help (i.e. the message comes up that the equation cannot be solved algebraically)? – bbq Oct 16 '13 at 13:58
@bbq: You can still plot the contour even if the equation cannot be solved. – Hector Oct 16 '13 at 16:24

I propose a general solution.

You need to plot

$$G(x,{\cal F}(y))=0$$

where ${\cal F}(y)$ is inverse of $f(y)/y$. In general there is no formula for ${\cal F}(y)$. Moreover, it is a multivalued function.

Let us fight with it.

To be specific, I use Rahul Narain's example.

g[x_, y_] := Sin[Sqrt[2 x^2 + 2 y]] - 1/2;
fun[y_] := Sin[y^2]/y;


Here fun is $f(y)/y$ not $f(y)$.

Plot[fun[y], {y, -10, 10}]


Inverse of this function has numerous branches. Let us split this function by monotonic ranges.

X = Range[-10, 10, 0.003];
tfun = fun[X];
spl = #[[All, 1 ;; 2]] & /@
SplitBy[Transpose@{Most[tfun], Most[X], Differences[tfun]}, UnitStep@Last[#] &];

ListLinePlot[spl]


Now ${\cal F}(y)$ can be defined as a table of interpolations

int = {Interpolation[#][y], Min@#[[All, 1]], Max@#[[All, 1]]} & /@ spl;


Finally, we have

Show[ContourPlot[Evaluate[g[x, #1] == 0], {x, -5, 5}, {y, #2, #3},
PlotPoints -> {60, 5}, MaxRecursion -> 3, AspectRatio -> 1/3,
ImageSize -> 500] & @@@ int, PlotRange -> {-1, 1}]


-

@Hector's answer tells you the Right Way (in my opinion) to plot the points with $G(x,y)=0$:

g[x_, y_] := Sin[Sqrt[2 x^2 + 2 y]] - 1/2
plot = ContourPlot[g[x, y] == 0, {x, -5, 5}, {y, -5, 5}]


Now, if we want to plot $f(y)/y$ against $x$ instead, a simple way would be to just replace the $y$-coordinates of the plotted points with $f(y)/y$. (We use Normal to turn the GraphicsComplex into a collection of ordinary primitives such as Line.)

f[y_] := Sin[y^2]
Normal[plot] /. Line[pts_] :> Line[With[{x = #[[1]], y = #[[2]]}, {x, f[y]/y}] & /@ pts]


One limitation of this approach is that it loses the points whose $y$-coordinates go outside the plot range, even if $f(y)/y$ would be inside the plot. I think if you started with a contour plot of $g(x,\tan(t))$ instead, with $t\in[-\pi/2,\pi/2]$, you could in principle cover the whole range of $y$ in a single plot.

Another problem is while ContourPlot tries to do a nice adaptive sampling of the plot, it doesn't know you're going to postprocess it afterwards. So if $f(y)/y$ varies rapidly, you're likely to get jaggy artifacts in the plot due to undersampling.

P.S. I took $G(x,y)$ from Hector's answer and $f(y)$ from Alexei's, because Hector's $f$ depended on $x$ which I think is not what the question asks for.

-

Let us make it within an example. Let us assume that your polynomial equation for y is like this:

G = x^5 + y^5 - x^2*y^2 - 1 == 0;


It can be easily solved:

sl=Solve[G,y][[1]]


This is the solution:

{y -> Root[-1 + x^5 - x^2 #1^2 + #1^5 &, 1]}


You may (and should look at it):

Plot[y /. sl[[1]], {x, 0, 2}, PlotRange -> All]


That' s how it should look like:

Now along the same line one may plot any function of y. Let us assume that your function f(y)=sin(y^2). Then you simply substitute sin(y^2)/y instead of y into the previous operator:

Plot[Sin[y^2]/y /. sl[[1]], {x, 0, 2 \[Pi]}, PlotRange -> All]


That's how it looks like:

Later edit: I will address here your question asked in comments. Namely, what to do, if you cannot get any result by using the Solve operator, as I used in my answer above.

In the answer I will use the same function G(x,y) as in my answer above, but I will treat it, as if the Solve operator gives no answer.

In such a case one can apply the FindRoot operator. Sometimes it may be a bit tricky, since it is necessary to guess a good starting point (I will come to this later), but it is worth trying. Indeed, this:

    G = x^5 + y^5 - x^2*y^2 - 1 == 0;
Assuming[{x = 1.5}, FindRoot[G, {y, -1.}]]


brings a numerical result:

{y -> -1.25148}


Let us try to look for the function sin(y^2)/y in the interval 1<=x<=6.

A. This

lst = Table[{x, FindRoot[G, {y, -1.}][[1, 2]]}, {x, 1, 6, 0.05}];


makes the list {x,y} in the interval 1<=x<=6.

B. This:

lst1 = lst /. {x_, y_} -> {x, Sin[y^2]/y};


makes the list {x, Sin[y^2]/y}

C. And here:

    Show[{ListPlot[lst1, AxesLabel -> {Style["x", 16, Italic],Style[Sin[y^2]/y // TraditionalForm, Italic, 16]}],
ListLinePlot[lst1, PlotStyle -> Red]}]


it is plotted. That is how it looks like:

I often use this approach myself, and one problem that here might come up is the problem that I used the same starting point in the whole interval of x from 1 to 6. In the present case the starting point y0=-1 worked everywhere, not interfering with the convergence. However, generally it may. Here it is exactly the place, where the science turns into art. If it happens, you might try to guess a better starting point. Otherwise, you may try to make the list by concatenation of several lists, each obtained by its own starting point. Have fun!

-
that helps a lot, thanks one more question: what if G(y;x) in my example is so complicated that Solve cannot help (i.e. the message comes up that the equation cannot be solved algebraically)? – bbq Oct 16 '13 at 13:58