Question

I'm trying to subclass numpy.complex64 in order to make use of the way numpy stores the data, (contiguous, alternating real and imaginary part) but use my own __add__, __sub__, ... routines.

My problem is that when I make a numpy.ndarray, setting dtype=mysubclass, I get a numpy.ndarray with dtype='numpy.complex64' in stead, which results in numpy not using my own functions for additions, subtractions and so on.

Example:

import numpy as np
class mysubclass(np.complex64):
    pass

a = mysubclass(1+1j)
A = np.empty(2, dtype=mysubclass)

print type(a)
print repr(A)

Output:

<class '__main__.mysubclass'>
array([ -2.07782988e-20 +4.58546896e-41j,  -2.07782988e-20 +4.58546896e-41j], dtype=complex64)'

Does anyone know how to do this?

Thanks in advance - Soren

Was it helpful?

Solution

The NumPy type system is only designed to be extended from C, via the PyArray_RegisterDataType function. It may be possible to access this functionality from Python using ctypes but I wouldn't recommend it; better to write an extension in C or Cython, or subclass ndarray as @seberg describes.

There's a simple example dtype in the NumPy source tree: newdtype_example/floatint.c. If you're into Pyrex, reference.pyx in the pytables source may be worth a look.

OTHER TIPS

Note that scalars and arrays are quite different in numpy. np.complex64 (this is 32-bit float, just to note, not double precision). You will not be able to change the array like that, you will need to subclass the array instead and then override its __add__ and __sub__.

If that is all you want to do, it should just work otherwise look at http://docs.scipy.org/doc/numpy/user/basics.subclassing.html since subclassing an array is not that simple.

However if you want to use this type also as a scalar. For example you want to index scalars out, it gets more difficult at least currently. You can get a little further by defining __array_wrap__ to convert to scalars to your own scalar type for some reduce functions, for indexing to work in all cases it appears to me that you may have define your own __getitem__ currently.

In all cases with this approach, you still use the complex datatype, and all functions that are not explicitly overridden will still behave the same. @ecatmur mentioned that you can create new datatypes from the C side, if that is really what you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top