# How to count the number of function evaluations in NIntegrate

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?

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}

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

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.

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