5
$\begingroup$

Edit: Still inexplicably, it was found that in the Plot[] functions, showing a correct curve plot for the expression computing the derivative incorrectly, when 'Evaluate' is replaced with 'Simplify', the remaining incorrect curve is also plotted correctly. An illustrating plot is added at the end.

This question is related to the Mathematica 13 derivative flaw, discussed in the following pages:

  1. Derivative function anomaly in Mathematica v. 13.1 (identified as a DifferenceRoot issue)
  2. A workaround needed to overcome the Derivative function anomaly in Mathematica 13

The issue is further illustrated with an apparent inconsistency, revealed in different plots of the same derivative expression.

The examples, based on the same sample expression, as in the discussions, referenced above, are set as follows:

expr=-x 10^(-x^3); 
exprD=D[expr,{x,n}];
f[x_]:=-x 10^(-x^3);
exprDf=Derivative[n][f][x];

Q3_1

The general derivative expressions above, have been identified as causing a problem, apparently due to DifferenceRoot[]. A summary of the anomalous results is shown below for continuity and information. It illustrates the miscalculated derivatives for $n=0$, when set as a replacement rule for n. Q3_2

The following shows that for $n=1$ all forms of evaluating the derivative produce correct results: Q3_3

The plots of the correct derivative expressions for $n=0$ are shown for reference below with D[expr,{x,0}] and Derivative[0][f][x]: Q3_4

 Plot[Evaluate[{D[expr, {x, 0}], Derivative[0][f][x]}], {x, -1, 1.5}, 
     PlotLegends -> "Expressions"]

Q3_5

The anomalous behaviour takes a different 'shape' when the two expressions, D[expr,{x,n}]/.n->0; and Derivative[n][f][x]/.n->0; are used to plot the corresponding derivatives. Evaluating the derivatives in the following two different ways, both result in the incorrect expression for $n=0$: Q3_6

However, when the same evaluation is done within the Plot[] function, Evaluate[exprD]/.n->0 produces the correct graphical result:

Plot[{Evaluate[exprD] /. n -> 0, Evaluate[exprD /. n -> 0]}, {x, -1, 
  1.5}, PlotLegends -> "Expressions"]

Q3_7

The same 'anomaly' is repeated with the evaluated expressions Derivative[n][f][x]]/.n->0 and [Derivative[n][f][x]/.n->0]. Both produce the incorrect results for $n=0$ as shown below: Q3_8

However, when the same evaluation is done within the Plot[], Evaluate[Derivative[n][f][x]]/.n->0 produces the correct graphical result:

Plot[{Evaluate[Derivative[n][f][x]] /. n -> 0, 
  Evaluate[Derivative[n][f][x] /. n -> 0]}, {x, -1, 1.5}, 
 PlotLegends -> "Expressions"]

Q3_9

Plot[{Evaluate[Derivative[n][f][x]]/.n->0,Simplify[Derivative[n][f][x]/.n->0]},{x,-1,1.5},PlotLegends->"Expressions"]

Q3_10

The question is:

What 'hidden' procedure (order of computation?), implemented with the Plot[] function, apparently circumvents the flaw that shows when computing the 0th derivative with a replacement rule $n->0$?

$\endgroup$
4
  • 1
    $\begingroup$ Your second, third, fourth, fifth, and sixth uses of Evaluate are incorrect (that is, ineffective). You might as well have left them out. $\endgroup$
    – Michael E2
    Commented Nov 17, 2022 at 1:13
  • $\begingroup$ @Michael E2, Deficiencies in my using code and in my explanations are likely. Sorry. I am aware that expressions and plots can be obtained without Evaluate. My question is about inconsistent derivative evaluation, which is unexpectedly 'correct'. The two expressions, preceding the 2nd and 3rd plots produce incorrect derivatives with or without Evaluate. The 'mystery' then is why Plot of the same expressions results in one of the derivative curves being of a correctly computed derivative! $\endgroup$
    – ghogoh
    Commented Nov 17, 2022 at 9:07
  • 1
    $\begingroup$ …Just a suggestion: it's better to make the question shorter, you don't need to illustrate those trivial and expected behaviors, that'll make the question easier to read and more attractive. $\endgroup$
    – xzczd
    Commented Nov 18, 2022 at 2:45
  • $\begingroup$ Then, to close voters: though the question is unnecessarily long, the underlying issue is non-trivial, it's not simple at all. Please see my answer for more details. Vote to reopen. @MichaelE2 $\endgroup$
    – xzczd
    Commented Nov 18, 2022 at 11:19

2 Answers 2

4
$\begingroup$

Three issues here:

  1. You've accidentally found another workaround for the bug of DifferenceRoot discussed in the linked post.

  2. Plot is a function that owns HoldAll attribute.

  3. Though Plot is a function that owns HoldAll attribute, it still evaluates its arguments in a somewhat non-standard way. (This seems to be an undocumented behavior. Not sure if it has been discussed in this site before. )

The following a minimal example illustrating 1st issue:

exprD /. n -> 0 /. x -> 0
(* 2/(3 Log[10]) <- incorrect, caused by the bug of DifferenceRoot *)

