## page was renamed from NumPy for Matlab Addicts
#format wiki
[[TableOfContents]]
= Introduction =
MATLAB® and !NumPy/!SciPy have a lot in common. But there are many differences. !NumPy and !SciPy were created to do numerical and scientific computing in the most natural way with Python, not to be MATLAB® clones. This page is intended to be a place to collect wisdom about the differences, mostly for the purpose of helping proficient MATLAB® users become proficient !NumPy and !SciPy users. NumPyProConPage is another page for curious people who are thinking of adopting Python with NumPy and SciPy instead of MATLAB® and want to see a list of pros and cons.
= Some Key Differences =
|| In MATLAB®, the basic data type is a multidimensional array of double precision floating point numbers. Most expressions take such arrays and return such arrays. Operations on the 2-D instances of these arrays are designed to act more or less like matrix operations in linear algebra. || In !NumPy the basic type is a multidimensional `array`. Operations on these arrays in all dimensionalities including 2D are elementwise operations. However, there is a special `matrix` type for doing linear algebra, which is just a subclass of the `array` class. Operations on matrix-class arrays are linear algebra operations. ||
|| MATLAB® uses 1 (one) based indexing. The initial element of a sequence is found using a(1). ''[#indexingNotes See note 'INDEXING']'' || Python uses 0 (zero) based indexing. The initial element of a sequence is found using a[0]. ||
|| MATLAB®'s scripting language was created for doing linear algebra. The syntax for basic matrix operations is nice and clean, but the API for adding GUIs and making full-fledged applications is more or less an afterthought. || !NumPy is based on Python, which was designed from the outset to be an excellent general-purpose programming language. While Matlab's syntax for some array manipulations is more compact than !NumPy's, !NumPy (by virtue of being an add-on to Python) can do many things that Matlab just cannot, for instance subclassing the main array type to do both array and matrix math cleanly. ||
|| In MATLAB®, arrays have pass-by-value semantics, with a lazy copy-on-write scheme to prevent actually creating copies until they are actually needed. Slice operations copy parts of the array. || In !NumPy arrays have pass-by-reference semantics. Slice operations are views into an array. ||
|| In MATLAB®, every function must be in a file of the same name, and you can't define local functions in an ordinary script file or at the command-prompt (inlines are not real functions but macros, like in C). || !NumPy code is Python code, so it has no such restrictions. You can define functions wherever you like. ||
|| MATLAB® has an active community and there is lots of [http://www.mathworks.com/matlabcentral/fileexchange code available for free]. But the vitality of the community is limited by MATLAB®'s cost; your MATLAB® programs can be run by only a few. || !NumPy/!SciPy also has an active community, based right here on this web site! It is smaller, but it is growing very quickly. In contrast, Python programs can be redistributed and used freely. See ["Topical Software"] for a listing of free add-on application software, ["Mailing Lists"] for discussions, and the rest of this web site for additional community contributions. We encourage your participation! ||
|| MATLAB® has an extensive set of optional, domain-specific add-ons ('toolboxes') available for purchase, such as for signal processing, optimization, control systems, and the whole !SimuLink® system for graphically creating dynamical system models. || There's no direct equivalent of this in the free software world currently, in terms of range and depth of the add-ons. However the list in ["Topical Software"] certainly shows a growing trend in that direction. ||
|| MATLAB® has a sophisticated 2-d and 3-d plotting system, with user interface widgets. || Addon software can be used with Numpy to make comparable plots to MATLAB®. [http://matplotlib.sourceforge.net/ Matplotlib] is a mature 2-d plotting library that emulates the MATLAB® interface. [http://pyqwt.sourceforge.net/ PyQwt] allows more robust and faster user interfaces than MATLAB®. And [http://code.enthought.com/projects/mayavi/docs/development/html/mayavi/mlab.html mlab], a "matlab-like" API based on [http://code.enthought.com/projects/mayavi/ Mayavi2], for 3D plotting of Numpy arrays. See the ["Topical Software"] page for more options, links, and details. There is, however, no definitive, all-in-one, easy-to-use, built-in plotting solution for 2-d and 3-d. This is an area where Numpy/Scipy could use some work. ||
|| MATLAB® provides a full development environment with command interaction window, integrated editor, and debugger. || Numpy does not have one standard IDE. However, the [http://ipython.scipy.org/ IPython] environment provides a sophisticated command prompt with full completion, help, and debugging support, and interfaces with the Matplotlib library for plotting and the Emacs/XEmacs editors. ||
|| MATLAB® itself costs thousands of dollars if you're not a student. The source code to the main package is not available to ordinary users. You can neither isolate nor fix bugs and performance issues yourself, nor can you directly influence the direction of future development. (If you are really set on Matlab-like syntax, however, there is [http://www.octave.org/ Octave], another numerical computing environment that allows the use of most Matlab syntax without modification.) || !NumPy and !SciPy are free (both beer and speech), whoever you are. ||
= 'array' or 'matrix'? Which should I use? =
== Short answer ==
'''Use arrays'''.
* They are the standard vector/matrix/tensor type of numpy. Many numpy function return arrays, not matrices.
* There is a clear distinction between element-wise operations and linear algebra operations.
* You can have standard vectors or row/column vectors if you like.
The only disadvantage of using the array type is that you will have to use `dot` instead of `*` to multiply (reduce) two tensors (scalar product, matrix vector multiplication etc.).
== Long answer ==
Numpy contains both an `array` class and a `matrix` class. The `array` class is intended to be a general-purpose n-dimensional array for many kinds of numerical computing, while `matrix` is intended to facilitate linear algebra computations specifically. In practice there are only a handful of key differences between the two.
* Operator `*`, `dot()`, and `multiply()`:
* For `array`, ''' '`*`' means element-wise multiplication''', and the `dot()` function is used for matrix multiplication.
* For `matrix`, ''' '`*`' means matrix multiplication''', and the `multiply()` function is used for element-wise multiplication.
* Handling of vectors (rank-1 arrays)
* For `array`, the '''vector shapes 1xN, Nx1, and N are all different things'''. Operations like `A[:,1]` return a rank-1 array of shape N, not a rank-2 of shape Nx1. Transpose on a rank-1 `array` does nothing.
* For `matrix`, '''rank-1 arrays are always upconverted to 1xN or Nx1 matrices''' (row or column vectors). `A[:,1]` returns a rank-2 matrix of shape Nx1.
* Handling of higher-rank arrays (rank > 2)
* `array` objects '''can have rank > 2'''.
* `matrix` objects '''always have exactly rank 2'''.
* Convenience attributes
* `array` '''has a .T attribute''', which returns the transpose of the data.
* `matrix` '''also has .H, .I, and .A attributes''', which return the conjugate transpose, inverse, and `asarray()` of the matrix, respectively.
* Convenience constructor
* The `array` constructor '''takes (nested) Python sequences as initializers'''. As in, `array([[1,2,3],[4,5,6]])`.
* The `matrix` constructor additionally '''takes a convenient string initializer'''. As in `matrix("[1 2 3; 4 5 6]")`.
There are pros and cons to using both:
* ''' `array` '''
* :) You can treat rank-1 arrays as ''either'' row or column vectors. `dot(A,v)` treats `v` as a column vector, while `dot(v,A)` treats `v` as a row vector. This can save you having to type a lot of transposes.
* <:( Having to use the `dot()` function for matrix-multiply is messy -- `dot(dot(A,B),C)` vs. `A*B*C`.
* :) Element-wise multiplication is easy: `A*B`.
* :) `array` is the "default" !NumPy type, so it gets the most testing, and is the type most likely to be returned by 3rd party code that uses !NumPy.
* :) Is quite at home handling data of any rank.
* :) Closer in semantics to tensor algebra, if you are familiar with that.
* :) ''All'' operations (`*`, `/`, `+`, `**` etc.) are elementwise
* ''' `matrix` '''
* :\ Behavior is more like that of MATLAB® matrices.
* <:( Maximum of rank-2. To hold rank-3 data you need `array` or perhaps a Python list of `matrix`.
* <:( Minimum of rank-2. You cannot have vectors. They must be cast as single-column or single-row matrices.
* <:( Since `array` is the default in !NumPy, some functions may return an `array` even if you give them a `matrix` as an argument. This shouldn't happen with !NumPy functions (if it does it's a bug), but 3rd party code based on !NumPy may not honor type preservation like !NumPy does.[[BR]]
* :) `A*B` is matrix multiplication, so more convenient for linear algebra.
* <:( Element-wise multiplication requires calling a function, `multipy(A,B)`.
* <:( The use of operator overloading is a bit illogical: `*` does not work elementwise but `/` does.
The `array` is thus much more advisable to use, but in the end, you don't really have to choose one or the other. You can mix-and-match. You can use `array` for the bulk of your code, and switch over to `matrix` in the sections where you have nitty-gritty linear algebra with lots of matrix-matrix multiplications.
= Facilities for Matrix Users =
Numpy has some features that facilitate the use of the `matrix` type, which hopefully make things easier for Matlab converts.
* A `matlib` module has been added that contains matrix versions of common array constructors like `ones()`, `zeros()`, `empty()`, `eye()`, `rand()`, `repmat()`, etc. Normally these functions return `array`s, but the `matlib` versions return `matrix` objects.
* `mat` has been changed to be a synonym for `asmatrix`, rather than `matrix`, thus making it concise way to convert an `array` to a `matrix` without copying the data.
* Some top-level functions have been removed. For example `numpy.rand()` now needs to be accessed as `numpy.random.rand()`. Or use the `rand()` from the `matlib` module. But the "numpythonic" way is to use `numpy.random.random()`, which takes a tuple for the shape, like other numpy functions.
= Table of Rough MATLAB-NumPy Equivalents =
The table below gives rough equivalents for some common MATLAB® expressions. '''These are not exact equivalents''', but rather should be taken as hints to get you going in the right direction. For more detail read the built-in documentation on the NumPy functions.
Some care is necessary when writing functions that take arrays or matrices as arguments --- if you are expecting an `array` and are given a `matrix`, or vice versa, then '*' (multiplication) will give you unexpected results. You can convert back and forth between arrays and matrices using
* '''`asarray`''': always returns an object of type `array`
* '''`asmatrix`''' or '''`mat`''': always return an object of type `matrix`
* '''`asanyarray`''': always returns an `array` object or a subclass derived from it, depending on the input. For instance if you pass in a `matrix` it returns a `matrix`.
These functions all accept both arrays and matrices (among other things like Python lists), and thus are useful when writing functions that should accept any array-like object.
In the table below, it is assumed that you have executed the following commands in Python:
{{{
#!python numbers=off
from numpy import *
import scipy as Sci
import scipy.linalg
}}}
Also assume below that if the Notes talk about "matrix" that the arguments are rank 2 entities.
'''THIS IS AN EVOLVING WIKI DOCUMENT. If you find an error, or can fill in an empty box, please fix it! If there's something you'd like to see added, just add it.'''
== General Purpose Equivalents ==
|| '''MATLAB''' ||||