I have a linear recurrence problem where the next element relies on more than just the prior value, e.g. the Fibonacci sequence. One method calculating the nth element is to define it via a function call, e.g.
Fibonacci[0] = 0; Fibonacci[1] = 1;
Fibonacci[n_Integer?Positive] := Fibonacci[n] + Fibonacci[n - 1]
and for the sequence I'm working with, that is exactly what I do. (The definition is inside of a Module
so I don't pollute Global`
.) However, I am going to be using this with 210 - 213 points, so I'm concerned about the extra overhead when I just need the last term and none of the prior elements. I'd like to use Fold
to do this, but Fold
only passes the immediately prior result which means it is not directly useful for a general linear recurrence problem.
I'd like a pair of functions to replace Fold
and FoldList
that pass a specified number of prior sequence elements to the function, i.e.
In[1] := MultiFoldList[f, {1,2}, {3,4,5}] (* for lack of a better name *)
Out[1]:= {1, 2, f[3,2,1], f[4,f[3,2,1],2], f[5,f[4,f[3,2,1],2],f[3,2,1]]}
I had something that did this, but I closed the notebook prior to saving it. So, if I rewrite it on my own, I'll post it.
Edit: as to why I am not using RSolve
or MatrixPower
to solve this. My specific problem is I'm performing an n-point Pade approximant to analytically continue a function I only know at a set number of points on the imaginary axis, {zi}. Part of creating the approximant is to generate a set of coefficients, ai, which is another recurrence relation, that are then fed into the final relationship
A[n+1]== A[n] + (z - z[[n]]) a[[n+1]] A[n-1]
which is not amenable to either RSolve
nor MatrixPower
, at least that I can see.
Can RecurrenceTable perform this task for you?
Find the 1000th term in a recurrence depending on two previous values:
Edit: If your recurrence is defined by a function
f[m, n]
that doesn't like to get evaluated for non-numeric m and n, then you could use Condition:The recurrence table in terms of
f
:Almost a convoluted joke, but you could use a side-effect of
NestWhileList
Not too bad performance:
By changing the last
2
by any integer you may pass the last k results to your function (in this case Total[]).LinearRecurrence
andRecurrenceTable
are very useful.For small kernels, the
MatrixPower
method that Daniel gave is the fastest.For some problems these may not be applicable, and you may need to roll your own.
I will be using Nest because I believe that is appropriate for this problem, but a similar construct can be used with Fold.
A specific example, the Fibonacci sequence. This may not be the cleanest possible for that, but I believe you will see the utility as I continue.
Here I use
Apply
(@@
) so that I can address elements with#
,#2
, etc., rathern than#[[1]]
etc. I useSlotSequence
to drop the first element from the old list, andSequence
it into the new list at the same time.If you are going to operate on the entire list at once, then a simple
Append[Rest@#, ...
may be better. Either method can be easily generalized. For example, a simple linear recurrence implementation is(the kernel is in reverse order from the built in
LinearRecurrence
)A multiple foldlist can be useful but it would not be an efficient way to get linear recurrences evaluated for large inputs. A couple of alternatives are to use RSolve or matrix powers times a vector of initial values.
Here are these methods applied to example if nth term equal to n-1 term plus two times n-2 term.
Out[67]= 1/3 (-(-1)^n + 2^n)
Out[79]= {683, 683}
Daniel Lichtblau Wolfram Research