# Plot a functional relation involving a derivative and inverse

I have a function f[x] obtained by solving certain ODE. Thus, it is given as an interpolation function. I need to plot $$\frac{dx}{df}$$ as a function of $$f$$.

Below I will give a simple analytical example just to explain what I mean. Let $$f(x)=\arctan(x).$$ Then we have $$\frac{df}{dx}=\frac{1}{1+x^2},\quad \text{or} \quad \frac{dx}{df}=1+x^2.$$

Now we express $$x$$ in terms of $$f$$, i.e., $$x=\tan(f),$$ and substitute in the equation above: $$\frac{dx}{df}=1+x^2=1+\tan(f)^2.$$

Thus, given $$f(x)=\arctan(x)$$, I would like to get a plot of $$1+\tan(f)^2.$$

One naive way to do it is to parametrize $$f$$ and $$\frac{dx}{df}$$ in terms of $$x$$ and use ParametricPlot

ParametricPlot[{f[x], 1/f'[x]}, {x, -10, 10}, AspectRatio -> 1]


However, for my numerically defined function this does not work very well. Additionally, I would like to get the dependence in a functional form, the best would be again an interpolation function. How can I achieve this, maybe it is possible to formulate the problem as ODE and use NDSolve?

• Can you simply define the inverse function fi = InverseFunction[f] and then plot fi'(y)? Apr 17, 2021 at 20:43
• @Roman I tried that too, it is much slower than ParametricPlot and suffers from similar numerical issues. Apr 17, 2021 at 20:45
• How about adding another ODE to your solver that describes $x(f)$ so that you directly get an interpolating function for $x(f)$ from ODE solving, together with $f(x)$? Apr 17, 2021 at 20:49
• @Roman This is a good idea. In other words you are suggesting to solve $dx(f)/df=1/(df/dx)$ as a preparatory step. I have to think about it... Apr 17, 2021 at 20:53
• For NDSolve, the dependent variables have to be functions of the same independent variable. So you cannot solve for both f(x) and x(f) at the same time as @Roman suggested. Apr 18, 2021 at 12:46

Just the same idea in How to roll a graph on the y-axis Edition 2.

Assume that the inverse function of f is g ,then f and g satisfy the equation f'[g[y]]*g'[y]==1

h[x_] := 1/(1 + x^2);
sol1 = NDSolve[{f'[x] == h[x], f[1] == π/4}, {f}, {x, -10, 10}];
sol2 = NDSolve[{h[g[y]]*g'[y] == 1, g[π/4] == 1}, {g}, {y, -1.57,
1.57}];
Show[Plot[{f[x] /. First@sol1}, {x, -10, 10}, PlotStyle -> Red,
AspectRatio -> Automatic],
Plot[g[y] /. First@sol2, {y, -1.57, 1.57}], PlotRange -> 5]

(* compare the result and the original post. *)

ff[x_] := ArcTan[x];
ParametricPlot[{ff[x], 1/ff'[x]}, {x, -6, 6}, AspectRatio -> 1,
PlotStyle -> {Opacity[.3], Red, Thickness[.02]}];
Plot[{g'[y] /. First[sol2]}, {y, -1.57, 1.57}, AspectRatio -> 1]
Show[%%, %]


You can more or less directly invert the interpolation table. (I may have given this answer before, but I cannot find it.) You can improve accuracy by specifying derivative values, if you have them. One needs strict monotonicity (f'[x] is nonzero and does not change sign).

Example: NDSolve by default returns an order-3 interpolation.

ode = {y'[x] == Cos[x]^2 + y[x] Sin[y[x]]^2, y[0] == 0};

ff = NDSolveValue[ode, y, {x, 0, 10}];


Order-3 inverse:

With[{
x = Flatten@ff@"Grid",
y = ff["ValuesOnGrid"],
dy = ff'["ValuesOnGrid"]
},
iff = Interpolation[Transpose@{List /@ y, x, 1/dy}]
]

(* error *)
ParametricPlot[{{ff[x], iff@ff[x] - x // RealExponent}}, {x, 0, 10},
PlotPoints -> 100]


Order-5 inverse: The second derivative of ff is a continuous, piecewise-linear interpolation. Using the second derivative values improves the accuracy slightly.

With[{
x = Flatten@ff@"Grid",
y = ff["ValuesOnGrid"],
dy = ff'["ValuesOnGrid"],
ddy = ff''["ValuesOnGrid"]
},
iff = Interpolation[Transpose@{List /@ y, x, 1/dy, -ddy/dy^3}]
]

ParametricPlot[{{ff[x], iff@ff[x] - x // RealExponent}},
{x, 0, 10}, PlotPoints -> 100]


If you add InterpolationOrder -> All to NDSolve, the accuracy improves slightly for order 5 and above, because the higher-order derivatives are more accurate in both ff and iff. The gain is minimal and diminishes as the order increases, however.

• Nice approach. In this way there is no need for NDSolve for the inverse. Apr 18, 2021 at 16:49