[Matrix-SIG] Re: SWIG NumPy interfaces
Joe Van Andel
vanandel@atd.ucar.edu
Mon, 12 Apr 1999 10:24:05 -0600
This is a multipart MIME message.
--==_Exmh_-12996654300
Content-Type: text/plain; charset=us-ascii
Reply-To: vanandel@ucar.edu
Cc: pascucci <pascucci@cs.utexas.edu>
Fcc:
--------
Here's an example of what I use. The next release of EGCS may actually
support templates well enough to use CXX from the LLNL distribution,
but for now SWIG is what I use.
Joe VanAndel Internet: vanandel@ucar.edu
National Center for Web: http://www.atd.ucar.edu/~vanandel/home.html
Atmospheric Research
--==_Exmh_-12996654300
Content-Type: text/plain ; name="IIR_Filter.i"; charset=us-ascii
Content-Description: IIR_Filter.i
%module IIR_Filter
%{
#include "IIR_Filter.h"
#include "FloatTuple.h"
%}
%include "numpy_typemaps.i"
%typemap(python,in) float* TUPLE (float *temp) {
int i;
int cnt;
if (PyTuple_Check($source)) {
cnt = PyTuple_Size($source);
temp = new float[cnt];
for (i=0; i < cnt; ++i) {
temp[i] = PyFloat_AsDouble(PyTuple_GetItem($source, i));
}
$target = temp;
} else {
PyErr_SetString(PyExc_TypeError, "expected a tuple");
return NULL;
}
}
%include "FloatTuple.h"
class IIR_Filter {
public:
IIR_Filter(int, float, FloatTuplePtr);
PyObject *filter(PyArrayObject *INPUT_2D, // I
PyArrayObject *INPUT_2D); // Q
};
--==_Exmh_-12996654300
Content-Type: text/plain ; name="numpy_typemaps.i"; charset=us-ascii
Content-Description: numpy_typemaps.i
%typemap(python,in) PyArrayObject *INPUT
{
$target = (PyArrayObject *)$source;
}
%typemap(python,in) PyArrayObject *INPUT_1D
{
$target = (PyArrayObject *)$source;
if ($target->nd != 1) {
PyErr_SetString(PyExc_TypeError, "must be 1D array");
return NULL;
}
}
%typemap(python,in) PyArrayObject *INPUT_2D
{
$target = (PyArrayObject *)$source;
if ($target->nd != 2) {
// printf("%s: num dim = %d\n", "$target", $target->nd);
PyErr_SetString(PyExc_TypeError, "must be 2D array");
return NULL;
}
}
// pass 2D array of double
// by Dr. Les Schaffer les@designspring.com
%typemap(python, in) double ** {
PyArrayObject *arr; /* will point to our array object. */
PyObject ** op; /* pointer to pointer to array object */
/* cast as PyObject; */
/* (needed by PyArray_As2d). */
int d1, d2, type; /* ints neeed by PyArray_As2D. */
char ***ptr; /* need by PyArray_As2D. */
double ** arrayPtr_2D; /* this is our double ** array pointer. */
/* C extensions can then access */
/* arbitrary sized 2D arrays as */
/* arrayPtr[i][j]. */
/* point ptr to the address of ArrayPtr_2D. */
/* PyArray_As2D will then place in it a */
/* char ** pointer aimed at a set of */
/* pointers to the rows of our array. */
ptr = (char ***) & arrayPtr_2D;
/* here is our array object from caller */
arr = (PyArrayObject *) $source;
/* point op at our array object pointer */
op = (PyObject **)&arr;
/* i use double almost always */
type = (int) PyArray_DOUBLE;
/* now let PyArray_As2D re-arrange, if necessary (?), */
/* our array and set the pointers to the rows of array */
PyArray_As2D( op, ptr, &d1, &d2, type);
/* done. hand arrayPtr2D to our C ext */
$target = arrayPtr_2D;
}
%typemap(python,out) PyObject * {
$target = $source;
}
// grab a 12 element array from a Python tuple
%typemap(python,in) float[12] (float temp[12]){
int i;
if (PyTuple_Check($source)) {
if (!PyArg_ParseTuple($source, "ffffffffffff",
temp, temp+1, temp+2, temp+3,
temp+4, temp+5, temp+6, temp+7,
temp+8, temp+9, temp+10, temp+11)) {
PyErr_SetString(PyExc_TypeError, "tuple must have 12 elements");
return NULL;
}
$target = &temp[0];
} else {
PyErr_SetString(PyExc_TypeError, "expected a tuple");
return NULL;
}
}
%typemap(python,in) float[13] (float temp[13]){
int i;
if (PyTuple_Check($source)) {
if (!PyArg_ParseTuple($source, "fffffffffffff",
temp, temp+1, temp+2, temp+3,
temp+4, temp+5, temp+6, temp+7,
temp+8, temp+9, temp+10, temp+11,
temp+12 )) {
PyErr_SetString(PyExc_TypeError, "tuple must have 13 elements");
return NULL;
}
$target = &temp[0];
} else {
PyErr_SetString(PyExc_TypeError, "expected a tuple");
return NULL;
}
}
%typemap(python,in) float[15] (float temp[15]){
int i;
if (PyTuple_Check($source)) {
if (!PyArg_ParseTuple($source, "fffffffffffffff",
temp, temp+1, temp+2, temp+3,
temp+4, temp+5, temp+6, temp+7,
temp+8, temp+9, temp+10, temp+11,
temp+12, temp+13, temp+14)) {
PyErr_SetString(PyExc_TypeError, "tuple must have 15 elements");
return NULL;
}
$target = &temp[0];
} else {
PyErr_SetString(PyExc_TypeError, "expected a tuple");
return NULL;
}
}
--==_Exmh_-12996654300
Content-Type: text/plain ; name="FloatTuple.cc"; charset=us-ascii
Content-Description: FloatTuple.cc
#include <stdio.h> // for NULL
#include "FloatTuple.h"
FloatTuple::FloatTuple(int cnt, float *tuple)
{
values_ = tuple; // we're inheriting this memory
numFloats_ = cnt;
}
FloatTuple::~FloatTuple()
{
delete values_;
values_ = NULL;
numFloats_= 0;
}
--==_Exmh_-12996654300
Content-Type: text/plain ; name="FloatTuple.h"; charset=us-ascii
Content-Description: FloatTuple.h
#ifndef FloatTupleH
#define FloatTupleH
class FloatTuple {
public:
FloatTuple(int cnt, float *TUPLE);
~FloatTuple();
int numFloats_;
float *values_;
};
typedef FloatTuple* FloatTuplePtr;
#endif
--==_Exmh_-12996654300--