From: Todd M. <jm...@st...> - 2003-01-15 18:56:22
|
Chris Barker wrote: >Hi folks, > >I use Numeric an wxPython together a lot (of course I do, I use Numeric >for everything!). > >Unfortunately, since wxPython is not Numeric aware, you lose some real >potential performance advantages. For example, I'm now working on >expanding the extensions to graphics device contexts (DCs) so that you >can draw a whole bunch of objects with a single Python call. The idea is >that the looping can be done in C++, rather than Python, saving a lot of >overhead of the loop itself, as well as the Python-wxWindows translation >step. > >For drawing thousands of points, the speed-up is substantial. It's less >substantial on more complex objects (rectangles give a factor of two >improvement for ~1000 objects), due to the longer time it takes to draw >the object itself, rather than make the call. > >Anyway, at the moment, Robin Dunn has the wrappers set up so that you >can pass in a NumPy array (or, indeed, and sequence) rather than a list >or tuple of coordinates, but it is faster to use a list than a NumPy >array, because for arrays, it uses the generic PySequence_GetItem call. >If we used the NumPy API directly, it should be faster than using a >list, not slower! THis is how a representative section of the code looks >now: > > >bool isFastSeq = PyList_Check(pyPoints) || >PyTuple_Check(pyPoints); >. >. >. > // Get the point coordinants > if (isFastSeq) { > obj = PySequence_Fast_GET_ITEM(pyPoints, i); > } > else { > obj = PySequence_GetItem(pyPoints, i); > } > >. >. >. > >So you can see that if a NumPy array is passed in, PySequence_GetItem >will be used. > >What I would like to do is have an isNumPyArray check, and then access >the NumPy array directly in that case. > >The tricky part is that Robin does not want to have wxPython require >Numeric. (Oh how I dream of the day that NumArray becomes part of the >standard library!) >How can I check if an Object is a NumPy array (and then use it as such), >without including Numeric during compilation? > >I know one option is to have condition compilation, with a NumPy and >non-Numpy version, but Robin is managing a whole lot of different >version as it is, and I don't think he wants to deal with twice as many! > >Anyone have any ideas? > Use the Python C-API and string literals as the basis for the interface. I think the steps are something like this: 1. Import "Numeric". (PyImport_ImportModule) 2. Get the module dictionary. (PyModule_GetDict) 3. Get "array" out of the dictionary. (PyDict_GetItemString) 4. Call "isinstance" on Numeric.array and the object. (PyObject_IsInstance) Similarly: 1. Import "numarray". 2. Get the module dictionary. 3. Get "NumArray" out of the dictionary 4. Call the C-API equivalent of "isinstance" on numarray.NumArray and the object. The first 3 steps of both cases can be initialized once, I think, and stored in C static variables to avoid repeated fetches. If any of the first 3 steps fail, then consider that case failed and returning False. If it's not a Numeric array, check to see if it's a numarray. > >By the way, you can substitute NumArray for NumPy in this, as it is the >wave of the future, and particularly if it would be easier. > >-Chris > > Todd |