[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