Documentation

OMPC is finally at a stage when you can start playing with it. At first you might want to have a look at the Examples page. It explains how and why OMPC works. The programs in the Examples section do not require anything but a working Python environment.

The stage of the development still doesn't allow you to use it as a replacement for MATLAB(R). This documentation is targeted at developers. It is more like something that is usually called a hacking guide.

Installation

First you will need a Python interpreter. The development and most of the testing is done with Python 2.5 (get it here).

Although my setup.py script is almost ready, I am still thinking about using alternative ways of installing OMPC, other than distutils and setuptools. OMPC will be changing rapidly now and I want to avoid issues with files left over from previous versions. I seriously recommend installing Mercurial.

To get the latest version of the package you could always get it in a zip file , tar.gz file or tar.bz2 file.
Downloading this package is equivalent to getting the newest version from the Mercurial repository.

hg clone https://www.bitbucket.org/juricap/ompc/

At the moment I am suggesting to work from within the directory that contains the ompc and ompclib directories. This means that after uncompressing the downloaded archive you should change into ompc-XXXXXXXXXXX.zip (ompc-2f62b3a16cd5.zip in my case). For example:

This is not much but numpy functions can be used after a small wrapper is written. It should be not difficult to start writing a wrapper after you look in the ompclib/ompclib_numpy.py file. Otherwise read the next section. Such a wrapper can look like this

It is essential that the data of the ._a member are stored in the memory in the FORTRAN order. This is for the sake of reusing MEX extensions. Numpy can be made to work with almost any order but the MEX extensions and other C-code that works with MATLAB(R) compatible arrays assumes one single way of memory storage.

One would say that it is best to use an existing popular numpy.ndarray as a numerical object of OMPC. I agree. The numpy.matrix class is an example how to do it. Numpy is a great module but some of its features make it very difficult to simply inherit from its base numerical object. One reason is that the numpy's FORTRAN order is not MATLAB(R)'s FORTRAN order (at least for arrays with more than 2 dimensions). This is because the order of dimensions in numpy and MATLAB(R) is different. To get 5 matrices each with 3 rows and 2 columns in numpy you do zeros((5,3,2)), in MATLAB(R) zeros(3,2,5). Notice that (3,2) has the same order in both packages but the rest of the dimension are named on different side of the dimension vector. This means that in numpy we have (..., d4, d3, rows, cols) but in MATLAB(R) (rows, cols, d3, d4, ...).

But printing such an array reveals what numpy thinks of such an array:

>>> print aarray([[[ 1., 1.],
[ 0., 0.]],

[[ 1., 1.],
[ 0., 0.]],

[[ 1., 1.],
[ 0., 0.]]])

However, the main reason why one cannot derive marray from ndarray is that ndarray does not support in-place resizing. Growing of ndarrays is possible only by recreating the whole object and proper interpretation. This is a design feature, numpy is very efficient in storage of slices of an array, upon slicing it creates views that share data with their parent bigger arrays. Should such parent array change itself there is I believe currently no way of telling all children to quickly copy the current data because their parent is going to change.

For the above reasons the presented marray does not inherit from another numerical object directly. Rather it holds its data in the ._a memebr variable. The _a member of an marray('double', (5,3,2)) currently simply holds an ndarray with shape (2,3,5) stored in the C-order. All the the numpy functions that are going to operate on the should therefore assume that the axes are reversed.

The following shows how such marray can be converted to a numpy array:

_ompc_base - is a decorator I use to make the function an OMPC top-level function. This means that it will be loaded into the workspace upon the import ompc statement. Using the decorator is equivalent to stating __ompc_all__ += ['find'].

mpl - is a reference to matplotlib (import pylab as mpl), I am reusing here a ready implementation of find from pylab.

cond._a - in this version the marray object is based on numpy's ndarray (more in the previous section).

A number of issues have to be taken care of by an m-function. In our example, the pylab's find returns 0-based indices, therefore we use mpl.find(...)+1.

MATLAB(R) "squeeze"s the last dimension. So a correct implementation of the m-function sum should be:

The import statement initiates a search for files including fiels with .m extension. OMPC translates scripts to .pym files automatically and tries to import them. The Examples page has 2 sections explaining how is it possible.

Translating scripts

Use the following command to translate a file called myscript.m:

ompc/ompcply.py myscript.m > myscript.pym

The generated myscript.pym is a perfectly valid Python script that can be run by:

python myscript pym

It requires only that import ompc is called before the script is interpreted and that the implementation of ompclib has the function used in this script.