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. >>
For example, following Jens's answer:
In:=InverseFunction[g][z]
and
In:=q /. Solve[g[q] == z, q][[1]]
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][[1]]
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][[1]]
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 :)
Answer
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[10] Log[100^(Log[x]/Log[10])] *)
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[10] 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).
Comments
Post a Comment