Python interface

Seldon comes with a Python interface generated by Swig. In Seldon 5.0, the interface is limited: it only contains one vector structure (full vector, double precision) and one matrix structure (full row-major matrix, double precision). Extending the interface is easy, so a more complete interface is planned for version 5.1.

This page only addresses the compilation and the use of the interface under Linux. The generation of the interface was not tested on another platform yet. No known issue should prevent the interface from running successfully on another platform.

Compiling the interface

In addition to a C++ compiler, one needs Swig 1.3.x. Swig 1.1 cannot generate the interface. You will also need Python (say, 2.5 or 2.6, but previous versions should work too) and its headers.

In Seldon directory (root), you may simply launch scons if you have SCons installed (version >=1.0). You may also execute lines similar to those launched by SCons:

$ g++ -o Seldon.os -c -fPIC -DSELDON_DEBUG_LEVEL_4 \
  -I/usr/include/python2.6 Seldon.cpp
$ swig -o seldon_wrap.cc -Wall -c++ -python seldon.i
$ g++ -o seldon_wrap.os -c -fPIC -DSELDON_DEBUG_LEVEL_4 \
  -I/usr/include/python2.6 seldon_wrap.cc
$ g++ -o _seldon.so -shared Seldon.os seldon_wrap.os

This should generate the Python module seldon.py and the shared library _seldon.so. You may want to place these two files in a directory of your $PYTHONPATH, where Python searches for modules (in addition to the local directory .).

Using the interface

In Seldon directory (root), or in any place if seldon.py and _seldon.so are in a directory of $PYTHONPATH, you may launch Python and load the module.

It is recommended to use IPython instead of the regular Python shell, for convenience:

$ ls
SConstruct      Seldon.hxx  SeldonHeader.hxx  _seldon.so  computation/
Seldon.cpp      Seldon.os   SeldonSolver.hxx  array3d/    license
matrix/         seldon.i    seldon_wrap.cc    share/      vector/
matrix_sparse/  seldon.py   seldon_wrap.os    test/       version
$ ipython
Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18)
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import seldon

In [2]:

The module mainly provides VectorDouble and MatrixDouble. The former is the same as Vector<double, VectFull> and the latter is the same as Matrix<double, General, RowMajor>. Essentially all methods of these two classes are available. Example with VectorDouble:

In [1]: import seldon

In [2]: x = seldon.VectorDouble(5)

In [3]: x.Fill()

In [4]: x.Print()
0       1       2       3       4

In [5]: x.Reallocate(2)

In [6]: x.Print()
0       1

Example with MatrixDouble:

In [1]: from seldon import *

In [2]: M = MatrixDouble(3, 3)

In [3]: M.SetIdentity()

In [4]: M.Print()
1       0       0
0       1       0
0       0       1

In [5]: M.GetM()
Out[5]: 3

In [6]: M.GetM() * M.GetN()
Out[6]: 9

The main difference lies in the access operator: it is [] instead of (), to be consistent with NumPy conventions:

In [1]: import seldon

In [2]: x = seldon.VectorDouble(3)

In [3]: x[0] = 2.; x[1] = -1.; x[2] = 10.

In [4]: x.Print()
2       -1      10

In [5]: M = seldon.MatrixDouble(3, 3)

In [6]: M.SetIdentity()

In [7]: M[1, 0] = -5

In [8]: M.Print()
1       0       0
-5      1       0
0       0       1

In [8]: M[2, 2] + x[0]
Out[9]: 3.0

C++ exceptions are converted to Python exceptions:

In [2]: x = seldon.VectorDouble(3)

In [3]: x[3] = 2.
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)

/home/mallet/src/seldon/<ipython console> in <module>()

/home/mallet/src/seldon/seldon.pyc in __setitem__(*args)
   1091     def Read(*args): return _seldon.VectorDouble_Read(*args)
   1092     def __getitem__(*args): return _seldon.VectorDouble___getitem__(*args)
-> 1093     def __setitem__(*args): return _seldon.VectorDouble___setitem__(*args)
   1094     def __len__(*args): return _seldon.VectorDouble___len__(*args)
   1095 VectorDouble_swigregister = _seldon.VectorDouble_swigregister

Exception: ERROR!
Index out of range in Vector<VectFull>::operator().
   Index should be in [0, 2], but is equal to 3.

You can convert a vector or a matrix to a NumPy array:

In [1]: import seldon

In [2]: import numpy

In [3]: M = seldon.MatrixDouble(3, 3)

In [4]: M.Fill()

In [5]: M = numpy.array(M)

In [6]: M.shape
Out[6]: (3, 3)

In [7]: M
Out[7]:
array([[ 0.,  1.,  2.],
       [ 3.,  4.,  5.],
       [ 6.,  7.,  8.]])

In [8]: M.sum()
Out[8]: 36.0