14
$\begingroup$

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?

$\endgroup$
4
  • 2
    $\begingroup$ 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/… $\endgroup$
    – Artes
    Jun 11, 2012 at 11:20
  • $\begingroup$ @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. $\endgroup$ Jun 11, 2012 at 11:26
  • $\begingroup$ @Artes I don't think this is an exact duplicate as it specifically deals with scoping. $\endgroup$
    – Mr.Wizard
    Jun 11, 2012 at 11:34
  • $\begingroup$ @Mr.Wizard Ok, I did not vote to close it, though scoping constructs are unnecessary here. $\endgroup$
    – Artes
    Jun 11, 2012 at 11:42

2 Answers 2

20
$\begingroup$

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]
$\endgroup$
6
  • $\begingroup$ Beat me to it - +1. $\endgroup$ Jun 11, 2012 at 11:26
  • $\begingroup$ @Leonid: pure luck :-), thanks anyway $\endgroup$ Jun 11, 2012 at 11:28
  • 1
    $\begingroup$ 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. $\endgroup$ Jun 11, 2012 at 11:58
  • $\begingroup$ @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. $\endgroup$ Jun 11, 2012 at 12:03
  • $\begingroup$ What would be the solution if now f or g is a multivariate function such as f[x,y,z] for which we only want to derive partially, say, y $\endgroup$
    – mwoua
    Apr 24, 2018 at 10:38
13
$\begingroup$

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]}
$\endgroup$
8
  • $\begingroup$ 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? $\endgroup$ Jun 11, 2012 at 11:42
  • $\begingroup$ @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. $\endgroup$
    – Mr.Wizard
    Jun 11, 2012 at 11:46
  • $\begingroup$ +1 A while ago I encountered these Formal Symbols, but didn't see any use for them until now. Thanks! $\endgroup$ Jun 11, 2012 at 11:52
  • $\begingroup$ @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. $\endgroup$ Jun 11, 2012 at 11:57
  • 1
    $\begingroup$ Mr.Wizard, @Albert Just for avoiding some pitfalls: not all formal symbols are protected and are in the System` context (this is by design), cf. \[FormalPhi] vs. \[FormalDelta]. This definitely leaves room for potential collision. $\endgroup$ Dec 2, 2015 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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