From: Faheem M. <fa...@em...> - 2004-03-30 21:44:39
|
On Mon, 29 Mar 2004, Fernando Perez wrote: > The following should be enough to get you started: > > #include "Python.h" > #include "Numeric/arrayobject.h" > #include "blitz/array.h" > > using namespace std; > using namespace blitz; > > // Convert a Numpy array to a blitz one, using the original's data (no copy) > template<class T, int N> > static Array<T,N> py_to_blitz(PyArrayObject* arr_obj) > { > int T_size = sizeof(T); > TinyVector<int,N> shape(0); > TinyVector<int,N> strides(0); > int *arr_dimensions = arr_obj->dimensions; > int *arr_strides = arr_obj->strides; > > for (int i=0;i<N;++i) { > shape[i] = arr_dimensions[i]; > strides[i] = arr_strides[i]/T_size; > } > return Array<T,N>((T*) arr_obj->data,shape,strides,neverDeleteData); > } > > This is what I use for exactly the problem you are describing, and this code > was pretty much lifted, with minor changes, from weave's auto-generated C++. > What I do, to sidestep the memory management problems, is let python allocate > all my Numeric arrays (using zeros() if I have no data). I then use those > inside my C++ code as blitz++ arrays via the above snippet. Any changes made > by the C++ code are automatically reflected in the Numeric arary, since the > blitz object is using the Numeric data area. > > I hope this helps. Let me know if you need more help, I can mail you complete > example code. Thanks. That is very helpful. I've incorporated this into my code, and managed to get a simple example with boost working (extracting an element of an array). See below. Do you have a similar function which converts a blitz array to a numarray/Numeric one? If not, I can easily concoct one for myself. I now need to try to figure out what this reference counting stuff is about. I read the official Python docs but am still currently very confused. Faheem. *************************************************************************** #include "Python.h" #include "Numeric/arrayobject.h" #include <blitz/array.h> using namespace std; using namespace blitz; template<class T, int N> static Array<T,N> py_to_blitz(PyArrayObject* arr_obj); static PyObject * arrmod_elem(PyObject *self, PyObject *args); static PyMethodDef arrmod_methods[] = { {"elem", (PyCFunction)arrmod_elem, METH_VARARGS, "Returns the trace of a two-dimensional array.\n"}, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initarrmod(void) { (void) Py_InitModule3("arrmod", arrmod_methods, "Returns the Trace of a two-dimensional array.\n"); import_array(); } static PyObject * arrmod_elem(PyObject *self, PyObject *args) { PyObject *input, *result; PyArrayObject *array; double el; int i, j; if (!PyArg_ParseTuple(args, "Oii", &input, &i, &j)) return NULL; array = (PyArrayObject *) PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2); if (array == NULL) return NULL; Array<double,2> arr = py_to_blitz<double,2>(array); el = arr(i,j); result = Py_BuildValue("d",el); return result; } // Convert a Numpy array to a blitz one, using the original's data (no // copy) template<class T, int N> static Array<T,N> py_to_blitz(PyArrayObject* arr_obj) { int T_size = sizeof(T); TinyVector<int,N> shape(0); TinyVector<int,N> strides(0); int *arr_dimensions = arr_obj->dimensions; int *arr_strides = arr_obj->strides; for (int i=0;i<N;++i) { shape[i] = arr_dimensions[i]; strides[i] = arr_strides[i]/T_size; } return Array<T,N>((T*) arr_obj->data,shape,strides,neverDeleteData); } |