The NumPtr Module

Why?

Imagine that you have some Python code that needs to do some quick number crunching. After prototyping the algorithm in Python you find that it is far too slow for your purposes. To produce results faster you rewrite the algorithm in C. However, you would still like to have access to the data in Python as well. There are a number of reasons that you might need access to the data in both C and Python. Perhaps you need to generate the data in C and then simply access it in Python to format it and display in on a webpage or otherwise visualize the data. Perhaps you generate the dataset in Python and simply want to leverage C to get some of your calculations finished a bit faster.

Whatever the reasoning, an easy way to make your C code accessible from Python is by using SWIG. Earlier I show an example of a way to use Numeric Arrays with C code. However, this requires manually writing C extensions which is often a hassle when you have a large amount of C code you'd like to wrap and use from Python. To speed up the process you can use SWIG.

However, SWIG does not handle C arrays very gracefully.

NumPtr ( download NumPtr-1.1.tar.gz ) is a simple module that can take a Numeric array and return a SWIG-understandable pointer to that arrays data, allowing you to access that array normally in your SWIG'ed C code.

An Example

Let's do a quick example. Assume we have a file "average.c" which contains a single function "double ave( int n, double *array );". "ave" takes a single argument, an array of doubles, and returns a single result(also a double). We would swig this code with the following interface file:


/* file: average.i */
%module average
%{
extern double ave( int n, double *array );
%}
%include average.c

The C Code that defines ave might look like:

average.c
#include <stdio.h>
#include <stdlib.h>

double ave( int n, double *array );

double ave( int n, double *array )
{
  int i;
  double sum;
  for( i = 0; i < n; i++ )
  {
    sum += array[i];
  } 
  return (double)( sum / n );
}


syntax highlighted by Code2HTML, v. 0.9.1

You could access this average function like this:

/home/steder/Projects/Tutorials/python/BobChat-v0.3/BobClient.py
# An example using NumPtr and Numeric to interface with SWIG'ed code:

import Numeric
import NumPtr

# import swig'ed module:
import average

# Create a numeric array that we want to compute the average of:
A = Numeric.array( range(1, 100), Numeric.Float64 )

# Get a pointer to this array:
aptr = NumPtr.getpointer( A )

# Pass this pointer to your swig'ed function 'ave'
print "The average of array A is:",average.ave( len(A), aptr )

We can compile this code using the same commands used on my SWIG page.

Download this example:

You can download this example along with NumPtr here:
numptr-example.tar.gz