5
$\begingroup$

I expect the following code to count the number of function calls in NIntegrate.

i = 0;
f[x_] := (i += 1; Tanh[x] Sin[Exp[x]] Exp[-0.55 x^2 Exp[x^2]])
Print[NIntegrate[f[x], {x, -2, 1}]] 
Print[i]

However, the output is

0.0901049
2

which means only 2 function calls in NIntegrate. It's hard to believe converged result can be obtained by merely two function calls. What's happening here?

$\endgroup$
5
$\begingroup$

Try the option EvaluationMonitor

Block[{k = 0}, {NIntegrate[f[x], {x, -2, 1}, EvaluationMonitor :> k++], k}]

{0.0901049, 121}

Without using EvaluationMonitor you can do

ClearAll[f, ff]
f[x_] := Tanh[x] Sin[Exp[x]] Exp[-0.55 x^2 Exp[x^2]]

i = 0;
ff[y_?NumberQ] := Block[{x = y}, i++; f[x]]

{NIntegrate[ff[x], {x, -2, 1}], i}

{0.0901049, 121}

$\endgroup$
  • $\begingroup$ Yeah, that works. But what's wrong with my approach? $\endgroup$ – Chong Wang Sep 17 '19 at 18:34
7
$\begingroup$

A very simple modification (adding ?NumericQ) achieves the result you expected.

i = 0;
f[x_?NumericQ] := (i += 1; Tanh[x] Sin[Exp[x]] Exp[-0.55 x^2 Exp[x^2]])
Print[NIntegrate[f[x], {x, -2, 1}]]
Print[i]

(* 0.0901049*)

(*122*)

The issue is that NIntegrate tries to evaluate f[x] symbolically. In your version, it is called only once and is replaced by Tanh[x] Sin[Exp[x]] Exp[-0.55 x^2 Exp[x^2]. In my version, the f[x] is returned unchanged until specific numerical values are given to x.

$\endgroup$
  • $\begingroup$ My +1 for actually explaining the problem in the OP's approach! $\endgroup$ – Rebel-Scum Sep 18 '19 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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