Вы находитесь на странице: 1из 5

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
canaancan@gmail.com

Information institute
Chiredzi, Zimbabwe
mat.s.g@mail.com

Information institute
Chiredzi, Zimbabwe
d2020m@yahoo.com

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 09 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". Encyclopdia 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 TreesHistory 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

Вам также может понравиться