Neal Becker wrote: > Jon Wright wrote: > >>> I'm sorry, I still think we're talking past each other. What do you mean >>> by "native data type"? If you just want to get an ndarray without >>> specifying a type, use PyArray_FROM_O(). That's what it's for. You don't >>> need to know the data type beforehand. >> What I have wanted in the past (and what I thought Neal was after) is a >> way to choose which function to call according to the typecode of the >> data as it is currently in memory. I don't want to convert (or cast or >> even touch the data) but just call a type specific function instead. C++ >> templates can take some of the tedium out of that, but in some cases >> algorithms may be different too. Guessing which sort algorithm to use >> springs to mind. >> >> Rather than saying "give me the right kind of array", I think there is >> an interest in saying "choose which function is the best for this data". >> Something like: >> >> PyArrayObject* array = PyArray_FROM_O( (PyObject*) O ); >> type = array -> descr -> type_num ; >> switch (type){ >> case NPY_BYTE : signed_func(array); >> case NPY_UBYTE : unsigned_func(array); >> // etc >> >> It sort of implies having a C++ type hierarchy for numpy arrays and >> casting array to be a PyFloatArray or PyDoubleArray etc? >> >> The extra confusion might be due to the way arrays can be laid out in >> memory - indexing into array slices is not always obvious. Also if you >> want to make sure your inner loop goes over the "fast" index you might >> want an algorithm which reads the strides when it runs. >> >> Sorry if I've only added to the confusion. >> >> Cheers, >> >> Jon > > This is close to what I'm doing. If I really can handle any type, then > FROM_O is fine. > > Commonly, it's a little more complicated. > > Here is an example, in pseudo-code (real code is in c++): > > if (native_type_of (x) is int or long): > do_something_with (convert_to_long_array(x)) > elif (native_type_of (x) is complex): > do_something_with (convert_to_complex_array (x)) > > In the above, native_type_of means: > if (hasattr (x, "__array_struct__")): > array_if = PyCObject_AsVoidPtr (x.__array_struct__) > return (map_array_if_to_typenum (array_if)) > > So this means for any numpy array or any type supporting __array_struct__ > protocol, find out the native data type. > > I don't want to use FROM_O here, because I really can only handle certain > types. If I used FROM_O, then after calling FROM_O, if the type was not > one I could handle, I'd have to call FromAny and convert it. Or, in the > case above, if I was given an array of int32 which I'd want to handle as > long (int64), I'd have to convert it again.
Okay, I think I see now. I'm not sure what numpy could do to make your code more elegant. I would recommend just using PyArray_FROM_O() or PyArray_EnsureArray() to get a real ndarray object. They should not copy when the object is already an ndarray or if it satisfies the array interface; however, it will also handle the cases when you have a Python-level __array_interface__ or just nested sequences, too. You can look at the PyArray_Descr directly, dispatch the types that you can handle directly, and then convert for the types which you can't. You will not get any extraneous conversions or copies of data. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion