A Python Primer for Matlab Users
20/01/2013 by Bastian BechtoldWhy would you want to use Python over Matlab?
- Because Python is free and Matlab is not.
- Because Python is a general purpose programming language and Matlab is not.
Let me qualify that a bit. Matlab is a very useful programming environment for numerical problems. For a very particular set of problems, Matlab is an awesome tool. For many other problems however, it is just about unusable. For example, you would not write a complex GUI program in Matlab, you would not write your blogging engine in Matlab and you would not write a web service in Matlab. You can do all that and more in Python.
Python as a Matlab replacement
The biggest strength of Matlab is its matrix engine. Most of the data you work with in Matlab are matrices and there is a host of functions available to manipulate and visualize those matrices. Python, by itself, does not have a convenient matrix engine. However, there are three packages (think Matlab Toolboxes) out there that will add this capability to Python:
- Numpy (the matrix engine)
- Scipy (matrix manipulation)
- Matplotlib (plotting)
You can either grab the individual installers for Python, Numpy, Scipy and Matplotlib from their respective websites, or get them pre-packaged from pythonxy() or EPD.
A 30,000 foot overview
Like Matlab, Python is interpreted, that is, there is no need for a compiler and code can be executed at any time as long as Python is installed on the machine. Also, code can be copied from one machine to another and will run without change.
Like Matlab, Python is dynamically typed, that is, every variable can hold data of any type, as in:
# Python a = 5 # a number a = [1, 2, 3] # a list a = 'text' # a string
Contrast this with C, where you can not assign different data types to the same variable:
// C int a = 5; float b[3] = {1.0, 2.0, 3.0}; char c[] = "text";
Unlike Matlab, Python is strongly typed, that is, you can not add a number to a string. In Matlab, adding a single number to a string will convert that string into an array of numbers, then add the single number to each of the numbers in the array. Python will simply throw an error.
% Matlab a = 'text' b = a + 5 % [121 106 125 121]
# Python a = 'text' b = a + 5 # TypeError: Can't convert 'int' object to str implicitly
Unlike Matlab, every Python file can contain as many functions as you like. Basically, you can organize your code in as many files as you want. To access functions from other files, use import filename.
Unlike Matlab, Python is very quick to start. In fact, most operating systems automatically start a new Python process whenever you run a Python program and quit that process once the program has finished. Thus, every Python program behaves as if it indeed were an independent program. There is no need to wait for that big Matlab mother ship to start before writing or executing code.
Unlike Matlab, the source code of Python is readily available. Every detail of Python's inner workings is available to everyone. It is thus feasible and encouraged to actively participate in the development of Python itself or some add-on package. Furthermore, there is no dependence on some company deciding where to go next with Python.
Reading Python
When you start up Python, it is a rather empty environment. In order to do anything useful, you first have to import some functionality into your workspace. Thus, you will see a few lines of import statements at the top of every Python file. Moreover, Python has namespaces, so if you import numpy, you will have to prefix every feature of Numpy with its name, like this:
import numpy a = numpy.zeros(10, 1)
This is clearly cumbersome if you are planning to use Numpy all the time. So instead, you can import all of Numpy into the global environment like this:
from numpy import * a = ones(30, 1)
Better yet, there is a pre-packaged namespace that contains the whole Numpy-Scipy-Matplotlib stack in one piece:
from pylab import * a = randn(100, 1) plot(a) show()
Note that Python does not plot immediately when you type plot(). Instead, it will collect all plotting information and only show it on the screen once you type show().
So far, the code you have seen should look pretty familiar. A few differences:
-
No semicolons at the end of lines;
In order to print stuff to the console, use theprint()function instead. -
No
endanywhere.
In Python, blocks of code are identified by indentation and they always start with a colon like so:
sum = 0 for n in [1, 2, 3, 4, 5]: sum = sum + n print(sum)
- Function definitions are different.
They use thedefkeyword instead offunction.
You don't have to name the output variable names in the definition and instead usereturn().
# Python def abs(number): if number > 0: return number else: return -number
% Matlab function [out] = abs(number) if number > 0 out = number else out = -number end end
- There is no easy way to write out a list or matrix.
Since Python only gains a matrix engine by importing Numpy, it does not have a convenient way of writing arrays or matrices. This sounds more inconvenient than it actually is, since you are probably using mostly functions likezeros()orrandn()anyway and those work just fine. Also, many places accept Python lists (like this[1, 2, 3]) instead of Numpy arrays, so this rarely is a problem. Note that you must use commas to separate items and can not use semicolons to separate lines.
# create a numpy matrix: m = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # create a Python list: l = [1 2 3]
- Arrays access uses brackets and is numbered from 0.
Thus, ranges exclude the last number (see below).
Mostly, this just means that array access does not need any+1or-1when indexing arrays anymore.
a = linspace(1, 10, 10) one = a[0] two = a[1] # "6:8" is a range of two elements: a[6:8] = [70, 80] # <-- a Python list!
Common traps
- Array slicing does not copy.
a = array([1 2 3 4 5]) b = a[1:4] # [2 3 4] b[1] = rand() # this will change a and b! # make a copy like this: c = array(a[1:4], copy=True) # copy=True can be omitted c[1] = rand() # changes only c
- Arrays retain their data type.
You can slice them, you can dice them, you can do math on them, but a 16 bit integer array will never lose its data type. Use
new = array(old, dtype=double)to convert an array of any data type to the defaultdoubletype (like in Matlab).
# pretend this came from a wave file: a = array([1000, 2000, 3000, 4000, 5000], dtype=int16) a = a * 10 # int16 only goes to 32768! # a is now [10000, 20000, 30000, -25536, -15536]
Going further
Now you should be able to read Python code reasonably well. Numpy, Scipy and Matplotlib are actually modeled after Matlab in many ways, so many functions will have a very similar name and functionality. A lot of the numerical code you write in Python will look very similar to the equivalent code in Matlab. For a more in-depth comparison of Matlab and Python syntax, head over to the Numpy documentation for Matlab users.
However, since Python is a general purpose programming language, it offers some more tools. To begin with, there are a few more data types like associative arrays, tuples (unchangeable lists), proper strings and a full-featured object system. Then, there is a plethora of add-on packages, most of which actually come with your standard installation of Python. For example, there are internet protocols, GUI programming frameworks, real-time audio interfaces, web frameworks and game development libraries. Even this very blog is created using a Python static site generator.
Lastly, Python has a great online documentation site including a tutorial, there are many books on Python and there is a helpful Wiki on Python. There is also a tutorial and documentation for Numpy, Scipy and Matplotlib.
A great way to get to know any programming language is to solve the first few problems on project euler.
Real Time Signal Processing in Python
Wouldn't it be nice if you could do real time audio processing in a convenient programming language? Matlab comes to mind as a convenient language for signal processing. But while Matlab is pretty fast, it is really only fast for algorithms that can be vectorized. In audio however, we have many algorithms that need knowledge about the previous sample to calculate the next one, so they can't be vectorized.
But this is not going to be about Matlab. This is going to be about Python. Combine Python with Numpy (and Scipy and Matplotlib) and you have a signal ...
read moreAn error occurred loading this content. Try again later.
Since we moved, our Apple TV has been giving us trouble: we would rent a movie on the Apple TV, and instead of playing it, the Apple TV would just display
An error occurred loading this content. Try again later.
Rebooting, then trying again, would sometimes solve the issue. Trying to play a trailer before trying to play the movie seemed to increase chances of the Apple TV actually downloading the movie, too.
Finally, some forum or other pointed me to the correct solution: For some reason, the Apple TV did not play nice with our ISP DNS server. Simply ...
read moreNames
Names are everywhere in software. We name our variables, our functions, our arguments, classes, and packages. We name our source files and the directories that contain them. We name our jar files and war files and ear files. We name and name and name. Because we do so much of it, we'd better do it well.
-- from the Introduction to chapter 2 "Meaningful Names" of "Clean Code" by Robert C. Martin.
Indeed we name a lot of things in software. As The Structure and Interpretation of Computer Programs points out, the primary purpose of a function (lambda) is to ...
read moreMatlab, Mex, Homebrew and OS X 10.8 Mountain Lion
Now that I am a student again, I have to use Matlab again. Among the many joys of Matlab is the compilation of mex files.
Because it does not work. So angry.
Basically, mex does not work because it assumes that you have OS X 10.6 installed. In OS X 10.6 you had gcc-4.2 and your system SDK was stored in /Developer/SDKs/MacOSX10.6.sdk. However, as of 10.7 (I think), the /Developer directory has been deprecated in favor of distributing the whole development environment within the App package of XCode. Also, gcc has been ...
My Emacs customizations
I don't host my .emacs in a repository. I tried it for a while, but it did not work for me. I think repos are great for managing multiple divergent versions of the same source tree. However, my dotfiles should never diverge, they should just be kept in sync. This is what Dropbox is great at. So I use Dropbox instead of git.
One downside of that is that it is not as easy to provide a public link to my dotfiles. Or maybe it is. Here goes
Now on to the meat of this post: Some ...
read moreText editing with confidence and Emacs
In college, I realized for the first time how a good text editor could save me serious time, when I dragged an image file into Textmate and it auto-inserted all the LaTeX boilerplate for a figure. A few years later, on my first job, I learned Vim key bindings for Visual Studio because I hated text editing in Visual Studio so much. This showed me another way how a good text editor could save me serious time. A year after that, I was bored and tried Emacs. With Emacs, I discovered the marvelous world of REPLs and outlining.
Note that ...
read moreA Story about Schemes
Disclaimer: If you are a programmer, or wanting to be a programmer, or interested in programming, or, well, reading this, you should absolutely, positively watch the 1986 MIT lecture about The Structure and Interpretation of Computer Programs. (Most conveniently available here)
I tried reading the book numerous times, but it was too dry for my taste. The lecture however is juicy, brain-bending bliss. Especially if you don't know much functional programming yet. It certainly blew my mind. Frequently. Like, every ten minutes. Basically, I feel reborn as a programmer, with a new sense of what I am doing and ...
read moreKindle.app not starting on a case-sensitive file system
So Kindle.app was updated through the App Store and did not start any more. It just crashed and the crash reporter came up.
A quick look at Console.app turns up a link to the actual crash report. And the crash report starts with
Dyld Error Message: Library not loaded: @executable_path/../Frameworks/libWEbCoreKRF.dylib Referenced from: /Applications/Kindle.app/Contents/Frameworks/libWebCoreViewer.dylib Reason: image not found
libWEbCoreKRF.dylib? With a capitalized E? That looks very much like a spelling error. So, point your terminal to /Applications/Kindle.app/Contents/Frameworks/, type
sudo ln -s libWebCoreKRF.dylib libWEbCoreKRF.dylib ...
On the Virtue of Contributing to and Using Open Source Software
I am a mostly self-taught programmer. Apart from a few programming side jobs at the university, I have been programming professionally for the last two and a half years.
About two years ago, we wanted to buy a Matlab license for our company. However, our investors declined for dubious reasons. So I started looking for alternatives. Inspired by a good friend (thank you, Marc), I looked into Python. Python has this brilliant environment for numerical computation and plotting that, for my particular purposes, rivals Matlab.
However, just like Matlab, Python lacked a way of playing real time audio out of ...
read more