I have a custom float data type that emulates 128bit floats using two 64bit floats (the double-double class dd_real
from the QD library). From C++ I want to export an ndarray to python. I already know how to do this for 64bit floats, but for double-doubles I somehow need to specify my own custom dtype. How to do that?
Note: numpy has its own 128bit float (np.float128) unfortunately this maps to long double
in C/C++ which is merely an 80bit-float stored in 128bit (on all of my platforms).
In fact, one should be able to do this exactly in the same way that numpy exports np.float128 (I just don't know how that is done), with the only difference that it uses dd_real
on the C++ side instead of long double
.
If this helps, I already exported the C++ type dd_real
to python using boost::python
maybe this can be reused somehow.
So far I was able to research the following
The numpy documentation for dtypes refers to C-API for how to export custom dtypes, but that document somehow only explains the existing dtypes not how to create new ones.
When browsing stackoverflow I found this example, but I wonder if for dd_real
this could be simpler. I also don't see where the dtype is actually generated. Maybe only in python __ init__ via np.typeDict['quaternion'] = np.dtype(quaternion)
. How to use that dtype in C++ when I want to generate an ndarray?
NumPy provides a C-API to enable users to extend the system and get access to the array object for use in other routines. The best way to truly understand the C-API is to read the source code. If you are unfamiliar with (C) source code, however, this can be a daunting experience at first.
Data Types in Python integer - used to represent integer numbers. e.g. -1, -2, -3. float - used to represent real numbers. e.g. 1.2, 42.42. boolean - used to represent True or False.
The default data type: float_ . The 24 built-in array scalar type objects all convert to an associated data-type object.
uint8 is an unsigned 8-bit integer that can represent values 0.. 255. int on the other hand is usually a 32-bit signed integer.
The repository you linked to,
https://github.com/numpy/numpy-dtypes
probably contains the simplest possible examples on how to add new dtype to Numpy. I'm not aware of an easier way. Note the calls to register_cast_function
and REGISTER_UFUNC
in these files: these tell Numpy how operations such as multiplication and casting should be dealt with on an element-by-element level.
However, if what you actually want to do is to only export your data, you could just export as an array of doubles, or maybe bundling two doubles to a single data type
np.dtype([('a', double), ('b', double)])
Then, you'd need to write separate functions to do operations on these arrays (as arr1 * arr2
won't do what you want here). One possible way to go further and make also arr1 * arr2
to work would be to subclass np.ndarray
your data type, overriding __mul__
etc operations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With