Today I came across this wonderful little curiosity.

I was going to write a little Python program to try it out. Basically, we are creating two fibonacci sequences, one starting with 12, 18 and the other starting with 5, 5. At first I thought there will be nothing new here. Then I remembered that I was looking for a good example with which to demonstrate generator functions and I figured out that this would be a perfect example. Basically, we are looking for a function that each time we call it will generate the next fibonacci number in a sequence.

There is an example of such a Fibonacci function in an earlier post which I will repeat here:

def fibonacci():
    parent, baby = 1, 0

    while baby < 1000:
        print baby
            parent, baby = (parent + baby, parent)

In this case, we don’t want to print the fibonacci number, but want to return the next number in the series. We can do this with a generator function. A generator function is one that has the keyword yield. yield is like a return statement, except that the function remembers where we are and then the next time we call that function, we start from where we left off (or, in other words, directly after yield).

Here is our fibonacci generator:

def fibonacci(t1, t2):
while True:
    yield t1
    t1, t2 = t2, t1 + t2

fib = fibonacci(0, 1)
for i in range(10):
    print fib.next()

Running this we get:

0
1
1
2
3
5
8
13
21
34

Now comes the interesting part - we can create as many generators as we want, so here is our final program:

def fibonacci(t1, t2):
    while True:
        yield t1
        t1, t2 = t2, t1 + t2

lhs = fibonacci(12, 18)
rhs = fibonacci(5, 5)
for i in range(30):
    l = lhs.next()
    r = rhs.next()
    print '%10d %10d %8.7f' % (l, r, float(l) / r)

So, when I run it, I get the following results:

     12         5 2.4000000
     18         5 3.6000000
     30        10 3.0000000
     48        15 3.2000000
     78        25 3.1200000
    126        40 3.1500000
    204        65 3.1384615
    330       105 3.1428571
    534       170 3.1411765
    864       275 3.1418182

This looks promising and it seems to converge really quickly. So, lets run it for 20 iterations.

    12          5 2.4000000
    18          5 3.6000000
    30         10 3.0000000
    48         15 3.2000000
    78         25 3.1200000
    126        40 3.1500000
    204        65 3.1384615
    330       105 3.1428571
    534       170 3.1411765
    864       275 3.1418182
   1398       445 3.1415730
   2262       720 3.1416667
   3660      1165 3.1416309
   5922      1885 3.1416446
   9582      3050 3.1416393
  15504      4935 3.1416413
  25086      7985 3.1416406
  40590     12920 3.1416409
  65676     20905 3.1416408
 106266     33825 3.1416408

Well, that’s weird. It got really close to Pi (which, as far as I can remember is something like 3.1415927), but then it seems to wander off again. Well, maybe it oscillates for a while before settling down. So, let’s try 30 iterations (I will just record the last few lines of output).

    728358     231840 3.1416408
   1178508     375125 3.1416408
   1906866     606965 3.1416408
   3085374     982090 3.1416408
   4992240    1589055 3.1416408
   8077614    2571145 3.1416408
  13069854    4160200 3.1416408

Well, it seems that we’re not converging on Pi, but something very close to Pi.

Maybe I should have just stopped after 10 iterations. I marvelled at how the ratio between two fibonacci sequences would converge on Pi. Now I am a bit wiser, but also a bit sadder.