Philip Austin wrote:
[snip]
boost/libs/python/test/numpy.cpp boost/libs/python/test/numpy.py boost/python/numeric.hpp
Todd Miller writes:
I took a look at the files above trying to see what you're doing.
(note that all of this was written by Dave Abrahams, I'm just one of the first Numeric users.)
What I thought I would see, was some form of direct coupling between a module in boost and either the Numeric or numarray C-API. However, when I search the whole source tree (*.cpp *.hpp) I can find neither PyArrayObject, arrayobject.h, NDInfo, nor libnumarray.h. So I'm not sure what part of any Numeric/numarray C-API you're using now (if any)
The answer is -- no part of the C-API if he can get away with it. Your move towards Numeric compatibility for numarray means that he now can get away with it.
Specifically, the extension tries to import the numarray module, and if that fails, imports Numeric (the user can change this with
numeric::set_module_and_type("Numeric", "ArrayType"); or: numeric::set_module_and_type("numarray", "NDArray"); )
numeric wraps the module pointer, and calls functions through it -- e.g. (from boost/libs/python/src/numeric.cpp):
void array_base::resize(object const& shape) { attr("resize")(shape); }
which invokes PyObject_CallObject to call the array's resize method, with the tuple shape (similar to CXX). If the method isn't part of the library (say for Numeric and getflat) then a python exception is thrown.
and in particular, what isn't working for you. Note: numarray and Numeric are not totally compatible at either the C or Python levels, so either area could have been a source of difficulty.
The problem was that, as long as a call to getNDInfo was required to access an array's data pointer, a Python-only approach like the above wouldn't work. Since it is now possible to do this via a cast to PyArrayObject* for a numarray, the problem has disappeared.
(there's nothing stopping you from using the C-API if you want, though. For example you can create a numarray with data copied from a C array with something like:
numeric::array makeNum(int * data, int n=0){ object obj(detail::new_reference(PyArray_FromDims(1, &n, PyArray_INT))); char *arr_data = ((PyArrayObject*) obj.ptr())->data; memcpy(arr_data, data, 4 * n); return numeric::array(obj); } )
Regards, Phil