<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <hr style="border
Step1:  <hr style="border
Step2:  &nbsp;
<hr style="border
Step3:  &nbsp;
<hr style="border
Step4:  &nbsp;
<hr style="border
Step5:  &nbsp;
<hr style="border
Step6:  &nbsp;
<hr style="border
Step7:  <hr style="border
Step8:  &nbsp;
<hr style="border
Step9:  &nbsp;
<hr style="border
Step10:  <hr style="border
Step11:  &nbsp;
<hr style="border
Step12:  &nbsp;
<hr style="border
Step13:  &nbsp;
<hr style="border
Step14:  &nbsp;
<hr style="border
Step15:  &nbsp;
<hr style="border
Step16:  &nbsp;
<hr style="border
Step17:  <hr style="border
Step18:  <hr style="border
Step19:  <hr style="border
Step20:  <hr style="border
Step21:  <hr style="border
Step22:  <hr style="border
<ASSISTANT_TASK:>
Python Code:
# calculate pi
import numpy as np
# N : number of iterations
def calc_pi(N):
    x = np.random.ranf(N);
    y = np.random.ranf(N);
    r = np.sqrt(x*x + y*y);
    c=r[ r <= 1.0 ]
    return 4*float((c.size))/float(N)
# time the results
pts = 6; N = np.logspace(1,8,num=pts);
result = np.zeros(pts); count = 0;
for n in N:
    result = %timeit -o -n1 calc_pi(n) 
    result[count] = result.best
    count += 1
    
# and save results to file   
np.savetxt('calcpi_timings.txt', np.c_[N,results],
           fmt='%1.4e %1.6e');
