* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download 6 Fibonacci Numbers
Survey
Document related concepts
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
Non-standard calculus wikipedia , lookup
Mathematics of radio engineering wikipedia , lookup
Collatz conjecture wikipedia , lookup
German tank problem wikipedia , lookup
Large numbers 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).