Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

While answering another question, I stumbled upon a problem I cannot easily resolve. To assign the derivative of a function to another function, typically one can do this with a Set or a SetDelayed:

f[x_]=D[Sin[x],x]
f2[x_]:=Evaluate@D[Sin[x],x]

Both give the same result, since forcing evaluating on a SetDelayedis essentially the same as using Set. However, both can give rise to naming conflicts, i.e.

x=7;
f[x_]=D[Sin[x],x]
f2[x_]:=Evaluate@D[Sin[x],x]

won't work. This bothers me a lot, because the reason I always use SetDelayedis to avoid this (sometimes difficult to find) type of bugs. So I tried to force some kind of local scoping, but until now didn't find a working solution. Using

f3[x_]:=Evaluate[Block[{x},D[Sin[x],x]]]
f4[x_]:=Evaluate[Module[{x},D[Sin[x],x]]]
f5[x_]:=Evaluate[With[{y=x},D[Sin[y],y]]]

doesn't work, because Block and With release the variable too fast and Module renames it locally (as can be seen by doing ?f3, ?f4 or `?f5).

What does work, is using

f6[x_] := With[{y = x}, Evaluate@D[Sin[y], y] /. y -> x]

And it works even when both x and y already have an assigned value. However, if we look at its definition, we get:

?f6
Global`f6
f6[x_]:=With[{y=x},Evaluate[D[Sin[y],y]]/. y->x]

This is not what I want, because now the evaluation is delayed. Whenever my original function (here Sin[x]) is much more complicated, the derivation can take some time. If I need to calculate a lot of values of f6, this will stack up to a huge amount of time.

Any ideas to get a 'name-conflict-safe' derivative assignment which evaluates at its definition?

Thanks!

share|improve this question
2  
You should use Derivative instead of D, e.g. f[x_] := Derivative[1][Sin][x]. See e.g. this answer mathematica.stackexchange.com/questions/5434/… –  Artes Jun 11 '12 at 11:20
    
@Artes: while I second your suggestion to use Derivative (see my answer), I think your example doesn't pre-evaluate the symbolic derivative which I think is what the OP is trying to achieve. –  Albert Retey Jun 11 '12 at 11:26
    
@Artes I don't think this is an exact duplicate as it specifically deals with scoping. –  Mr.Wizard Jun 11 '12 at 11:34
    
@Mr.Wizard Ok, I did not vote to close it, though scoping constructs are unnecessary here. –  Artes Jun 11 '12 at 11:42
add comment

2 Answers

up vote 14 down vote accepted

This might work as you expect and be save even if definitions for x exist:

Block[{x}, f[x_] = D[Sin[x], x];]

I would strongly suggest that you get familiar with Derivative and pure functions if you work with symbolic derivatives, though. This will make your life much easier in the long term. Your example would reduce to:

f = Derivative[1][Sin]

and a more complicated example would also work, e.g.:

f = Derivative[1][Exp[# - Sin[#]] &]

or even:

g[x_] := Exp[x^2 + Sin[x]];
gprime = Derivative[1][g]
share|improve this answer
    
Beat me to it - +1. –  Leonid Shifrin Jun 11 '12 at 11:26
    
@Leonid: pure luck :-), thanks anyway –  Albert Retey Jun 11 '12 at 11:28
    
Thanks for pointing that out. But what is then the formal difference between Dand Derivative? Is it only in the way they are used? It looks like they are doing the same thing. –  freddieknets Jun 11 '12 at 11:58
    
@freddieknets: yes, the way they are used is the main difference, but they are also not doing the exactly same thing: Derivative works with functions and the position in arguments while D works with expressions and the name of symbols. –  Albert Retey Jun 11 '12 at 12:03
add comment

You could use Formal Symbols:

f[\[FormalX]_] = D[Sin[\[FormalX]], \[FormalX]]

Which looks like this in the Notebook:

Mathematica graphics

Formal Symbols are entered with Esc$xEsc where x is any regular letter.

Formal Symbols cannot be assigned a global value, avoiding collisions:

Set::wrsym: Symbol [FormalX] is Protected. >>


I also wrote a function localSet to answer a prior question which you could use:

x = 1.23;

localSet[ f[x_], D[Sin[x],x] ]

DownValues[f]
{HoldPattern[f[x_]] :> Cos[x]}
share|improve this answer
    
Good point, I keep forgetting that these exist (I think the were introduced with version 7?). They seem to be made for such situations and need less explanation than other approaches. I don't have any indication that there would be problems, but do you have experience with using them in a larger piece of code? –  Albert Retey Jun 11 '12 at 11:42
    
@Albert yes regarding larger code, but nothing large scale. There can still be collisions if you don't think through what you're doing in some cases, but they help tremendously, and are IMHO quite elegant in a case like this, when otherwise you have to jump through hoops to get a "safe" evaluation of the RHS. –  Mr.Wizard Jun 11 '12 at 11:46
    
+1 A while ago I encountered these Formal Symbols, but didn't see any use for them until now. Thanks! –  freddieknets Jun 11 '12 at 11:52
    
@Mr.Wizard: the potential collisions are what I was concerned about. On the other hand such problems often don't even arise in practice as it would probably mean you really need to make abuse of those formal parameters to create any problems (like e.g. Unprotect them). Thanks for mentioning them, anyway. –  Albert Retey Jun 11 '12 at 11:57
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.