I have a little question. I need a smart way to compute a numerical integral. The standard way to compute a numerical integral, in multiple variables, is, for example, the following:

NIntegrate[x y , {x, 0, 1}, {y, 0, x}, AccuracyGoal -> 5]

The time of computation is very small. Now let me define the following recursive functions:


so, for example, we have:


and so on. Now if I compute the following numeric integral

NIntegrate[l[2], {x[2], 0, 1}, AccuracyGoal -> 5]

I obtain the output of '0.0416667', and it is correct. This is easy because, thanks to the symbolic integration in the recursive formula, we have a closed form for every function 'l[h]', with 'h' positive integer. Now I modify the recursive formula in this way


Obviously 'l[0]' is very difficult function, that probably, doesn't admit a closed form. If now I try to do the following numeric integration

NIntegrate[l[1], {x[1], 0, 0.1}, AccuracyGoal -> 5] (*1*)

the output appears after a very very long time of evaluation. Instead if I write manually the form of the previous numeric integral, with boundaries of integration, like the following:

NIntegrate[l[0],{x[1],0,0.1},{x[0],0,x[1]},AccuracyGoal->5] (*2*)

I obtain the output instantly.

The long time of evaluation of the numeric integral (1) is caused by the fact that the numeric integral of 'l1' needs to evaluate previously of numeric evaluation, the following symbolic integral:

Integrate[l[0], {x[0], 0, x[1]}]

this comes from the recursive formula for 'l[h]', where 'l[0]' is a very ugly function.

Now I can do my question: there is a way to define the recursive formula, in a way that if I put a recursive function in the final numeric integral, there is NO need to do the symbolic integral of a very ugly function?

Thanks for any tips and helps. I hope we will find a solution for this problem. Thanks again!

I add the following part in a second moment. Probabily the following can help us to achive the goal. I define the recursive function like:

l[0] := f[x0_]
l[h_] := Integrate[l[h - 1], {x[h - 1], 0, x[h]}]

So if I write 'l[2]', for example, I obtain the following output (I paste an immage for a clear visualization):

enter image description here

So this is pretty, but If now I try to compute numerically the integral evaluating the expression of 'l[2]' for 'f[x[0]]' equal to the ugly function of my example

NIntegrate[l[2]/.f[x0_]->Cos[x[0] - Sin[Cos[Tan[Sin[Cos[1 - Sin[Cos[x[0]]]]]]]]], {x[2], 0, 0.1}, AccuracyGoal -> 5]

I obtained the correct result but after the same very very long time of computation.


1 Answer 1


This is not an answer but rather an extended comment.


Functions that are defined recursively should make use of memoization to avoid unnecessary repetition of calculations (see Functions That Remember Values They Have Found and workflow).

l[0] := x[0]
l[h_] := l[h] = Integrate[l[h - 1], {x[h - 1], 0, x[h]}]

Note the use of memoization in the definition of l[h]

seq = l /@ Range[0, 5]

(* {x[0], x[1]^2/2, x[2]^3/6, x[3]^4/24, x[4]^5/120, x[5]^6/720} *)

In this specific case, by inspection, the closed form for the terms of this sequence are

l2[n_] = x[n]^(n + 1)/(n + 1)!;

Verifying the equivalence of l and l2 for an extended range,

And @@ Table[l[n] == l2[n], {n, 0, 20}]

(* True *)

The associated integrals are then

int[n_] = Assuming[n >= 0, Integrate[l2[n], {x[n], 0, 1}]]

(* 1/Gamma[3 + n] *)

Comparing with your original example,

{int[2], int[2] // N}

(* {1/24, 0.0416667} *)

Memoization should also be used in your second example; however, finding a closed form expression is unlikely.

  • $\begingroup$ @MarcoB - thanks. I corrected. $\endgroup$
    – Bob Hanlon
    Commented Jan 8, 2022 at 22:02

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.