Explanation: <hr style="border: solid 1px red; margin-bottom: -1% ">
NumPy <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; background-color:transparent;">
<hr style="border: solid 1px red; margin-top: 1.5% ">
Kevin Stratford  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a style="color: blue">kevin@epcc.ed.ac.uk</a><br>
Emmanouil Farsarakis &nbsp; &nbsp; <a style="color: blue">farsarakis@epcc.ed.ac.uk</a><br><br>
Other course authors: <br>
Neelofer Banglawala <br>
Andy Turner <br>
Arno Proeme <br>
<hr style="border: solid 1px red; margin-bottom: 2% ">
&nbsp;<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
<img src="reusematerial.png"; style="float: center; width: 90"; >
<hr style="border: solid 1px red; margin-bottom: 2% ">
&nbsp;<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: 1%; ">
<div align="center" style="float: center; color: blue;">
www.archer.ac.uk <br><br>
support@archer.ac.uk
</div>
<div>
<img src="epsrclogo.png"; style="float: left; width: 35%; margin-left: 20%; margin-top: 2% ">
<img src="nerclogo.png"; style="float: left; width: 25%; margin-left: 5%">
</div>
<br><br>
<br><br>
<div>
<img src="craylogo.png"; style="float: left; width: 30%; margin-left: 10%; margin-top: 6% ">
<img src="epcclogo.png"; style="float: left; width: 30%; margin-left: 5%; margin-top: 6% " >
<img src="ediunilogo.png"; style="float: left; width: 20%; margin-left: 5%; margin-top: 2% " > 
</div>
<br>
<br>
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Introducing NumPy <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
Core Python provides lists
Lists are slow for many numerical algorithms
NumPy provides fast precompiled functions for numerical routines:
multidimensional arrays : faster than lists
matrices and linear algebra operations
random number generation
Fourier transforms and much more... 
https://www.numpy.org/
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Calculating $\pi$  <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
<img src="montecarlo.png"; style="float: right; width: 40%; margin-right: 2%; margin-top: 0%; margin-bottom: -1%">
If we know the area $A$ of square length $R$, and the area $Q$ of the quarter circle with radius $R$, we can calculate $\pi$ : $ Q/A = \pi R^2/ 4 R^2  $, so 
$ \pi =  4\,Q/A $
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Calculating $\pi$ : monte carlo method <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
We can use the <i>monte carlo</i> method to determine areas $A$ and $Q$ and approximate $\pi$. For $N$ iterations
randomly generate the coordinates $(x,\,y)$, where $0 \leq \,x,\, y <R$ <br>
Calculate distance $ r = x^2 + y^2 $. Check if $(x,\,y)$ lies within radius of circle<br>
Check if $ r $ lies within radius $R$ of circle i.e. if $r \leq R $ <br>
if yes, add to count for approximating area of circle<br>
The numerical approximation of $\pi$ is then : 4 * (count/$N$)
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Calculating $\pi$ : a solution <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
End of explanation
# import numpy as alias np
import numpy as np
# create a 1d array with a list
a = np.array( [-1,0,1] ); a
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Creating arrays &nbsp; I <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# use arrays to create arrays
b = np.array( a ); b
# use numpy functions to create arrays 
# arange for arrays, range for lists!
a = np.arange( -2, 6, 2 ); a
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp;  Creating arrays &nbsp; II<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# between start, stop, sample step points
a = np.linspace(-10, 10, 5); 
a;
# Ex: can you guess these functions do?
b = np.zeros(3); print b
c = np.ones(3); print c
# Ex++: what does this do? Check documentation!
h = np.hstack( (a, a, a), 0 ); print h
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp;  Creating arrays &nbsp; III <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# array characteristics such as:
print a
print a.ndim  # dimensions
print a.shape # shape
print a.size  # size
print a.dtype # data type
# can choose data type
a = np.array( [1,2,3], np.int16 ); a.dtype
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Array characteristics   <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# multi-dimensional arrays e.g. 2d array or matrix 
# e.g. list of lists
mat = np.array( [[1,2,3], [4,5,6]]);
print mat; print mat.size; mat.shape
# join arrays along first axis (0)
d = np.r_[np.array([1,2,3]), 0, 0, [4,5,6]];
print d; d.shape
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Multi-dimensional arrays &nbsp; I <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# join arrays along second axis (1)
d = np.c_[np.array([1,2,3]), [4,5,6]];
print d; d.shape
# Ex: use r_, c_ with nd (n>1) arrays
# Ex: can you guess the shape of these arrays?
h = np.array( [1,2,3,4,5,6] ); 
i = np.array( [[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]] ); 
j = np.array( [[[1],[2],[3],[4],[5],[6]]] ); 
k = np.array( [[[[1],[2],[3],[4],[5],[6]]]] );
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Multi-dimensional arrays &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# reshape 1d arrays into nd arrays original matrix unaffected
mat = np.arange(6); print mat
print mat.reshape( (3, 2) )
print mat; print mat.size;
print mat.shape
# can also use the shape, this modifies the original array
a = np.zeros(10); print a
a.shape = (2,5)
print a; print a.shape;
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Reshaping arrays &nbsp; I<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# Ex: what do flatten() and ravel()? 
# use online documentation, or '?'
mat2 = mat.flatten()
mat2 = mat.ravel()
# Ex: split a martix? Change the cuts and axis values
# need help?: np.split?
cuts=2;
np.split(mat, cuts, axis=0)
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Reshaping arrays &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# Ex: can you guess what these functions do?
# np.copyto(b, a);
# v = np.vstack( (arr2d, arr2d) ); print v; v.ndim;
# c0 = np.concatenate( (arr2d, arr2d), axis=0); c0;
# c1 = np.concatenate(( mat, mat ), axis=1); print "c1:", c1;
# Ex++: other functions to explore
#
# stack(arrays[, axis])
# tile(A, reps)
# repeat(a, repeats[, axis])
# unique(ar[, return_index, return_inverse, ...])
# trim_zeros(filt[, trim]), fill(scalar)
# xv, yv = meshgrid(x,y)
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Functions for you to explore  <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# basic indexing and slicing we know from lists
a = np.arange(8); print a
a[3]
# a[start:stop:step] --> [start, stop every step)
print a[0:7:2]
print a[0::2]
# negative indices are valid! 
# last element index is -1
print a[2:-3:2]
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Accessing arrays &nbsp; I <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# basic indexing of a 2d array : take care of each dimension
nd = np.arange(12).reshape((4,3)); print nd;
print nd[2,2];
print nd[2][2];
# get corner elements 0,2,9,11
print nd[0:4:3, 0:3:2]
# Ex: get elements 7,8,10,11 that make up the bottom right corner
nd = np.arange(12).reshape((4,3)); 
print nd; nd[2:4, 1:3]
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Accessing arrays &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# slices are views (like references) 
# on an array, can change elements
nd[2:4, 1:3] = -1; nd
# assign slice to a variable to prevent this
s = nd[2:4, 1:3]; print nd; 
s = -1; nd
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Slices and copies &nbsp; I  <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# Care - simple assignment between arrays
# creates references!
nd = np.arange(12).reshape((4,3))
md = nd
md[3] = 1000
print nd
# avoid this by creating distinct copies
# using copy()
nd = np.arange(12).reshape((4,3))
md = nd.copy()
md[3] = 999
print nd
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp;  Slices and copies &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# advanced or fancy indexing lets you do more
p = np.array( [[0,1,2], [3,4,5], [6,7,8], [9,10,11]] ); 
print p
rows = [0,0,3,3]; cols = [0,2,0,2];
print p[rows, cols]
# Ex: what will this slice look like?
m = np.array( [[0,-1,4,20,99], [-3,-5,6,7,-10]] );
print m[[0,1,1,1], [1,0,1,4]];
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Fancy indexing &nbsp; I<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# can use conditionals in indexing
# m = np.array([[0,-1,4,20,99],[-3,-5,6,7,-10]]);
m[ m < 0 ]
# Ex: can you guess what this does? query: np.sum?
y = np.array([[0, 1], [1, 1], [2, 2]]);
rowsum = y.sum(1);
y[rowsum <= 2, :]
# Ex: and this? 
a = np.arange(10);
mask = np.ones(len(a), dtype = bool);
mask[[0,2,4]] = False; print mask
result = a[mask]; result
# Ex: r=np.array([[0,1,2],[3,4,5]]); 
xp = np.array( [[[1,11],[2,22],[3,33]], [[4,44],[5,55],[6,66]]] );
xp[slice(1), slice(1,3,None), slice(1)]; xp[:1, 1:3:, :1];
print xp[[1,1,1],[1,2,1],[0,1,0]]
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Fancy indexing &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# add an element with insert
a = np.arange(6).reshape([2,3]); print a
np.append(a, np.ones([2,3]), axis=0)
# inserting an array of elements
np.insert(a, 1, -10, axis=0)
# can use delete, or a boolean mask, to delete array elements
a = np.arange(10)
np.delete(a, [0,2,4], axis=0)
Explanation: &nbsp;
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Manipulating arrays  <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# vectorization allows element-wise operations (no for loop!)
a = np.arange(10).reshape([2,5]); b = np.arange(10).reshape([2,5]);
-0.1*a
a*b
a/(b+1)  #.astype(float)
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Vectorization &nbsp; I<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# random floats
a = np.random.ranf(10); a 
# create random 2d int array 
a = np.random.randint(0, high=5, size=25).reshape(5,5); 
print a;
# generate sample from normal distribution 
# (mean=0, standard deviation=1)
s = np.random.standard_normal((5,5)); s;
# Ex: what other ways are there to generate random numbers?
# What other distributions can you sample? 
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Random number generation <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# easy way to save data to text file
pts = 5; x = np.arange(pts); y = np.random.random(pts);
# format specifiers: d = int, f = float, e = scientific
np.savetxt('savedata.txt', np.c_[x,y], header = 'DATA', footer = 'END',
           fmt = '%d %1.4f')