exprD /. x -> 0 /. n -> 0
(* 0 <- correct *)

As shown above, if the numeric value of x is substituted into DifferenceRoot[…] before that of n, the bug of DifferenceRoot is circumvented and the desired result is obtained. This is what has happened in Plot (when Evaluate has not involved in):

Plot[exprD /. n -> 0, {x, -1, 1.5}]
(* correct result *)

If the HoldAll attribute is cleared, the output will be incorrect:

ClearAttributes[Plot, HoldAll];

Plot[exprD /. n -> 0, {x, -1, 1.5}]
(* incorrect result *)

SetAttributes[Plot, HoldAll];

The interesting part is 3rd issue. We know that, as mentioned in the document of Evaluate:

Evaluate only overrides HoldFirst etc. attributes when it appears directly as the head of the function argument that would otherwise be held.

In other words, Evaluate only temperally removes the Hold* attribute of the contiguous head. For example:

SetAttributes[fff, HoldAll]
fff[1 + 1 // Evaluate]
(* fff[2] *)

fff@g[1 + 1 // Evaluate]
(* fff[g[Evaluate[1 + 1]]] *)

fff@{1 + 1 // Evaluate}
(* fff[{Evaluate[1 + 1]}] *)

fff@{1 + 1 // Evaluate} "doesn't work" because {} is the shorthand of List, so Evaluate in code like

Plot[{Evaluate[exprD /. n -> 0]}, {x, -1, 1.5}]

should not have any effect in principle, but actually it's not the case. It turns out that Plot is handling List ({}) in a special way: if 1st argument of Plot is a List {}, Evaluate contiguous to this List still breaks the HoldAll attribute of Plot.

Finally, though not directly related, the following is another example showing Plot's special handling for List ({}):

Plot[Table[x^i, {i, 2}], {x, -1, 1}]

list = {x, x^2};
Plot[list, {x, -1, 1}]

In principle 2nd plot should be the same as 1st one i.e. it should not use different color for different curves, but actually it's not the case.

$\endgroup$
1
  • $\begingroup$ Thank you for a clear and elaborate answer (quite educational, too!). While I do try very hard to investigate through reading all I can find in Mathematica Documentation, tutorials and guides, it is never a substitute for the wisdom of practical experience and deep understanding. Very helpful! (I agree that my presentations tend to be somewhat bloated with details, but at my, still not very confident level of using Mathematica, I am just trying to be exhaustive and 'convincing'. Will do a harder redacting in future.) $\endgroup$
    – ghogoh
    Commented Nov 18, 2022 at 10:33
0
$\begingroup$

A workaround using Hold:

Your code that works only inside Plot (i.e. plot is correct but the second line output is incorrect):

expr = -x 10^(-x^3);
exprD = D[expr, {x, n}];
Plot[Evaluate[exprD] /. n -> 0, {x, -1, 1.5}]
exprD/. n -> 0

enter image description here

And the workaround that works in both cases (i.e. plot is correct and correct is also the second line output):

expr = -x 10^(-x^3);
exprD = Hold[D[expr, {x, n}]];
Plot[Evaluate[exprD /. n -> 0 // ReleaseHold], {x, -1, 1.5}]
exprD /. n -> 0 // ReleaseHold

enter image description here

And regarding your question:

What 'hidden' procedure (order of computation?), implemented with the Plot[] function, apparently circumvents the flaw that shows when computing the 0th derivative with a replacement rule n−>0?

I guess that Plot in your code uses D[expr, {x, 0}], i.e. it replaces n with 0 before doing anything else. But why it is doing so I do not know. Maybe in the implementation of Plot there is somewhere used Hold/ReleaseHold like I used.

$\endgroup$
4
  • $\begingroup$ I am aware of possible ways to produce correct plots of the same expressions, intentionally. This is not the question. Please see my response to Michael E2's comment above. I am also aware that built-in functions in Mathematica incorporate procedures, the order of which can lead to one output instead of another. Unfortunately, my knowledge of the subtleties of the software is not that deep. About the Plot function, I can guess as much. The question is what specifically causes the inconsistency demonstrated in my question and how it can be utilised. $\endgroup$
    – ghogoh
    Commented Nov 17, 2022 at 9:31
  • 1
    $\begingroup$ "I guess that Plot in your code uses D[expr, {x, 0}], i.e. it replaces n with 0 before doing anything else. " The guess is not right. See the discussion in my answer. $\endgroup$
    – xzczd
    Commented Nov 18, 2022 at 3:45
  • $\begingroup$ My guess was more about using Hold inside Plot and that turned out to be true by your answer. Hold or HoldAll... the effect is the same $\endgroup$ Commented Nov 18, 2022 at 10:43
  • 1
    $\begingroup$ No, these are 2 different workarounds. Your solution is equivalent to circumventing the bug by avoiding symbolic n i.e. using D[expr, {x, 0}] so the DifferenceRoot is untouched, but in OP's exprD, the DifferenceRoot is already there. Notice your workaround require a modification for the definition of exprD, which is beyond the reach of Plot. $\endgroup$
    – xzczd
    Commented Nov 18, 2022 at 11:40

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.