# Slow evaluation of complicated Table

I have a system of recursive equations

x[t+1]:=f[x[t],p[t-1],a[t],a[t-1]];
p[t+1]:=g[p[t],x[t-1],a[t],a[t-1]];
a[t+1]:=h[x[t],p[t],a[t],a[t-1]];


I want to evaluate them for $t \in [0,10]$ with some initial conditions on all variables. I tried several possibilities like,

Table[{x[t+1],p[t+1],a[t+1]}, {t, 0, 10}]


or

{x[#+1],p[#+1],a[#+1]}&/@Range[0,10]


but all of them are extremely slow. The MWE of the above might be given as

 x := 1; x := 1; p := 2; p := 2; a := 3; a := 3; x[t_] := 2 p[t - 1] a[t - 1] - x[t - 1] a[t - 2]; p[t_] := 5 x[t - 1] a[t - 1] - p[t - 1] a[t - 2]; a[t_] := 10 x[t - 1] p[t - 1] + a[t - 1] a[t - 2];

So commands

Table[{t + 1, x[t + 1], p[t + 1], a[t + 1]}, {t, 0, 10}]


and

{# + 1, x[# + 1], p[# + 1], a[# + 1]} & /@ Range[0, 10]


generate output

{{1, 1, 2, 3}, {2, 0.00336319, -0.00719693, 0.010203}, {3, 0.0677008, -0.0172979, 0.010203}, {4, 2.38052, -0.0540507, 0.00932697}, {5, 66.8197, 11.1562, 0.00471539}, {6, -0.518014, 1.47135, 7454.52}, {7, 21936.5, -19307.7, 27.5292}, {8, -1.64589*10^8, 1.46949*10^8, -4.23523*10^9}, {9, -1.24473*10^18, 3.48536*10^18, -2.41863*10^17}, {10, -1.68596*10^36, 1.50527*10^36, -4.33833*10^37}, {11, -1.30607*10^74, 3.65712*10^74, -2.53782*10^73}}

but very slowly. I noticed that if I calculate values for $t \in [0,2]$ and then put values as initial conditions for x, p, a manually and then redo the code for $t \in [0,3]$ and repeat, it works much much faster. Is there a way to automatize it?

• Is that all there is, because using what you've posted results in instantaneous results, on a netbook...Incomplete or scantily defined questions, where readers can't cut-n-paste the example to work with it are much less likely to get useful responses. – ciao Mar 5 '14 at 8:48
• Well, the functions are very long so I cannot really paste them here. I used a shorthand notation in describing them. – wlq Mar 5 '14 at 8:50
• then compose some minimal working example of "the problem"... – ciao Mar 5 '14 at 8:51

## 1 Answer

I'm going to step out on the limb and answer re: what is almost certainly the "problem" - you are repeatedly evaluating to the same result, an aspect of recursive functions, so you're creating excess work.

By example of Fibonacci numbers:

fib = 1;
fib = 1;
fib[n_] := fib[n - 1] + fib[n - 2];

fib // Timing
fib // Timing

(*
{0., 5}
{9.984064,832040}
*}


Note how the time gets huge quickly (keep in mind, this is a netbook I'm on right now).

With a simple change:

fib[n_] := fib[n] = fib[n - 1] + fib[n - 2]

fib // Timing

{* {0., 832040} *}


By "remembering" past results, evaluation time is drastically reduced.

Assuming your system of functions is referentially transparent, just using this kind of construct will likely address your speed issues.

Edit: Seeing your update, this is precisely what will help you , e.g., change to:

x[t_] := x[t] = 2 p[t - 1] a[t - 1] - x[t - 1] a[t - 2];
p[t_] := p[t] = 5 x[t - 1] a[t - 1] - p[t - 1] a[t - 2];
a[t_] := a[t] = 10 x[t - 1] p[t - 1] + a[t - 1] a[t - 2];


on my netbook the time is below clock resolution. Nonetheless, in the future include in your questions what you're trying to accomplish, there may well be a smarter way to do things.

• I suggest also reading this one here: mathematica.stackexchange.com/questions/2639/… – Pinguin Dirk Mar 5 '14 at 9:07
• Wow, this solves everything, thank you! – wlq Mar 5 '14 at 9:07
• @wlq: good to hear. Remember to Clear your definitions when finished with them or when you change definitions, else the "old" ones may get used. – ciao Mar 5 '14 at 9:09