[Numpy-discussion] casting
Robert Kern
robert.kern@gmail....
Mon Jan 14 15:36:06 CST 2008
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
More information about the Numpy-discussion
mailing list