# Introduction IPython notebook, using compute $\pi$ example¶

To be read together with the slides (Hans Fangohr, FEEG6002, 2015)

We use a smaller number N in comparison to the slides as the convenient %timeit magic does a great job in obtaining meaningful timings for statements that execute fairly fast.

In [72]:
N = 100000

In [73]:
import math
def f(x):
return math.sqrt(1. - x * x)

def pi(n):
s = 0.5 * (f(-1) + f(1))
h = 2. / n
for i in range(1, n):
x = -1 + i * h
s += f(x)
return s * h * 2

In [74]:
tbase = %timeit -o pi(N)

10 loops, best of 3: 43 ms per loop


Note: we have execution time available in the variable tbase.best (in seconds):

In [75]:
tbase.best

Out[75]:
0.04304039478302002

## Inline function f¶

In [76]:
def pi_inline(n):
s = 0.5 * (f(-1) + f(1))
h = 2. / n
for i in range(1, n):
x = -1 + i * h
s += math.sqrt(1. - x * x)
return s * h * 2

In [77]:
tinline = %timeit -o pi_inline(N)

10 loops, best of 3: 32.2 ms per loop

In [78]:
print("inlined function code is {:5.1f} times faster than pure python ".format(
tbase.best / tinline.best))

inlined function code is   1.3 times faster than pure python


## Using Numpy¶

In [79]:
import numpy as np

In [80]:
def pi_numpy(n):
h = 2. / n
xs = np.linspace(-1, 1, n)
ys = np.sqrt(1 - xs * xs)
return np.sum(ys) * h * 2

In [81]:
tnumpy = %timeit -o pi_numpy(N)

1000 loops, best of 3: 720 µs per loop

In [82]:
print("numpy code is {:5.1f} times faster than pure python ".format(
tbase.best / tnumpy.best))

numpy code is  59.8 times faster than pure python


## Using weave¶

In [83]:
import scipy.weave as weave

In [84]:
def pi_weave(n):
my_C_code = """
double s=0;       /* this is C code */
double h=2./n;      /* in a string    */
double x;
long i;
for (i=1; i<n; i++) {
x = -1+i*h;
s += sqrt(1.-x*x);
}
return_val = s*h*2;  /* last line C code */
"""
return weave.inline(my_C_code, ['n'], compiler='gcc')

In [85]:
tweave = %timeit -o pi_weave(N)

1000 loops, best of 3: 548 µs per loop

In [86]:
print("weave code (essentially c) is {:5.1f} times faster than pure python ".format(
tbase.best / tweave.best))

weave code (essentially c) is  78.5 times faster than pure python


## Report results¶

In [87]:
results = {'simple' : tbase,
'inline_f': tinline,
'numpy' : tnumpy,
'weave' : tweave}

time_base = tbase.best
for method in results.keys():
time_ = results[method].best
print("{:10} took {:10.5f}ms, speed up of {:6.6f}".format(
method, time_*1000, time_base / time_ ))

simple     took   43.04039ms, speed up of 1.000000
inline_f   took   32.23901ms, speed up of 1.335041
numpy      took    0.72005ms, speed up of 59.773831
weave      took    0.54803ms, speed up of 78.535966


# Exercise¶

Try to change the number N to see how the speed up changes as the computation required changes. Can you explain what you see?