!cat savedata.txt
# One could do ...
# p = np.loadtxt('savedata.txt')
# ...but much more flexibility with genfromtext
p = np.genfromtxt('savedata.txt', skip_header=2, skip_footer=1); p
# Ex++: what do numpy.save, numpy.load do ?
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; File IO <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# calculate pi using polynomials
# import Polynomial class 
from numpy.polynomial import Polynomial as poly;
num = 100000;
denominator = np.arange(num); 
denominator[3::4] *= -1 # every other odd coefficient is -ve
numerator = np.ones(denominator.size); 
# avoid dividing by zero, drop first element denominator
almost = numerator[1:]/denominator[1:]; 
# make even coefficients zero
almost[1::2] = 0
# add back zero coefficient
coeffs = np.r_[0,almost]; 
p = poly(coeffs);
4*p(1) # pi approximation
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Polynomials &nbsp; I<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
Can represent polynomials with the numpy class Polynomial from <i>numpy.polynomial.polynomial</i>.
Polynomial([a, b, c, d, e]) is equivalent to $p(x) = a\,+\,b\,x \,+\,c\,x^2\,+\,d\,x^3\,+\,e\,x^4$. <br>
For example: 
Polynomial([1,2,3]) is equivalent to $p(x) = 1\,+\,2\,x \,+\,3\,x^2$
Polynomial([0,1,0,2,0,3]) is equivalent to $p(x) = x \,+\,2\,x^3\,+\,3\,x^5 $
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Polynomials &nbsp; II<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
Can carry out arithmetic operations on polynomials, as well integrate and differentiate them.
Can also use the <i>polynomial</i> package to find a least-squares fit to data.
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Polynomials : calculating $\pi$ &nbsp; I <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
The Taylor series expansion for the trigonometric function $\arctan(y)$ is :<br>
&nbsp; &nbsp; &nbsp; $\arctan ( y) \, = \,y - \frac{y^3}{3} + \frac{y^5}{5}  - \frac{y^7}{7}  + \dots $
Now, $\arctan(1) = \frac{\pi}{4} $, so ...
&nbsp; &nbsp; &nbsp;$ \pi  = 4 \, \big( - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + ... \big) $
We can represent the series expansion using a numpy Polynomial, with coefficients: <br>
$p(x)$ = [0, &nbsp; 1, &nbsp;  0, &nbsp;  -1/3, &nbsp;  0, &nbsp;  1/5, &nbsp;  0, &nbsp;  -1/7,...], and use it to approximate $\pi$.
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Polynomials : calculating $\pi$ &nbsp; II <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
# accessing a 2d array
nd = np.arange(100).reshape((10,10))
# accessing element of 2d array
%timeit -n10000000 -r3 nd[5][5]
%timeit -n10000000 -r3 nd[(5,5)]
# Ex: multiplying two vectors
x=np.arange(10E7)
%timeit -n1 -r10 x*x
%timeit -n1 -r10 x**2
# Ex++: from the linear algebra package
%timeit -n1 -r10 np.dot(x,x) 
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Performance &nbsp; I <img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
Python has a convenient timing function called <i><b>timeit</b></i>. 
Can use this to measure the execution time of small code snippets.
To use timeit function
import module timeit and use <i><b>timeit.timeit</b></i>  or
use magic command <b>%timeit</b> in an IPython shell
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Performance &nbsp; II<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
By default, <i>timeit</i>:
Takes the best time out of 3 repeat tests (-r) 
takes the average time for a number of iterations (-n) per repeat 
In an IPython shell:
<i>%timeit &nbsp; <b>-n</b>&lt;iterations&gt; &nbsp; &nbsp;<b>-r</b>&lt;repeats&gt;  &nbsp; &nbsp;&lt;code&gt;</i>
query %timeit? for more information
https://docs.python.org/2/library/timeit.html
<hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Performance : experiments &nbsp; I<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
Here are some timeit experiments for you to run.
End of explanation
import numpy as np
# Ex: range functions and iterating in  for loops
size = int(1E6);
%timeit for x in range(size): x ** 2
# faster than range for very large arrays?
%timeit for x in xrange(size): x ** 2
%timeit for x in np.arange(size): x ** 2
%timeit np.arange(size) ** 2
# Ex: look at the calculating pi code 
# Make sure you understand it. Time the code.
Explanation: <hr style="border: solid 1px red; margin-bottom: 2% ">
[NumPy] &nbsp; Performance : experiments &nbsp; II<img src="headerlogos.png"; style="float: right; width: 25%; margin-right: -1%; margin-top: 0%; margin-bottom: -1%">
<hr style="border: solid 1px red; margin-bottom: -1%; ">
&nbsp;
End of explanation
<END_TASK>