Section 6.2 Recurrence relations
Previously, we saw that the sequence \((n!)_0^\infty\) of factorials has both a closed form representation and a recursive representation.
Example 6.2.1.
Consider the sequence \((n!)_{n=0}^\infty\) of factorials. Since
we can express \(n!\) via the “recurrence relation”
This is read: “\(n!\) is equal to \(n(n-1)!\) when \(n \ge 1\text{,}\) and equal to \(1\) when \(n=0\text{.}\)”
Definition 6.2.2.
Consider the sequence \((a_n)_k^\infty\text{.}\) A recurrence relation is a relation that allows \(a_n\) to be calculated using the preceding terms \(a_{n-1}, a_{n-2}, \ldots, a_{k+1}, a_k\text{.}\) Some number of initial terms in the sequence, depending on the formula for the relation, must be known.
As we mentioned in our discussion on recursion, there has to be a “base case”. We must know one or more starting terms of the sequence in order to use a recurrence relation. In the case of \(n!\text{,}\) we must know that \(0!=1\text{.}\)
Example 6.2.3.
The Fibonacci sequence
has a very difficult closed form expression. It is much easier to calculate the terms recursively by adding the prior two terms together. Therefore,
Notice that we require knowledge of the first two terms of the sequence, because the recurrence relation involves knowing two terms.
We can calculate the terms of a sequence given via recurrence relation in two different ways.
Definition 6.2.4.
Consider the sequence \((a_n)_k^\infty\) and suppose \(a_n\) is defined via recurrence relation. We can calculate \(a_n\) iteratively by beginning with the known terms and calculating each term of the sequence one at a time until \(a_n\) is reached.
Alternatively, we can calculate \(a_n\) recursively by starting with \(a_n\) and repeatedly using the recurrence relation to express \(a_n\) as a function of only the known terms, and then substituting those terms to find \(a_n\text{.}\)
In other words, to calculate \(a_n\) iteratively we must calculate every term of the sequence leading up to it. We only need to calculate one term of the sequence to calculate recursively, but there is a lot of preparatory work.
You might be wondering why this difference is significant. Here, it is important to remember that the target audience for this book is computer science students, where the goal may be to implement a program whereby a computer calculates \(a_n\text{.}\) There are practical considerations involved. Is it faster to do simple calculations and store a thousand terms of a sequence, or is it faster to do more complicated calculations but only need to store a few terms? Since it depends on the problem, it is good to know both methods.
Example 6.2.5.
Return to the Fibonacci sequence
and suppose we want to calculate \(F_5\text{.}\) The iterative calculation starts at \(F_0\) and “works up” to \(F_5\text{.}\)
So, \(F_5 = 8\text{.}\) All the calculations were relatively simple, but we needed to know six terms of the sequence in the end.
Let's try it recursively. This time we will start with \(F_5\) and continue applying the recurrence relation until we have an expression only involving the known values \(F_0\) and \(F_1\text{.}\)
Notice the use of alternating types of brackets to aid readability.
At this point we can do two different things to calculate \(F_5\text{.}\) One thing we can do is combine like terms.
Alternatively, we can start from the innermost pair of brackets and work outward. If we do this, something interesting happens.
When we calculate \(F_5\) this way, the previous terms in the Fibonacci sequence appear as well. That way, if we have already done the calculation iteratively, we know what numbers to expect!
Example 6.2.6.
Consider the sequence \((x_n)\) where
To calculate \(x_4\) iteratively, we simply calculate each term of \((x_n)\) until we arrive at \(x_4\text{.}\)
Thus, \(x_4 = 1\text{.}\)
In the recursive calculation, we will begin with \(x_4\) and repeatedly apply the recurrence relation until we have only known values of the sequence: so, \(x_2\) and \(x_1\text{.}\)
which agrees with our iterative calculation.
Example 6.2.7.
Consider the sequence \((b_k)\) where
This time we will just calculate \(b_5\) recursively. You can do the iterative calculation yourself to check.
So, \(b_5 = 3072\text{.}\)