Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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[0] := 1; x[1] := 1; p[0] := 2; p[1] := 2; a[0] := 3; a[1] := 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[2], p[2], a[2] 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?

share|improve this question
    
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. –  rasher Mar 5 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 at 8:50
1  
then compose some minimal working example of "the problem"... –  rasher Mar 5 at 8:51
add comment

1 Answer 1

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] = 1;
fib[2] = 1;
fib[n_] := fib[n - 1] + fib[n - 2];

fib[5] // Timing
fib[30] // 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[30] // 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.

share|improve this answer
1  
I suggest also reading this one here: mathematica.stackexchange.com/questions/2639/… –  Pinguin Dirk Mar 5 at 9:07
    
Wow, this solves everything, thank you! –  wlq Mar 5 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. –  rasher Mar 5 at 9:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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