Numerical Computing in Python: A Guide For Matlab Users
Numerical Computing in Python: A Guide For Matlab Users
B. Blais
Abstract
Matlab is a commercial program used extensively in the scientific and business communities. There
are many reasons why it is very popular, including its interactive structure, clean syntax, and ability
to interface with fast compiled languages, like C. It also has many routines for signal and image
processing, optimization, and visualization.
Python is a modern language used extensively by Google and NASA, as well as many others. Like
Matlab, it also has an interactive structure, clean syntax, and the ability to interface with fast
compiled languages, like C. There are modules in Python for doing numerical work and
visualization, and thus one can make a Python-based computational environment with much the
same feel as Matlab. Python is also free, is far more versatile, and can be used in many more
applications than Matlab, including robotics, web frameworks, text processing, and others. It is
particularly good as a first language, and I have found it personally very useful in my classes.
Outline
1 Introduction
2 Comparison with Matlab
3 Advantages
4 Extensions with Pyrex
5 Communication
6 Conclusions
What is Python?
def sinc(x):
’’’Compute the sinc function:
sin(pi*x)/(pi*x)’’’
try:
val = (x*pi)
return sin(val)/val
except ZeroDivisionError:
return 1.0
print output
Minimum
python - the base language
numpy - array class, numerical routines
scipy - higher level scientific routines (de-
pends on numpy)
matplotlib - visualization
ipython - a more flexible python shell
Minimum
python - the base language
numpy - array class, numerical routines
scipy - higher level scientific routines (de-
pends on numpy)
matplotlib - visualization
ipython - a more flexible python shell
Minimum
python - the base language
numpy - array class, numerical routines
scipy - higher level scientific routines (de-
pends on numpy)
matplotlib - visualization
ipython - a more flexible python shell
Minimum
python - the base language
numpy - array class, numerical routines
scipy - higher level scientific routines (de-
pends on numpy)
matplotlib - visualization
ipython - a more flexible python shell
Minimum
python - the base language
numpy - array class, numerical routines
scipy - higher level scientific routines (de-
pends on numpy)
matplotlib - visualization
ipython - a more flexible python shell
Useful
pyrex - writing fast compiled extensions
(like cmex, but way better)
wxpython - GUI library
pywin32 - Windows COM Interface
BeautifulSoup - HTML Parser
xlrd, pyXLWriter - Reading/Writing Excel Spread-
sheets
Useful
pyrex - writing fast compiled extensions
(like cmex, but way better)
wxpython - GUI library
pywin32 - Windows COM Interface
BeautifulSoup - HTML Parser
xlrd, pyXLWriter - Reading/Writing Excel Spread-
sheets
Useful
pyrex - writing fast compiled extensions
(like cmex, but way better)
wxpython - GUI library
pywin32 - Windows COM Interface
BeautifulSoup - HTML Parser
xlrd, pyXLWriter - Reading/Writing Excel Spread-
sheets
Useful
pyrex - writing fast compiled extensions
(like cmex, but way better)
wxpython - GUI library
pywin32 - Windows COM Interface
BeautifulSoup - HTML Parser
xlrd, pyXLWriter - Reading/Writing Excel Spread-
sheets
Useful
pyrex - writing fast compiled extensions
(like cmex, but way better)
wxpython - GUI library
pywin32 - Windows COM Interface
BeautifulSoup - HTML Parser
xlrd, pyXLWriter - Reading/Writing Excel Spread-
sheets
function f=c2f(c)
f=(180/100)*c+32;
def c2f(c):
return (180.0/100.0)*c+32
B. Blais Numerical Computing in Python
Initial Comparison
Introduction
Getting Help
Comparison With Matlab
Golden Ratio
Advantages
Fibonacci
Extensions with Pyrex
Finance
Communication
Optimization and Least Squares
Interactive Environment
a =
100
>> b=c2f(-40)
b =
-40
Interactive Environment
In [2]:a=f2c(212)
In [3]:a
Out[3]:100.0
In [4]:b=c2f(-40)
In [5]:b
Out[5]:-40.0
Interactive Environment
Object-oriented or Procedural
In [7]:import convert
In [8]:a=convert.f2c(212)
In [9]:a
Out[9]:100.0
In [10]:dir(convert)
Out[10]:[’__builtins__’, ’__doc__’,
’__file__’, ’__name__’,
’c2f’, ’f2c’]
Interactive Environment
Object-oriented or Procedural
In [1]:from Temperature import *
In [2]:t=Temperature(f=32)
In [3]:print t.c
0.0
In [4]:print t.k
273.15
In [5]:t.c=-40
In [6]:t.k
Out[6]:233.14999999999998
In [7]:t.f
Out[7]:-40.0
In [8]:t.k=350
In [9]:t.c
Out[9]:76.850000000000023
In [10]:t.f
Out[10]:170.33000000000004
Interactive Environment
Object-oriented or Procedural
class Temperature(object):
coefficients = {’c’: (1.0, 0.0, -273.15), ’f’: (1.8, -273.15, 32.0)}
def __init__(self, **kwargs):
try:
name, value = kwargs.popitem( )
except KeyError:
name, value = ’k’, 0
setattr(self, name, float(value))
def __getattr__(self, name):
try:
eq = self.coefficients[name]
except KeyError:
raise AttributeError, name
return (self.k + eq[1]) * eq[0] + eq[2]
def __setattr__(self, name, value):
if name in self.coefficients:
# name is c or f -- compute and set k
eq = self.coefficients[name]
self.k = (value - eq[2]) / eq[0] - eq[1]
elif name == ’k’:
object.__setattr__(self, name, value)
else:
raise AttributeError, name
Interactive Environment
Object-oriented or Procedural
In [1]:from Temperature import *
In [2]:t=Temperature(f=32)
In [3]:print t.c
0.0
In [4]:print t.k
273.15
In [5]:t.c=-40
In [6]:t.k
Out[6]:233.14999999999998
In [7]:t.f
Out[7]:-40.0
In [8]:t.k=350
In [9]:t.c
Out[9]:76.850000000000023
In [10]:t.f
Out[10]:170.33000000000004
Getting Help
...
Getting Help
...
Getting Help
...
Getting Help
Namespace is important for getting Help
In [19]:import scipy
In [20]:help(scipy)
NAME
scipy
FILE
/usr/local/lib/python2.5/site-packages/scipy/__init__.py
DESCRIPTION
SciPy --- A scientific computing package for Python
===================================================
...
Available subpackages
---------------------
ndimage --- n-dimensional image package [*]
stats --- Statistical Functions [*]
signal --- Signal Processing Tools [*]
...
Help
In [16]:help(d)
Help on function fft in module numpy.fft.fftpack:
Help
In [16]:help(d)
Help on function fft in module numpy.fft.fftpack:
Zen
In [23]:import this
The Zen of Python, by Tim Peters
Golden Ratio
Matlab Python
function goldfract(n) def goldfract(N):
%GOLDFRACT Golden ratio continued """GOLDFRACT(N)
% fraction. Golden ratio continued fraction
% GOLDFRACT(n) displays n terms. Displays N terms."""
p = ’1’; p = ’1.0’
for k = 1:n for k in range(N):
p = [’1+1/(’ p ’)’]; p = ’1.0+1.0/(’ +p+ ’)’
end print p
p
p = 1; p = 1
q = 1; q = 1
for k = 1:n for k in range(N):
s = p; s = p
p = p + q; p = p + q
q = s; q = s
end
print ’%d/%d’ % (p,q)
p = sprintf(’%d/%d’,p,q) p=’%f/%f’ % (p,q) # use floats
format long p=eval(p)
p = eval(p) print "%.20f" % p
format short err = (1+sqrt(5))/2 - p
err = (1+sqrt(5))/2 - p print err
Fibonacci
Matlab Python
function f = fibonacci(n) def fibonacci(n):
% FIBONACCI Fibonacci sequence """FIBONACCI Fibonacci sequence
% f = FIBONACCI(n) generates the """
% first n Fibonacci numbers. from numpy import zeros
f=zeros(n)
f = zeros(n,1); f[0] = 1
f(1) = 1; f[1] = 2
f(2) = 2; for k in range(2,n):
for k = 3:n f[k]=f[k-1]+f[k-2]
f(k) = f(k-1) + f(k-2);
end return f
Fibonacci
Python: Array
def fibonacci(n): Python: List
"""FIBONACCI Fibonacci sequence
def fibonacci2(n):
"""
"""FIBONACCI Fibonacci sequence
from numpy import zeros
"""
f=zeros(n)
f=[1,2] # use a list
f[0] = 1
for k in range(2,n):
f[1] = 2
f.append(f[k-1]+f[k-2])
for k in range(2,n):
f[k]=f[k-1]+f[k-2]
return f
return f
Financial Data
Get the Data
import scipy
import os
import urllib
import datetime
fname=’my_yahoo_data.csv’
if not os.path.exists(fname):
url=’http://ichart.finance.yahoo.com/table.csv?s=%%5EIXIC&d=%d&e=%d&f=%d&g=d&a=%d&b=%d&c=%
print url
f = urllib.urlopen(url)
k=open(fname,"wt")
st=f.read()
k.write(st)
k.close()
f.close()
Date,Open,High,Low,Close,Volume,AdjB.Close
Blais Numerical Computing in Python
Initial Comparison
Introduction
Getting Help
Comparison With Matlab
Golden Ratio
Advantages
Fibonacci
Extensions with Pyrex
Finance
Communication
Optimization and Least Squares
Financial Data
Date,Open,High,Low,Close,Volume,Adj Close
2007-04-25,2533.54,2551.39,2523.84,2547.89,2644120000,2547.89
2007-04-24,2528.39,2529.48,2509.26,2524.54,2220610000,2524.54
2007-04-23,2525.77,2531.40,2518.47,2523.67,1928530000,2523.67
...
val=float(line.split(’,’)[-1])
vals.append(val) # last value
date=line.split(’,’)[0].split(’-’)
dint=[int(x) for x in date] # convert to ints
dateval=datetime.date(dint[0],dint[1],dint[2]).toordinal()
dates.append(dateval) # first value
Financial Data
Plot the Data
clf()
# plot the data
plot_date(dates,vals,’-o’)
p=scipy.polyfit(dates,vals,1)
x=arange(min(dates),max(dates),1)
y=p[0]*x+p[1]
plot(x,y,’r--’,linewidth=3)
N−1
X
2
f (x) = 100(xi − xi−1 )2 + (1 − xi−1 )2
i=1
Minimum at x0 = x1 = . . . = 1
Perform the Optimization
from scipy.optimize import fmin
def rosen(x): # The Rosenbrock function
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
N−1
X
2
f (x) = 100(xi − xi−1 )2 + (1 − xi−1 )2
i=1
Minimum at x0 = x1 = . . . = 1
Perform the Optimization
from scipy.optimize import fmin
def rosen(x): # The Rosenbrock function
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
N−1
X
2
f (x) = 100(xi − xi−1 )2 + (1 − xi−1 )2
i=1
Minimum at x0 = x1 = . . . = 1
Perform the Optimization
from scipy.optimize import fmin
def rosen(x): # The Rosenbrock function
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
x=linspace(0,6e-2,100)
A,k,theta = 10, 1.0/3e-2, pi/6
y_true = A*sin(2*pi*k*x+theta)
y_meas = y_true + 2*randn(len(x))
Matlab Python
help spam import spam
help(spam)
Matlab Python
a=[1 2 3 ; 4 5 6] from numpy import *
a=mat(’[1 2 3 ; 4 5 6]’)
a=matrix([ [1,2,3] , [4,5,6] ])
Matlab Python
help spam import spam
help(spam)
Matlab Python
a=[1 2 3 ; 4 5 6] from numpy import *
a=mat(’[1 2 3 ; 4 5 6]’)
a=matrix([ [1,2,3] , [4,5,6] ])
Matlab Python
help spam import spam
help(spam)
Matlab Python
a=[1 2 3 ; 4 5 6] from numpy import *
a=mat(’[1 2 3 ; 4 5 6]’)
a=matrix([ [1,2,3] , [4,5,6] ])
Matlab Python
a=1:10 from numpy import *
a=r_[1:11] # 1 minus last number
b=linspace(1,10,10)
b=linspace(1,10,10) # better way
Matlab Python
% run my script with some commands # in ipython
myscript; run myscript.py
Matlab Python
a=1:10 from numpy import *
a=r_[1:11] # 1 minus last number
b=linspace(1,10,10)
b=linspace(1,10,10) # better way
Matlab Python
% run my script with some commands # in ipython
myscript; run myscript.py
Matlab Python
x=-10:10 from pylab import *
y=x.^2 from numpy import *
plot(x,y,’-o’)
x=linspace(-10,10,20)
y=x**2
plot(x,y,’-o’)
show()
Matlab Python
a=[1 2 3; 4 5 6; 7 8 9] from numpy import *
b=[10 20 30; 40 50 60; 70 80 90] # two choices: matrix or array class
a=array(a)
b=array(b)
Matlab Python
a=sqrt(2) % built-in import math
import mymath
% uses first fmin in path
fmin(’cos’,3,4) a=math.sqrt(2)
b=mymath.sqrt(2)
Matlab Python
a=sqrt(2) % built-in import math
import mymath
% uses first fmin in path
fmin(’cos’,3,4) a=math.sqrt(2)
b=mymath.sqrt(2)
Matlab Python
a=sqrt(2) % built-in import math
import mymath
% uses first fmin in path
fmin(’cos’,3,4) a=math.sqrt(2)
b=mymath.sqrt(2)
Matlab Python
a=sqrt(2) % built-in import math
import mymath
% uses first fmin in path
fmin(’cos’,3,4) a=math.sqrt(2)
b=mymath.sqrt(2)
Data Types
datetime: Basic date and time types
calendar: General calendar-related functions
collections: High-performance container datatypes
heapq: Heap queue algorithm
bisect: Array bisection algorithm
array: Efficient arrays of numeric values
Data Types
datetime: Basic date and time types
calendar: General calendar-related functions
collections: High-performance container datatypes
heapq: Heap queue algorithm
bisect: Array bisection algorithm
array: Efficient arrays of numeric values
File Formats
csv: CSV File Reading and Writing
ConfigParser: Configuration file parser
robotparser: Parser for robots.txt
netrc: netrc file processing
xdrlib: Encode and decode XDR data
Multimedia Services
audioop: Manipulate raw audio data
imageop: Manipulate raw image data
aifc: Read and write AIFF and AIFC files
sunau: Read and write Sun AU files
wave: Read and write WAV files
chunk: Read IFF chunked data
colorsys: Conversions between color systems
rgbimg: Read and write "cSGI RGB"d files
imghdr: Determine the type of an image
sndhdr: Determine type of sound file
ossaudiodev: Access to OSS-compatible audio devices
Development Tools
pydoc: Documentation generator and online help system
doctest: Test interactive Python examples
unittest: Unit testing framework
Factorial
Pyrex
Python
def factorial(int n):
def factorial(n): cdef int i
cdef double x
x=1
for i in range(1,n+1): x=1
x=x*i for i from 1 <= i <= n:
x=x*i
return x
return x
Factorial
Pyrex
Python
def factorial(int n):
def factorial(n): cdef int i
cdef double x
x=1
for i in range(1,n+1): x=1
x=x*i for i from 1 <= i <= n:
x=x*i
return x
return x
Compiling
Setup
from pyrex_compile import *
compile(’factorial_pyrex.pyx’)
Test
In [1]:import factorial_python as python
In [2]:import factorial_pyrex as pyrex
In [3]:%timeit python.factorial(200)
1000 loops, best of 3: 319 microsec per loop
In [4]:%timeit pyrex.factorial(200)
100000 loops, best of 3: 4.17 microsec per loop
Compiling
Setup
from pyrex_compile import *
compile(’factorial_pyrex.pyx’)
Test
In [1]:import factorial_python as python
In [2]:import factorial_pyrex as pyrex
In [3]:%timeit python.factorial(200)
1000 loops, best of 3: 319 microsec per loop
In [4]:%timeit pyrex.factorial(200)
100000 loops, best of 3: 4.17 microsec per loop
C-API
Headers
/* Generated by Pyrex 0.9.5.1a on Sat Apr 28 11:15:48 2007 */
#include "Python.h"
#include "structmember.h"
#ifndef PY_LONG_LONG
#define PY_LONG_LONG LONG_LONG
#endif
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
__PYX_EXTERN_C double pow(double, double);
C-API
Translation
int __pyx_v_n;
int __pyx_v_i;
double __pyx_v_x;
PyObject *__pyx_r;
PyObject *__pyx_1 = 0;
static char *__pyx_argnames[] = {"n",0};
if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "i",
__pyx_argnames, &__pyx_v_n)) return 0;
/* "/home/bblais/tex/bryant/facdev/spring2007/src/factorial_pyrex.pyx":5 */
__pyx_v_x = 1;
/* "/home/bblais/tex/bryant/facdev/spring2007/src/factorial_pyrex.pyx":6 */
for (__pyx_v_i = 1; __pyx_v_i <= __pyx_v_n; ++__pyx_v_i) {
/* "/home/bblais/tex/bryant/facdev/spring2007/src/factorial_pyrex.pyx":7 */
__pyx_v_x = (__pyx_v_x * __pyx_v_i);
}
/* "/home/bblais/tex/bryant/facdev/spring2007/src/factorial_pyrex.pyx":9 */
__pyx_1 = PyFloat_FromDouble(__pyx_v_x); if (!__pyx_1) {__pyx_filename =
__pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
__pyx_r = __pyx_1;
__pyx_1 = 0;
Watch Out!
Test
In [1]:import factorial_python as python
In [3]:%timeit python.factorial(200)
1000 loops, best of 3: 319 microsec per loop
In [4]:%timeit pyrex.factorial(200)
100000 loops, best of 3: 4.17 microsec per loop
Watch Out!
Test
In [1]:import factorial_python as python
In [3]:%timeit python.factorial(200)
1000 loops, best of 3: 319 microsec per loop
In [4]:%timeit pyrex.factorial(200)
100000 loops, best of 3: 4.17 microsec per loop
In [5]:pyrex.factorial(200)
Out[5]:inf
In [6]:python.factorial(200)
Out[6]:7886578673647905035523632139321850622951359776871732632947425332443
59449963403342920304284011984623904177212138919638830257642790242637105061
92662495282993111346285727076331723739698894392244562145166424025403329186
41312274282948532775242424075739032403212574055795686602260319041703240623
51700858796178922222789623703897374720000000000000000000000000000000000000
000000000000L
N=1
for i from 0<=i<nd: # calculate number of elements
N=N*A.dimensions[i]
p=<double *>A.data
result=0.0
for i from 0<=i<N:
result=result+p[i]**2
return result
Testing
In [1]:from numpy.random import rand
In [2]:from pyrex_numpy import spam
In [3]:a=rand(2,3,4)
In [4]:a
Out[4]:
array([[[ 0.41275586, 0.40248059, 0.52365634, 0.13457172],
[ 0.10361721, 0.07592018, 0.50031702, 0.65126816],
[ 0.09734859, 0.82231387, 0.74795067, 0.48530395]],
In [5]:a.shape
Out[5]:(2, 3, 4)
In [6]:spam(a)
Out[6]:5.481696128900011
In [7]:(a**2).sum()
Out[7]:5.4816961289
In [8]:%timeit spam(a)
1000000 loops, best of 3: 465 ns per loop
In [9]:%timeit (a**2).sum()
10000 loops, best of 3: 31.2 microsec per loop
mlabwrap.py
Communicating with
Matlab
from mlabwrap import mlab
from numpy import *
mlab.xlabel(’This’)
mlab.ylabel(’That’)
mlab.title(’Something Interesting’)
mlab.zlabel(’Value’)
a=mlab.svd(array([[1,2], [1,3]]))
print a
# Run:
In [44]:run test_mlab.py
[[ 3.86432845]
[ 0.25877718]]
rpy.py
Communicating with R
# Simple script for drawing the chi-squared density
#
from rpy import *
degrees = 4
grid = r.seq(0, 10, length=100)
values = [r.dchisq(x, degrees) for x in grid]
r.par(ann=0)
r.plot(grid, values, type=’lines’)
xlrd.py
Conclusions
Questions?