6
$\begingroup$

Let's say I have a function

f1 = #^2 &;

I want to calculate its derivative, perform some manipulations and make the result a pure function. I try

D[f1[x], x] (*Function[{x}, \!\(
\*SubscriptBox[\(∂\), \(x\)]\(f1[x]\)\)]*)

So the derivative didn't evaluate. I try forcing it

Function[{x}, Evaluate@D[f1[x], x]] (*Function[{x}, 2 x]*)

And it works. But let's say I want to additionally manipulate the derivative inside the function so I try

Function[{x}, N@Evaluate@D[f1[x], x]] (*Function[{x}, N[Evaluate[\!\(
\*SubscriptBox[\(∂\), \(x\)]\(f1[x]\)\)]]]*)

And this doesn't work anymore. Any suggestions on how to fix this problem? I also obviously lack understanding of the evaluation logic of such cases, so I will be grateful for explanations or references.

$\endgroup$
0

4 Answers 4

5
$\begingroup$

Let's examine the problem as given. I will consider it as a general code rewriting problem. We have an expression of the form

h[.., f[ Evaluate[g[x]] ],..]     (* or more generally... *)
h[.., f[ Evaluate[g[x]], y],..]  (* etc. *)

where h is a HoldAll function and we'd like to evaluate g[x] but not f[] to get

h[.., f[g0],..]      (* or *)
h[.., f[g0, y],..]

where g0 = g[x]. Evaluate does not work this way, because Evaluate[expr] is evaluated only when it appears as an argument of h; it is not evaluated when it appears in an argument at a lower level.

For Evaluate to do its work, it needs to appear one level higher around f:

h[.., Evaluate[f[g[x],..]],..]

But that yields

h[.., f0,..]

where f0 = f[g[x],..], which is different that what we said we wanted. For instance, in this example, N[] has no effect:

f2 = #^2/2 &;
Function[{x}, Evaluate@N@D[f2[x], x]]
(*  Function[{x}, x]  *)

One way to get the code rewritten is to extend the semantics of Evaluate with a replacement rule:

h[.., f[Evaluate[g[x]],..],..] /.
 e_Evaluate :> RuleCondition[e, True]

The OP's example:

f1 = #^2 &;
Function[{x}, N@Evaluate@D[f1[x], x]] /.
 e_Evaluate :> RuleCondition[e, True]
(*  Function[{x}, N[2 x]]  *)

Note that the rule will result in all expressions Evaluate[expr] to be evaluated, even if an expression appears in HoldComplete or a function that has the attribute HoldAllComplete.

$\endgroup$
2
  • $\begingroup$ Thank you for your answer. It is not very clear for me where is HoldAll applied in the initial example. Also, I cannot find documentation for RuleCondition, is there anywhere I can read about it? $\endgroup$
    – Ihor
    Commented Feb 11, 2020 at 7:59
  • 1
    $\begingroup$ @Ihor You're welcome. HoldAll is found in Attributes@Function; in the general scheme at the beginning of the answer, h represents Function in your question. I found out about RuleCondition here: mathematica.stackexchange.com/a/29319/4999 $\endgroup$
    – Michael E2
    Commented Feb 11, 2020 at 12:55
7
$\begingroup$
f1 = #^2 &;

f1' gives a pure function:

df1 = f1'

2 #1 &

df1[2]

4

Alternatively, you can use Derivative:

df1b = Derivative[1] @ f1

2 #1 &

df1b[3]

6

Re "to additionally manipulate the derivative inside the function", you can use Composition to wrap df1 with desired manipulations:

ndf1 = N@*(f1')

N@*(2 #1 &)

ndf1[2]

4.

$\endgroup$
2
  • $\begingroup$ Thank you for your answer! Do you know why in the specific case I attempted it didn't work? $\endgroup$
    – Ihor
    Commented Feb 6, 2020 at 10:47
  • 3
    $\begingroup$ @Ihor, 1. D[f1[x], x] does give 2x (version 11.3.0 - Windows 10) (maybe you need to use ClearAll[f1] before line that defines f1) and 2. Using Evaluate @ N @ D[f1[x],x] instead of N @ Evaluate @ D[f1[x],x] works (This has to do with the HoldAll attribute of Function; it does not evaluate its arguments unless it sees Evaluate as the head of the argument) $\endgroup$
    – kglr
    Commented Feb 6, 2020 at 10:59
2
$\begingroup$

This behavior is due in this specific case to NHoldAll. Under Scope we find both Derivative and Slot, among many others which also have this attribute.

$\endgroup$
2
  • $\begingroup$ Thank you for your answer. But it seems not to be the reason because, for example, Function[{x}, Sin@Evaluate[D[f1[x], x]]] also doesn't evaluate. $\endgroup$
    – Ihor
    Commented Feb 6, 2020 at 10:44
  • 1
    $\begingroup$ @Ihor that isn't N, though :) I made sure to specify in this specific case, but you are correct. It seems to me, here, now, that you are not applying the functions after you define them, as both your examples work once you apply them to something like x. The initial example gives 2. x and this most recent one gives Sin[2 x], when you apply it to x. $\endgroup$ Commented Feb 6, 2020 at 10:57
2
$\begingroup$

Try

f1 = #^2 &;

derivative

f1s = Function[x, f1'[x] // Evaluate]
f1s[u]    (*2 u*)

or

F1s[u_] := f1'[u]
$\endgroup$

Your Answer

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

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