3
$\begingroup$

Have a look at the following definition

Y[q_, w_ /; w < 0] := 0
Y[q_, w_] := w

The function Y is zero for negative w. It is indeed so when we plot it

Plot[Y[0.5, e], {e, -2, -1}]

Now we integrate zero and get -1.5

NIntegrate[Y[0.5, e], {e, -2, -1}]

What is wrong here? What command Plotor NIntegrate behave correctly according to the MA syntax?

According to the Wolfram Language Documentation

  • The Wolfram System tries to put specific definitions before more general definitions.
  • Whenever the appropriate ordering is not clear, the Wolfram System stores rules in the order you give them.

In this particular case we can check that the result is indeed zero.

Y[0.5,-1]
(* 0 *)
$\endgroup$

2 Answers 2

5
$\begingroup$

This is a matter of evaluation order. First of all, notice under your definition, any w that doesn't satisfy w < 0 will match the second definition, for example

Clear[e]
Y[0.5, e]
(* e *)

Then why does Plot choose the first definition of Y? Because, as mentioned in Details and Options section of document of Plot:

Plot has attribute HoldAll and evaluates f only after assigning specific numerical values to x.

Then why does NIntegrate behave differently? It owns attribute HoldAll, too! That's because owning HoldAll doesn't necessarily mean the argument will never be evaluated. Actually NIntegrate evaluates the arguments once they're Blocked. This is also mentioned in the document (in Details and Options section of document of NIntegrate):

NIntegrate first localizes the values of all variables, then evaluates f with the variables being symbolic, and then repeatedly evaluates the result numerically.

This behavior has been discussed in the following posts, too:

NIntegrate evaluates its 1st argument while it has the attribute HoldAll?

Numerical Laplace transform error

Finally, as already mentioned by Ulrich Neumann, one can make Plot behave like NIntegrate by adding the undocumented option Evaluated:

Plot[Y[0.5, e], {e, -2, -1}, Evaluated -> True]

Or simply Evaluate:

Plot[Y[0.5, e] // Evaluate, {e, -2, -1}]

Is it possible to make NIntegrate behave like Plot? Sadly Evaluated isn't an option of NIntegrate, but we can make use of NumericQ:

help[e_?NumericQ] := Y[0.5, e]
NIntegrate[help[e], {e, -2, -1}]

BTW, when defining piecewise functions, it's not a good idea to use Condition (/;). It doesn't work well with all the functions for simplification (Simplify, etc.), it's not suitable for numeric evaluation, either. (Because it's based on pattern matching. ) Piecewise is a much better choice. (Don't forget you can create it with EscpwEsc. )

$\endgroup$
2
  • $\begingroup$ I do not completely understand. You are saying that the observed result on NIntegrate is actually coming from the symbolic evaluation. But now let us change to NIntegrate[Y[0.5, -Exp[Exp[Exp[e]]]], {e, 0, 1}]. It cannot be computed symbolically, yet the result is not zero! In contrast Y[q_, w_?NumericQ] := 0 /; w < 0and Y[q_, w_?NumericQ] := w leads to zero in both cases. Can you please comment on this. $\endgroup$
    – yarchik
    Commented Jul 2, 2019 at 11:28
  • $\begingroup$ It comes from symbolic evaluation of integrand i.e. Y[0.5, -Exp[Exp[Exp[e]]]] first evaluate to -E^E^E^e. $\endgroup$
    – xzczd
    Commented Jul 2, 2019 at 11:31
2
$\begingroup$

Your second definition of Y overwrites the first. That's why MMA evaluates Y[q,w]->w !

Try

Y[q_, w_ /; w < 0] := 0
Y[q_, w_ /; w >= 0] := w

NIntegrate[Y[0.5, e], {e, -2, -1}]
(* 0 *)
$\endgroup$
9
  • $\begingroup$ Not quite for 2 reasons: 1) exchanging the order of definitions does not change anything; 2) assuming that my second definition indeed has a priority, why then it is not visible in Plot? I believe that Plot has to be consistent with NIntegrate no matter what the function is. Suspect a bug... $\endgroup$
    – yarchik
    Commented Jul 2, 2019 at 8:26
  • $\begingroup$ Don't know why Plot works. But everything works as expected if you use a clean function definition , for example Y[q_, w_] := Which[w < 0, 0, True, w] $\endgroup$ Commented Jul 2, 2019 at 8:50
  • $\begingroup$ @ yarchik : Add Evaluate in your plot-command Plot[Y[0.5, e], {e, -2, -1},Evaluated -> True] and you will see the correct plot! No bug!! $\endgroup$ Commented Jul 2, 2019 at 9:25
  • $\begingroup$ Why then Y[0.5,-1] returns zero? $\endgroup$
    – yarchik
    Commented Jul 2, 2019 at 9:31
  • $\begingroup$ Because MMA takes the first matching definition. $\endgroup$ Commented Jul 2, 2019 at 9:33

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.