Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
World Applied Programming, Vol (1), No (1), April 2011. 72-76 ISSN: 2222-2510 ©2011 WAP journal. www.waprogramming.com All about Fibonacci: A python approach C. Canaan * M. S. Garai M. Daya Information institute Chiredzi, Zimbabwe [email protected] Information institute Chiredzi, Zimbabwe [email protected] Information institute Chiredzi, Zimbabwe [email protected] Abstract: Here we want to represent a brief introduction to Fibonacci sequence and different techniques for generating and calculating the value of this sequence. So, first we will make you familiar with Fibonacci numbers and then proposed algorithms in python language will be represented. Mathematical definitions are also placed for clarifying the matter. Key word: Fibonacci Fibonacci numbers Fibonacci algorithms Fibonacci generation I. INTRODUCTION Leonardo Pisano Bigollo (c. 1170 – c. 1250) [1] also known as Leonardo of Pisa, Leonardo Pisano, Leonardo Bonacci, Leonardo Fibonacci, or, most commonly, simply Fibonacci, was an Italian mathematician, considered by some "the most talented western mathematician of the Middle Ages" [2]. Fibonacci is best known to the modern world for [3] the spreading of the Hindu-Arabic numeral system in Europe, primarily through the publication in the early 13th century of his Book of Calculation, the Liber Abaci; and for a number sequence named after him known as the Fibonacci numbers, which he did not discover but used as an example in the Liber Abaci [4]. In the Liber Abaci (1202), Fibonacci introduces the so-called modus Indorum (method of the Indians), today known as Arabic numerals (Sigler 2003; Grimm 1973). The book advocated numeration with the digits 0–9 and place value. The book showed the practical importance of the new numeral system, using lattice multiplication and Egyptian fractions, by applying it to commercial bookkeeping, conversion of weights and measures, the calculation of interest, money-changing, and other applications. The book was well received throughout educated Europe and had a profound impact on European thought. Liber Abaci also posed, and solved, a problem involving the growth of a population of rabbits based on idealized assumptions. The solution, generation by generation, was a sequence of numbers later known as Fibonacci numbers. The number sequence was known to Indian mathematicians as early as the 6th century [5] [6] [7], but it was Fibonacci's Liber Abaci that introduced it to the West. In the Fibonacci sequence of numbers, each number is the sum of the previous two numbers, starting with 0 and 1. This sequence begins 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 ... [8] The higher up in the sequence, the closer two consecutive "Fibonacci numbers" of the sequence divided by each other will approach the golden ratio (approximately 1 : 1.618 or 0.618 : 1). After this short introduction, we are going to introduce Fibonacci sequence algorithms in the following sections. II. FIBONACCI NUMBERS AND RELATED ALGORITHMS The Fibonacci numbers are the integer sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, ..., in which each item is formed by adding the previous two. The sequence can be defined recursively by Fibonacci number programs that implement this definition directly are often used as introductory examples of recursion. However, many other algorithms for calculating (or making use of) Fibonacci numbers also exist. The recursive definition can be translated directly into Python as follows: 72 C. Canaan et al., World Applied Programming, Vol (1), No (1), April 2011. <<fibonacci_recursive.py>>= def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) Although the recursive implementation given above is elegant and close to the mathematical definition, it is not very practical. Calculating fib(n) requires calculating two smaller Fibonacci numbers, which in turn require two additional recursive calls each, and so on until all branches reach 1. As a consequence, the time required to calculate fib(n) is exponential in n (it is about Φn, where Φ is the golden ratio). Interestingly, when computing fib(n), the for all 1<k<n fib(k) is called fib(n-k) times, but fib(0) is called fib(n-2) times. To remedy this, we can employ memoization to cache previous computations. The memoization cache is a dictionary consisting of entries composed of a key n and a corresponding value fib(n). We initialize the dictionary with the first two Fibonacci numbers: <<fibonacci_memo.py>>= memo = {0:0, 1:1} The memoized fib function recursively computes and stores the value of fib(n) if it hasn't been previously stored in the memo dictionary. Otherwise it simply returns the memoized value of fib(n). <<fibonacci_memo.py>>= def fib(n): if not n in memo: memo[n] = fib(n-1) + fib(n-2) return memo[n] To calculate the nth Fibonacci number in only n steps, we can also start with 0 and 1 and iteratively add up items n times: <<fibonacci_iteration.py>>= def fib(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a We can also construct a generator that calculates and yields the Fibonacci numbers one at a time: <<fibonacci_generator.py>>= def fib(): a, b = 0, 1 while 1: yield a a, b = b, a + b All sequences defined by linear recurrence have an associated closed-form expression for the nth number. The Fibonacci numbers in particular are given by Binet's formula (for Jacques Philippe Marie Binet) 73 C. Canaan et al., World Applied Programming, Vol (1), No (1), April 2011. where is the golden ratio, This can be implemented straightforwardly: <<fibonacci_binet.py>>= phi = (1 + 5**0.5) / 2 def fib(n): return int(round((phi**n - (1-phi)**n) / 5**0.5)) Because of floating-point rounding errors, this will however only give the right result for n < 70. Binet's formula can be inverted by ignoring the term, which disappears for large n. We can therefore define the inverse Fibonacci function that, when given F(n), returns n (ignoring that F(1) = F(2)): <<fibonacci_binet.py>>= from math import log def fibinv(f): if f < 2: return f return int(round(log(f * 5**0.5) / log(phi))) Here rounding is used to our advantage: it removes the error introduced by our modification to Binet's formula. The function will in fact return the right answer when given any Fibonacci number that can be stored as an exact integer in the computer's memory. On the other hand, it does not verify that the given number actually is a Fibonacci number; inputting a large Fibonacci number or any number close to it will give the same result. This may be useful, for example to find the Fibonacci number closest to a given number. There are efficient ways to calculate the nth Fibonacci number exactly without first calculating all its predecessors. One way to do so is to utilize the matrix identity and employing exponentiation by squaring to find the nth power of the left-hand matrix. We here represent a 2-by-2 matrix A as the 3-tuple (a, b, c) where <<fibonacci_matrix.py>>= def mul(A, B): a, b, c = A d, e, f = B return a*d + b*e, a*e + b*f, b*e + c*f def pow(A, n): if n == 1: return A if n & 1 == 0: return pow(mul(A, A), n//2) else: return mul(A, pow(mul(A, A), (n-1)//2)) def fib(n): if n < 2: return n return pow((1,1,0), n-1)[0] Our next approach to quick computation of large Fibonacci number is based on representation of as , where Ln is n-th Lucas number and Fn is n-th Fibonacci number. It is easy to obtain 74 C. Canaan et al., World Applied Programming, Vol (1), No (1), April 2011. formulas necessary for exponentiation by squaring. For example: . Therefore , F2n = LnFn. Similar , and . <<fibonacci_LF.py>>= def powLF(n): if n == 1: return (1, 1) L, F = powLF(n//2) L, F = (L**2 + 5*F**2) >> 1, L*F if n & 1: return ((L + 5*F)>>1, (L + F) >>1) else: return (L, F) def fib(n): return powLF(n)[1] Notes: (1) The code can be imporved: it is not necessary to calculate Ln on the last step. def fib(n): if n & 1: return powLF(n)[1] else: L, F = powLF(n // 2) return L * F (2) The choice of power (**2) over multiplication is based on experiments (this way program is 10% faster). (3) It is obvious how to rework this algorithm to the iterative one at the expense of its clarity. Using a method developed by [9] we can iterate, for large numbers, very few times (for F1000 we only need 22 iterations) <<fibonacci_ewd.py>>= fibs = {0: 0, 1: 1} def fib(n): if n in fibs: return fibs[n] if n % 2 == 0: fibs[n] = ((2 * fib((n / 2) - 1)) + fib(n / 2)) * fib(n / 2) return fibs[n] else: fibs[n] = (fib((n - 1) / 2) ** 2) + (fib((n+1) / 2) ** 2) return fibs[n] At the expense of immediate legibility, we can compute Fibonacci numbers way faster than naive methods. Uses caching of results both for speed and to define starting values. REFERENCES [1] [2] [3] [4] The Fibonacci Series - Biographies - Leonardo Fibonacci (ca.1175 - ca.1240)". Library.thinkquest.org. http://library.thinkquest.org/27890/biographies1.html. Retrieved 2010-08-02. Howard Eves. An Introduction to the History of Mathematics. Brooks Cole, 1990: ISBN 0-03-029558-0 (6th ed.), p 261. Leonardo Pisano - page 3: "Contributions to number theory". Encyclopædia Britannica Online, 2006. Retrieved 18 September 2006. Parmanand Singh. "Acharya Hemachandra and the (so called) Fibonacci Numbers". Math. Ed. Siwan , 20(1):28-30, 1986. ISSN 0047-6269 75 C. Canaan et al., World Applied Programming, Vol (1), No (1), April 2011. [5] [6] [7] [8] [9] Susantha Goonatilake (1998). Toward a Global Science. Indiana University Press. p. 126. ISBN 9780253333889. http://books.google.com/?id=SI5ip95BbgEC&pg=PA126&dq=Virahanka+Fibonacci. Donald Knuth (2006). The Art of Computer Programming: Generating All Trees—History of Combinatorial Generation; Volume 4. Addison-Wesley. p. 50. ISBN 9780321335708. http://books.google.com/?id=56LNfE2QGtYC&pg=PA50&dq=rhythms. Rachel W. Hall. Math for poets and drummers. Math Horizons 15 (2008) 10-11. Fibonacci Numbers from The On-Line Encyclopedia of Integer Sequences. E. W. Dijkstra (found at http://www.cs.utexas.edu/users/EWD/ewd06xx/EWD654.PDF). 76