Download 6 Fibonacci Numbers

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Infinity wikipedia , lookup

Big O notation wikipedia , lookup

Infinitesimal wikipedia , lookup

History of the function concept wikipedia , lookup

Functional decomposition wikipedia , lookup

Non-standard analysis wikipedia , lookup

Fundamental theorem of calculus wikipedia , lookup

Proofs of Fermat's little theorem wikipedia , lookup

Abuse of notation wikipedia , lookup

Series (mathematics) wikipedia , lookup

Hyperreal number wikipedia , lookup

Arithmetic wikipedia , lookup

Non-standard calculus wikipedia , lookup

Mathematics of radio engineering wikipedia , lookup

Collatz conjecture wikipedia , lookup

German tank problem wikipedia , lookup

Addition wikipedia , lookup

Large numbers wikipedia , lookup

Factorial wikipedia , lookup

Elementary mathematics wikipedia , lookup

Recurrence relation wikipedia , lookup

Transcript
6
Fibonacci Numbers
The Fibonacci numbers fn are the numbers in the sequence defined by
fn+1 = fn + fn−1 ,
f2 = 1, f1 = 1.
(1)
The sequence begins
1, 1, 2, 3, 5, 8, 13, 21, . . .
The Fibonacci numbers have many very interesting properties and have been much studied by
mathematicians. In this handout we will take a look at some of these properties and show how to
calculate and investigate Fibonacci numbers with the computer.
First, we write a simple Matlab script to calculate the first n Fibonacci numbers, placing the
results in an array f:
%FIB1
n = input(’n (number of Fibonacci numbers to compute): ’);
f(1) = 1; f(2) = 1;
for i = 3:n
f(i) = f(i-1) + f(i-2)
end
Here is some sample output:
>> format compact
>> fib1
n (number of Fibonacci
f =
1
1
2
f =
1
1
2
f =
1
1
2
f =
1
1
2
f =
1
1
2
numbers to compute): 7
3
3
5
3
5
8
3
5
8
13
We deliberately omitted a semicolon from the end of the line that assigns to f(i), so that we can
see the progress of the array as it is built. On each iteration of the loop Matlab expands the
dimension of the array f by 1 in order to accommodate the newly assigned element f(i). Although
this works, it is not good programming practice. It is more efficient, and leads to clearer code, to
initialize arrays to the required length before using them. The following modified version of fib1 is
therefore better. Here, we have also converted the M-file into a function.
function f = fib2(n)
%FIB2
Fibonacci numbers.
%
FIB2(N) is a vector of the first N Fibonacci numbers.
f = ones(1,n);
for i = 3:n
f(i) = f(i-1) + f(i-2);
end
On running fib2 we have
>> fib2(7)
ans =
1
1
2
3
5
8
13
Let us now examine the ratios of successive Fibonacci numbers.
>> n = 15;
>> f = fib2(n);
>> for i = 2:n, disp( f(i)/f(i-1) ), end
1
2
1.5000
1.6667
1.6000
1.6250
1.6154
1.6190
1.6176
1.6182
1.6180
1.6181
1.6180
1.6180
It seems that the ratios are converging to 1.6180. We can derive the limit mathematically, as follows.
Dividing the recurrence (1) by fn gives
fn−1
fn+1
=1+
,
fn
fn
f2 = 1, f1 = 1.
Now introduce the new variable gn = fn /fn−1 . Then
gn+1 = 1 +
1
.
gn
(2)
Suppose that limn→∞ gn = γ. Then, taking limits in (2) we have
1
γ =1+ ,
γ
This quadratic has solutions
or γ 2 − γ − 1 = 0.
√
1± 5
,
γ=
2
which have numerical values
>> gamma = [1+sqrt(5) 1-sqrt(5)]/2
gamma =
1.6180
-0.6180
Thus√the limit we observed in Matlab is the larger of the two possible limits. You may recognize
(1 + 5)/2 as the golden ratio, which is supposed to be the ratio of lengths of sides of a rectangle
that gives the most visually pleasing rectangle.
One way to evaluate the golden ratio without using square roots is to use (2):
>> g = 1; for i = 1:15, g = 1+1/g; end, g
g =
1.6180
What we are effectively doing is evaluating a partial sum of the continued fraction
√
1+ 5
1
=1+
1
2
1+
1
1+
1
1+
1
1+
1
1+
1
1+
1
1+
1 + ···
Continued fractions have a very interesting theory, some of which you may come across in later
courses in number theory or numerical analysis.
Instead of computing the nth Fibonacci number fn by first computing all preceding numbers in
the sequence we might want to compute fn directly. Is there an explicit formula for fn ? We rewrite
(1) as
fn+1 − fn − fn−1 = 0,
f2 = 1, f1 = 1.
(3)
This is a three-term recurrence relation. Recurrence relations have a theory analogous to that of
linear ordinary differential equations. To solve (1) we look for solutions of the recurrence of the form
fn = θn . Plugging into the recurrence gives
0 = θn+1 − θn − θn−1 = θn−1 (θ2 − θ − 1).
Assuming θ 6= 0, we must have θ 2 − θ − 1 = 0. This is the quadratic we solved earlier, and it has the
distinct roots
√
√
θ1 = (1 + 5)/2,
θ2 = (1 − 5)/2.
The theory of recurrence relations tells us that the general solution to the recurrence (3) is
fn = αθ1n + βθ2n ,
where α and β are arbitrary constants. These constants are determined by the initial conditions,
f2 = f1 = 1. To make the algebra easier we define f0 = 0. Then the conditions f0 = 0 and f1 = 1
give two equations in two unknowns:
α + β = 0,
αθ1 + βθ2 = 1.
The solution is easily found to be
√
α = 1/ 5,
Therefore
√
1
fn = (θ1n − θ2n )/ 5 = √
5
This formula can be verified in Matlab :
√
β = −1/ 5.
ÃÃ
√ !n Ã
√ !n !
1+ 5
1− 5
.
−
2
2
>> for i = 1:12, disp( (((sqrt(5)+1)/2)^i - ((1-sqrt(5))/2)^i)/sqrt(5) ), end
1
1
2
3.0000
5.0000
8.0000
13.0000
21.0000
34.0000
55.0000
89.0000
144.0000
Looking more closely at this formula, we see that
>> theta_2 = (1-sqrt(5))/2
theta_2 =
-0.6180
and so the powers of θ2 rapidly become small. In fact,
1
fn = the nearest integer to √
5
Ã
√ !n
1+ 5
.
2
In Matlab , the nearest integer to a real number is obtained with the round function:
>> help round
ROUND Round towards nearest integer.
ROUND(X) rounds the elements of X to the nearest integers.
See also FLOOR, CEIL, FIX.
>> for i = 1:12, disp( round( ((sqrt(5)+1)/2)^i/sqrt(5) ) ), end
1
1
2
3
5
8
13
21
34
55
89
144
(4)
Recursion
In Matlab a function can call itself. Such a function is called a recursive function. Recursion
is an important notion in both mathematics and computing. The Fibonacci numbers are defined
recursively (each number is defined in terms of the previous two), and proof by induction is recursive
in nature. In computing, recursion often allows us to solve problems with particularly elegant and
short code.
Here is a recursive function to calculate the nth Fibonacci number:
function f = fibr(n)
%FIBR
Fibonacci number.
%
FIBR(N) is the N’th Fibonacci number.
if n == 1 | n == 2
f = 1;
return
end
f = fibr(n-1) + fibr(n-2);
Note the two key characteristic features of recursive functions: one or more recursive calls to the
function, and a test for deciding when to terminate the recursion. In this case, termination occurs
when n = 1 or n = 2, at which point we use the given starting values for f1 and f2 .
It is important to note that not all problems that can be solved recursively should be: sometimes,
recursion can be very inefficient. Our Fibonacci problem is such an example. Let’s look at the time
it takes to compute the first 25 Fibonacci numbers:
>> tic, fib2(25); toc
elapsed_time =
0
>> tic, fibr(25); toc
elapsed_time =
4.3400
Function fib2 is so fast that Matlab ’s timer reports an elapsed time of zero; the actual time was
less than the resolution of Matlab ’s clock. But function fibr took over 4 seconds. Figure 1 plots
the execution time of fibr as a function of n. We see exponential growth, instead of what is clearly
linear growth for fib2, and the clear conclusion is that evaluation of the Fibonacci numbers is best
not programmed recursively. The reason for the inefficiency is the large number of recursive calls
that are generated.
Fast Evaluation
So far, the fastest way we have seen to evaluate fn is to use the formula (4). That formula is slightly
unsatisfying in that it involves real arithmetic, including square roots, to compute a result that we
know to be an integer. Here is another approach that works entirely in integer arithmetic. We can
express the Fibonacci recurrence as
fn+1 = fn + fn−1 ,
fn = f n .
This seems bizarre, but we can rewrite these relations in matrix-vector form as
·
fn+1
1 1
=
fn
1 0
¸
·
¸·
fn
,
fn−1
¸
50
45
40
Time in seconds
35
30
25
20
15
10
5
0
0
5
10
15
n
20
25
30
Figure 1: Execution time of fibr.
or
hn+1
where
1 1
h = M hn ,
=
1 0 n
·
fn
hn =
,
fn−1
·
¸
¸
1 1
M=
.
1 0
·
¸
We now have a first order vector recurrence, and we can apply the recurrence inductively to obtain
the formula
· ¸
1
.
hn+1 = M n−1 h2 = M n−1
1
The obvious way to use this formula is to multiply the vector [1 1]T by M n times; that would be
essentially equivalent to using the original recurrence (1). But suppose, for simplicity that n − 1 is
a power of 2: n − 1 = 2k . Then
M n−1 = (((M 2 )2 ) . . .)2 ,
where there are k squarings. This enables us to compute fn+1 by k matrix squarings at a cost of
about 12k = 12 log2 (n − 1) scalar operations. For large n, this is much less than the n − 1 operations
required to evaluate fn+1 using the recurrence (1).