-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Downloaded a script from the iPython parallell computing examples in …
…the iPython documentation. The script calculates some statistics about the digits of Pi (up to 150 million, I think)
- Loading branch information
Tom Malone
committed
Oct 16, 2015
1 parent
a553ac9
commit 76e42e3
Showing
1 changed file
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
"""Compute statistics on the digits of pi. | ||
This uses precomputed digits of pi from the website | ||
of Professor Yasumasa Kanada at the University of | ||
Tokoyo: http://www.super-computing.org/ | ||
Currently, there are only functions to read the | ||
.txt (non-compressed, non-binary) files, but adding | ||
support for compression and binary files would be | ||
straightforward. | ||
This focuses on computing the number of times that | ||
all 1, 2, n digits sequences occur in the digits of pi. | ||
If the digits of pi are truly random, these frequencies | ||
should be equal. | ||
""" | ||
|
||
# Import statements | ||
from __future__ import division, with_statement | ||
|
||
import numpy as np | ||
from matplotlib import pyplot as plt | ||
|
||
try : #python2 | ||
from urllib import urlretrieve | ||
except ImportError : #python3 | ||
from urllib.request import urlretrieve | ||
|
||
# Top-level functions | ||
|
||
def fetch_pi_file(filename): | ||
"""This will download a segment of pi from super-computing.org | ||
if the file is not already present. | ||
""" | ||
import os, urllib | ||
ftpdir="ftp://pi.super-computing.org/.2/pi200m/" | ||
if os.path.exists(filename): | ||
# we already have it | ||
return | ||
else: | ||
# download it | ||
urlretrieve(ftpdir+filename,filename) | ||
|
||
def compute_one_digit_freqs(filename): | ||
""" | ||
Read digits of pi from a file and compute the 1 digit frequencies. | ||
""" | ||
d = txt_file_to_digits(filename) | ||
freqs = one_digit_freqs(d) | ||
return freqs | ||
|
||
def compute_two_digit_freqs(filename): | ||
""" | ||
Read digits of pi from a file and compute the 2 digit frequencies. | ||
""" | ||
d = txt_file_to_digits(filename) | ||
freqs = two_digit_freqs(d) | ||
return freqs | ||
|
||
def reduce_freqs(freqlist): | ||
""" | ||
Add up a list of freq counts to get the total counts. | ||
""" | ||
allfreqs = np.zeros_like(freqlist[0]) | ||
for f in freqlist: | ||
allfreqs += f | ||
return allfreqs | ||
|
||
def compute_n_digit_freqs(filename, n): | ||
""" | ||
Read digits of pi from a file and compute the n digit frequencies. | ||
""" | ||
d = txt_file_to_digits(filename) | ||
freqs = n_digit_freqs(d, n) | ||
return freqs | ||
|
||
# Read digits from a txt file | ||
|
||
def txt_file_to_digits(filename, the_type=str): | ||
""" | ||
Yield the digits of pi read from a .txt file. | ||
""" | ||
with open(filename, 'r') as f: | ||
for line in f.readlines(): | ||
for c in line: | ||
if c != '\n' and c!= ' ': | ||
yield the_type(c) | ||
|
||
# Actual counting functions | ||
|
||
def one_digit_freqs(digits, normalize=False): | ||
""" | ||
Consume digits of pi and compute 1 digit freq. counts. | ||
""" | ||
freqs = np.zeros(10, dtype='i4') | ||
for d in digits: | ||
freqs[int(d)] += 1 | ||
if normalize: | ||
freqs = freqs/freqs.sum() | ||
return freqs | ||
|
||
def two_digit_freqs(digits, normalize=False): | ||
""" | ||
Consume digits of pi and compute 2 digits freq. counts. | ||
""" | ||
freqs = np.zeros(100, dtype='i4') | ||
last = next(digits) | ||
this = next(digits) | ||
for d in digits: | ||
index = int(last + this) | ||
freqs[index] += 1 | ||
last = this | ||
this = d | ||
if normalize: | ||
freqs = freqs/freqs.sum() | ||
return freqs | ||
|
||
def n_digit_freqs(digits, n, normalize=False): | ||
""" | ||
Consume digits of pi and compute n digits freq. counts. | ||
This should only be used for 1-6 digits. | ||
""" | ||
freqs = np.zeros(pow(10,n), dtype='i4') | ||
current = np.zeros(n, dtype=int) | ||
for i in range(n): | ||
current[i] = next(digits) | ||
for d in digits: | ||
index = int(''.join(map(str, current))) | ||
freqs[index] += 1 | ||
current[0:-1] = current[1:] | ||
current[-1] = d | ||
if normalize: | ||
freqs = freqs/freqs.sum() | ||
return freqs | ||
|
||
# Plotting functions | ||
|
||
def plot_two_digit_freqs(f2): | ||
""" | ||
Plot two digits frequency counts using matplotlib. | ||
""" | ||
f2_copy = f2.copy() | ||
f2_copy.shape = (10,10) | ||
ax = plt.matshow(f2_copy) | ||
plt.colorbar() | ||
for i in range(10): | ||
for j in range(10): | ||
plt.text(i-0.2, j+0.2, str(j)+str(i)) | ||
plt.ylabel('First digit') | ||
plt.xlabel('Second digit') | ||
return ax | ||
|
||
def plot_one_digit_freqs(f1): | ||
""" | ||
Plot one digit frequency counts using matplotlib. | ||
""" | ||
ax = plt.plot(f1,'bo-') | ||
plt.title('Single digit counts in pi') | ||
plt.xlabel('Digit') | ||
plt.ylabel('Count') | ||
return ax |