Friday, November 27, 2015

Raspberry Pi - Computing Pi and Outputing Results Realtime w/ Python




Since I'm in the United States I was able to celebrate Thanksgiving.  One of my favorite parts of this day is eating pie.  Over the last couple weeks I've been comparing streaming algorithms that output Pi(the number) as it's calculated.  One handy python library I found was the PiDigits Library.  I was amazed at how well it did.  I also (through a lot of googling) found a couple more variations of those pi algorithms.  Of course I wanted to find the fastest.  I hopefully try to optimize it with the gmpy python library which handles very large numbers better.

  1. One I found here: https://github.com/DaveMDS/pigreco Gosper? algorithm? 
  2. And another here https://github.com/spmacdonald/pi_spigot 
  3. And another here https://github.com/CSC-IT-Center-for-Science/scalable-python/blob/master/Demo/scripts/pi.py Lambert


All of which I compared to the Pidigits python library and found a close winner between the

found the 3rd to be the quickest but really close to the first 1st.. I wrapped much of the equation with mpz functions (which handles large integers).

import gmpy

def pi_decimal_generator(): #gosper        
        global j
        q, r, t, j = mpz(1), mpz(180), mpz(60), 2        
        while 1:
            u, y = mpz(3*(3*j+1)*(3*j+2)), mpz((q*(27*j-12)+5*r)/(5*t))
            q, r, t, j = mpz((20*j**2-10*j)*q), mpz(10*u*(q*(5*j-2)+r-y*t)), mpz(t*u), j+1            
            yield int(y)

def pi_lambert_mpz(): 
    #lambert    
    k, a, b, a1, b1 = 2, mpz(4), mpz(1), mpz(12), mpz(4)
    while 1:
        p, q, k = mpz(k**2), mpz(2*k+1), (k+1)
        a, b, a1, b1 = mpz(a1), mpz(b1), mpz(p*a+q*a1), mpz(p*b+q*b1)
        d, d1 = mpz(a/b), mpz(a1/b1)
        while d == d1:
            yield int(d)
            a, a1 = mpz(10*(a%b)), mpz(10*(a1%b1))
            d, d1 = mpz(a/b), mpz(a1/b1)


Graph of 20,000 digits of before mpz and after (on a non overclocked Raspberry Pi 2):




You can see that adding mpz (from the gmpy python library) increased digit output by over double.

Lamberts and Gospers seemed really close so I did a calc to 100,000 digits normal CPU speed and overclocked to 1ghz.


Looks better right :-)


I then looked at my CPU and noticed it was only using one of the 4 Cores that the Pi 2 has :-(.

I doing my research on seeing if this can be split into multiple processes. But so far my attempts have been unsuccessful.  Maybe a reader(much smarter then myself) can help enlighten me on this quest.  Please comment and share.

Happy Thanksgiving weekend..