[Numpy-discussion] Anyone have a well-tested SWIG-based C++ STL valarray <=> numpy.array typemap to share?

Lisandro Dalcin dalcinl at gmail.com
Fri Sep 7 20:39:16 EDT 2007


David, I'll try to show you what I do for a custom C++ class, of
course this does not solve the issue resizing (my class does not
actually support resizing, so this is fine for me):

My custom class is a templatized one called DTable (is like a 2d
contiguous array), but currently I only instantiate it for 'int' and
'double'. This class have two relevant methods: getShape(), returning
a std::pair, and getArray(), returning a reference to an underliing
std::vector. So I am able to automatically support array interface by
using this:

First, I define a templatized utility function 'array_interface'

%header %{
namespace numpy {

  template<typename T> static char typechar() { return '\0'; }
  template<> static char typechar<int>()      { return  'i'; }
  template<> static char typechar<double>()   { return  'f'; }

  template<typename T>
  static PyObject*
  array_interface(const DTable<T>* self)
  {
    const std::pair<int,int>& shape = self->getShape();
    const std::vector<T>&     data  = self->getArray();
    void* array = const_cast<T*>(&data[0]);
    char endian = PyArray_NATIVE;
    char kind   = typechar<T>();
    int  elsize = sizeof(T);
    return Py_BuildValue("{sNsNsNsN}",
			 "shape",   Py_BuildValue("ii", shape.first, shape.second),
			 "typestr", PyString_FromFormat("%c%c%d", endian, kind, elsize),
			 "data",    Py_BuildValue("NO", PyLong_FromVoidPtr(array), Py_False),
			 "version", PyInt_FromLong(3));
  }
}
%}

Now define a SWIG macro to apply it to instantiations of my class

%define %array_interface(Class)
%extend Class { PyObject* __array_interface__; }
%{
#define %mangle(Class) ##_## __array_interface__ ## _get(_t) \
        numpy::array_interface(_t)
#define %mangle(Class) ##_## __array_interface__ ## _set(_t, _val) \
        SWIG_exception_fail(SWIG_AttributeError, "read-only attribute")
%}
%enddef

and finally instantiate my class with different names for 'int' and
'double' in SWIG and finally apply previous macro


%template(DTableI) DTable<int>;
%template(DTableS) DTable<double>;

%array_interface( DTable<int> );
%array_interface( DTable<double> );

I think you can implement someting similar for std::vector,
std::valarray, or whatever... For use other data types, the only you
need is to specialize the 'typecode' function.

Hope this help you.


On 9/4/07, David Goldsmith <David.L.Goldsmith at noaa.gov> wrote:
> Anyone have a well-tested SWIG-based C++ STL valarray <=> numpy.array
> typemap to share?  Thanks!
>
> DG
> --
> ERD/ORR/NOS/NOAA <http://response.restoration.noaa.gov/emergencyresponse/>
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>


-- 
Lisandro Dalcín
---------------
Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
PTLC - Güemes 3450, (3000) Santa Fe, Argentina
Tel/Fax: +54-(0)342-451.1594



More information about the NumPy-Discussion mailing list