[Numpy-discussion] casting

Neal Becker ndbecker2@gmail....
Mon Jan 14 12:59:15 CST 2008

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.

More information about the Numpy-discussion mailing list