# How to take the derivative w.r.t. an arbitrary function?

EDIT: The answer posted by @Jens works for built-in functions only. However I'm starting to wonder if this is related to my Mathematica install somehow. I have version 7. Here is an example in the Mathematica documentation center that implies that if I ask InverseFunction[] to find the inverse of a non-built-in pure function, it will be able to. However, as a test I tried to duplicate the result:

The documentation center gives

In:= InverseFunction[(a # + b)/(c # + d) &]

Out:= (-b+d#1)/(a-c#1) &.

Using the exact same input, I get

Out:= InverseFunction[(a # + b)/(c # + d) &],

which is just the inputted command. :\

The documentation center is talking about version 9. Is there some fundamental difference in how versions 7 and 9 use InverseFunction? Is there any workaround?

I've also tried to use other definitions other than InverseFunction[], such as Solve[]...but in that case Solve[] uses inverse functions to find the solution (as evinced by the message I get:

InverseFunction::ifun: Inverse functions are being used. Values may be lost for multivalued inverses. >>

In:=InverseFunction[g][z] and

In:=q /. Solve[g[q] == z, q][]

both give the same answer, $g^{(-1)}[z]$. If you replace "g" with "Log" or the head of any other built-in function, they give the same answer; for example,

In:=InverseFunction[Log][z] and

In:=q /. Solve[Log[q] == z, q][]

give an answer of $e^z$, which is correct. But while the function using Solve can deal with non-built-in functions, e.g.

In:=q /. Solve[Log[q] == z, q][]

Out:=10^z,

which is of course the right answer. The problem is that when trying to implement this as a workaround based on Jens's solution, it hangs up on the same error for some reason, namely that it doesn't know what do to with non-built-in functions.

Being relatively inexperienced at programming in Mathematica I'm not sure what other workarounds there may be. It also seems strange that the documentation center's example doesn't work for me, although as I say I think it's probably a version issue. Does anyone have any ideas?

_

I want to be able to take the derivative of one function (of a given variable) w.r.t. a different function (of the same variable), i.e. $\frac{df[x]}{dg[x]}$. I know you can use the chain rule to appropriately recast this into the form $\frac{dh[y]}{dy}$, where $h[y]$ is $f[x]$ evaluated at $x=g^{-1}(y)$, with $g^{-1}$ the inverse function of $g$.

There are a couple semi-related questions already posted, one of which is here, asking about how to take the derivative of the log of an arbitrary function.

I already asked a question about VariationalD (which I initially thought did what I wanted) here. I was referenced to a third question here on the Dt[] command, but I can't figure out how to get what I want from there, either.

In messing around with D[] and Dt[], I have found that, weirdly, D[] will actually do this for some special cases. For example,

In:= D[Log[x],Log[x]]

Out:= 1

and

In:= D[Log[x]^2,Log[x]]

Out:= 2Log[x].

However, commands such as D[Log[x^2],Log[x]] and D[x,Log[x]] return zero. Dt[], meanwhile, heads in the right direction, for example:

In:= Dt[Log[x^2],Log[x]]

Out:= 2 Dt[x,Log[x]]/x.

This is correct except that I don't know how to make it evaluate, even though I'm sure Mathematica can handle inverting a function to use the chain rule.

I don't want to use the logarithm function, it's just an example. I want to be able to take the derivative of a fit (with a complicated functional form) to experimental data w.r.t. different (complicated) functions. So while in principle I could hash out the equivalent derivative w.r.t. $x$, I really don't want to :)

• Sorry, but that edit looks to me like a very different question. I answered the original one which is based on symbolic derivatives. Looks like you're now interested in numerical derivatives. – Jens Jun 21 '13 at 21:08
• @Jens Sorry for the confusion - I do want a solution for symbolic derivatives, the edit was to illustrate that there's apparently a related issue in that I can't duplicate the result of the example in the documentation center either (and a little because I'm not fluent in Mma programming). As I mentioned in another comment I had already tried your suggestion of defining an auxiliary function (and tried copy/pasting yours just to see if it works). For some reason it doesn't accept the new function (i.e. I get exactly the same result as if I try without defining log10[x_] := Log[10, x]). – John Hyatt Jun 21 '13 at 21:21

It's just an application of the rules of differentiation, which we can implement by writing our own function:

deriv[f_, g_[x_]] := Module[{z},
Simplify[D[f /. x :> InverseFunction[g][z], z]] /. z :> g[x]
]

deriv[Log[x^2]^2, Log[x]]

(* ==> 4 Log[x^2] *)


The variable x in this call has to be undefined so it doesn't get evaluated to something unintended before the derivative with respect to Log[x] is calculated. Also, this will obviously only work if the function in the second argument actually has an inverse.

To use this deriv method with functions that don't just have a single argument as defined in the pattern above, you could first define an auxiliary function that makes the intended function conform to this pattern. E.g., for the base-10 log:

log10[x_] := Log[10, x]

deriv[Log[x^2]^2, log10[x]]

(* ==> 4 Log Log[100^(Log[x]/Log)] *)


Edit

Since InverseFunction is less reliable in version 7, we can equally well resort to another rule of calculus and do the derivative at x this way:

Clear[deriv2];
deriv2[f_, g_, x_] := Simplify[D[f, x]/D[g, x]]

deriv2[Log[x^2]^2, Log[10, x], x]

(* ==> 4 Log Log[x^2] *)


This is written without the restrictive pattern of the first definition in deriv. Instead, I allow arbitrary expressions f and g but require a third argument that spell out the independent variable x to be used in both expressions. Using FullSimplify, you can verify that this yields the same results as the previous approach when InverseFunction works, but it doesn't actually check for the invertibility of g (which should make it less likely to fail in practice).

• Yep, that does it. I knew there was probably a way to program that function but I'm not very familiar with programming in Mathematica. Much obliged! I still would like to know (purely out of curiosity) why D[] will still evaluate the functions I mentioned above, but not arbitrary functions. I'm surprised Mathematica doesn't have a function built in already that does this; it's not super common, but there are some applications that you want to take this kind of derivative in. – John Hyatt Jun 21 '13 at 19:18
• As soon as I had typed my other response, I tried a function that does have an inverse but can't be evaluated by your deriv[] function. InverseFunction[] acts only on the function head. Looking around a bit it seems that InverseFunction was meant to be used only with built-in functions (but some of those, like Log[10,x] don't work either, because the head on the function, Log, is the natural logarithm. I'm fumbling around trying to make a workaround with Solve[] that is reliable; if I figure it out I will post it. Thanks! – John Hyatt Jun 21 '13 at 20:20
• It should be generalizable. To make your Log[10,x] example work, one could add a HoldAll attribute. But the easiest way is what I just added to my answer: make an auxiliary function to clearly define what your "differentiation variable" is. – Jens Jun 21 '13 at 20:38
• Ah, you replied while I was editing the original post :) Unfortunately I had already tried exactly what you suggest and it doesn't change anything (I put some other information in the edited question, above). – John Hyatt Jun 21 '13 at 20:58