Skip to main content

equation solving - 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. >>


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

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...