numpy.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020-2024 INRIA
3  */
4 
5 #ifndef __eigenpy_numpy_hpp__
6 #define __eigenpy_numpy_hpp__
7 
8 #include "eigenpy/config.hpp"
9 
10 #ifndef PY_ARRAY_UNIQUE_SYMBOL
11 #define PY_ARRAY_UNIQUE_SYMBOL EIGENPY_ARRAY_API
12 #endif
13 
14 // For compatibility with Numpy 2.x
15 // See
16 // https://numpy.org/devdocs/reference/c-api/array.html#c.NPY_API_SYMBOL_ATTRIBUTE
17 #define NPY_API_SYMBOL_ATTRIBUTE EIGENPY_DLLAPI
18 
19 #include <numpy/numpyconfig.h>
20 #ifdef NPY_1_8_API_VERSION
21 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
22 #endif
23 
24 /* Allow compiling against NumPy 1.x and 2.x
25  see:
26  https://github.com/numpy/numpy/blob/afea8fd66f6bdbde855f5aff0b4e73eb0213c646/doc/source/reference/c-api/array.rst#L1224
27 */
28 #if NPY_ABI_VERSION < 0x02000000
29 #define PyArray_DescrProto PyArray_Descr
30 #endif
31 
32 #include <numpy/ndarrayobject.h>
33 #include <numpy/ufuncobject.h>
34 
35 #if NPY_ABI_VERSION < 0x02000000
36 static inline PyArray_ArrFuncs* PyDataType_GetArrFuncs(PyArray_Descr* descr) {
37  return descr->f;
38 }
39 #endif
40 
41 /* PEP 674 disallow using macros as l-values
42  see : https://peps.python.org/pep-0674/
43 */
44 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
45 static inline void _Py_SET_TYPE(PyObject* o, PyTypeObject* type) {
46  Py_TYPE(o) = type;
47 }
48 #define Py_SET_TYPE(o, type) _Py_SET_TYPE((PyObject*)(o), type)
49 #endif
50 
51 #if defined _WIN32 || defined __CYGWIN__
52 #define EIGENPY_GET_PY_ARRAY_TYPE(array) \
53  call_PyArray_MinScalarType(array)->type_num
54 #else
55 #define EIGENPY_GET_PY_ARRAY_TYPE(array) PyArray_MinScalarType(array)->type_num
56 #endif
57 
58 #include <complex>
59 
60 namespace eigenpy {
61 void EIGENPY_DLLAPI import_numpy();
62 int EIGENPY_DLLAPI PyArray_TypeNum(PyTypeObject* type);
63 
64 // By default, the Scalar is considered as a Python object
65 template <typename Scalar, typename Enable = void>
67  enum { type_code = NPY_USERDEF };
68 };
69 
70 template <>
71 struct NumpyEquivalentType<bool> {
72  enum { type_code = NPY_BOOL };
73 };
74 
75 template <>
76 struct NumpyEquivalentType<char> {
77  enum { type_code = NPY_INT8 };
78 };
79 template <>
80 struct NumpyEquivalentType<unsigned char> {
81  enum { type_code = NPY_UINT8 };
82 };
83 template <>
85  enum { type_code = NPY_INT8 };
86 };
87 
88 template <>
90  enum { type_code = NPY_INT16 };
91 };
92 template <>
94  enum { type_code = NPY_UINT16 };
95 };
96 
97 template <>
99  enum { type_code = NPY_INT32 };
100 };
101 template <>
103  enum { type_code = NPY_UINT32 };
104 };
105 
106 // On Windows, long is a 32 bytes type but it's a different type than int
107 // See https://github.com/stack-of-tasks/eigenpy/pull/455
108 #if defined _WIN32 || defined __CYGWIN__
109 
110 template <>
111 struct NumpyEquivalentType<long> {
112  enum { type_code = NPY_INT32 };
113 };
114 template <>
115 struct NumpyEquivalentType<unsigned long> {
116  enum { type_code = NPY_UINT32 };
117 };
118 
119 #endif // WIN32
120 
121 template <>
123  enum { type_code = NPY_INT64 };
124 };
125 template <>
127  enum { type_code = NPY_UINT64 };
128 };
129 
130 // On Mac, long is a 64 bytes type but it's a different type than int64_t
131 // See https://github.com/stack-of-tasks/eigenpy/pull/455
132 #if defined __APPLE__
133 
134 template <>
135 struct NumpyEquivalentType<long> {
136  enum { type_code = NPY_INT64 };
137 };
138 template <>
139 struct NumpyEquivalentType<unsigned long> {
140  enum { type_code = NPY_UINT64 };
141 };
142 
143 #endif // MAC
144 
145 // On Linux, long long is a 64 bytes type but it's a different type than int64_t
146 // See https://github.com/stack-of-tasks/eigenpy/pull/455
147 #if defined __linux__
148 
149 #include <type_traits>
150 
151 template <typename Scalar>
152 struct NumpyEquivalentType<
153  Scalar,
154  typename std::enable_if<!std::is_same<int64_t, long long>::value &&
155  std::is_same<Scalar, long long>::value>::type> {
156  enum { type_code = NPY_LONGLONG };
157 };
158 template <typename Scalar>
159 struct NumpyEquivalentType<
160  Scalar, typename std::enable_if<
161  !std::is_same<uint64_t, unsigned long long>::value &&
162  std::is_same<Scalar, unsigned long long>::value>::type> {
163  enum { type_code = NPY_ULONGLONG };
164 };
165 
166 #endif // Linux
167 
168 template <>
169 struct NumpyEquivalentType<float> {
170  enum { type_code = NPY_FLOAT };
171 };
172 template <>
173 struct NumpyEquivalentType<double> {
174  enum { type_code = NPY_DOUBLE };
175 };
176 template <>
177 struct NumpyEquivalentType<long double> {
178  enum { type_code = NPY_LONGDOUBLE };
179 };
180 
181 template <>
182 struct NumpyEquivalentType<std::complex<float> > {
183  enum { type_code = NPY_CFLOAT };
184 };
185 template <>
186 struct NumpyEquivalentType<std::complex<double> > {
187  enum { type_code = NPY_CDOUBLE };
188 };
189 template <>
190 struct NumpyEquivalentType<std::complex<long double> > {
191  enum { type_code = NPY_CLONGDOUBLE };
192 };
193 
194 template <typename Scalar>
196  if ((int)NumpyEquivalentType<Scalar>::type_code == NPY_USERDEF) return false;
197  return true;
198 }
199 
200 } // namespace eigenpy
201 
202 namespace eigenpy {
203 #if defined _WIN32 || defined __CYGWIN__
204 EIGENPY_DLLAPI bool call_PyArray_Check(PyObject*);
205 
206 EIGENPY_DLLAPI PyObject* call_PyArray_SimpleNew(int nd, npy_intp* shape,
207  int np_type);
208 
209 EIGENPY_DLLAPI PyObject* call_PyArray_New(PyTypeObject* py_type_ptr, int nd,
210  npy_intp* shape, int np_type,
211  void* data_ptr, int options);
212 
213 EIGENPY_DLLAPI PyObject* call_PyArray_New(PyTypeObject* py_type_ptr, int nd,
214  npy_intp* shape, int np_type,
215  npy_intp* strides, void* data_ptr,
216  int options);
217 
218 EIGENPY_DLLAPI int call_PyArray_ObjectType(PyObject*, int);
219 
220 EIGENPY_DLLAPI PyTypeObject* getPyArrayType();
221 
222 EIGENPY_DLLAPI PyArray_Descr* call_PyArray_DescrFromType(int typenum);
223 
224 EIGENPY_DLLAPI void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs);
225 
226 EIGENPY_DLLAPI int call_PyArray_RegisterDataType(PyArray_DescrProto* dtype);
227 
228 EIGENPY_DLLAPI int call_PyArray_RegisterCanCast(PyArray_Descr* descr,
229  int totype,
230  NPY_SCALARKIND scalar);
231 
232 EIGENPY_DLLAPI PyArray_Descr* call_PyArray_MinScalarType(PyArrayObject* arr);
233 
234 EIGENPY_DLLAPI int call_PyArray_RegisterCastFunc(
235  PyArray_Descr* descr, int totype, PyArray_VectorUnaryFunc* castfunc);
236 #else
237 inline bool call_PyArray_Check(PyObject* py_obj) {
238  return PyArray_Check(py_obj);
239 }
240 
241 inline PyObject* call_PyArray_SimpleNew(int nd, npy_intp* shape, int np_type) {
242  return PyArray_SimpleNew(nd, shape, np_type);
243 }
244 
245 inline PyObject* call_PyArray_New(PyTypeObject* py_type_ptr, int nd,
246  npy_intp* shape, int np_type, void* data_ptr,
247  int options) {
248  return PyArray_New(py_type_ptr, nd, shape, np_type, NULL, data_ptr, 0,
249  options, NULL);
250 }
251 
252 inline PyObject* call_PyArray_New(PyTypeObject* py_type_ptr, int nd,
253  npy_intp* shape, int np_type,
254  npy_intp* strides, void* data_ptr,
255  int options) {
256  return PyArray_New(py_type_ptr, nd, shape, np_type, strides, data_ptr, 0,
257  options, NULL);
258 }
259 
260 inline int call_PyArray_ObjectType(PyObject* obj, int val) {
261  return PyArray_ObjectType(obj, val);
262 }
263 
264 inline PyTypeObject* getPyArrayType() { return &PyArray_Type; }
265 
266 inline PyArray_Descr* call_PyArray_DescrFromType(int typenum) {
267  return PyArray_DescrFromType(typenum);
268 }
269 
270 inline void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs) {
271  PyArray_InitArrFuncs(funcs);
272 }
273 
275  return PyArray_RegisterDataType(dtype);
276 }
277 
278 inline PyArray_Descr* call_PyArray_MinScalarType(PyArrayObject* arr) {
279  return PyArray_MinScalarType(arr);
280 }
281 
282 inline int call_PyArray_RegisterCanCast(PyArray_Descr* descr, int totype,
283  NPY_SCALARKIND scalar) {
284  return PyArray_RegisterCanCast(descr, totype, scalar);
285 }
286 
287 inline int call_PyArray_RegisterCastFunc(PyArray_Descr* descr, int totype,
288  PyArray_VectorUnaryFunc* castfunc) {
289  return PyArray_RegisterCastFunc(descr, totype, castfunc);
290 }
291 #endif
292 } // namespace eigenpy
293 
294 #endif // ifndef __eigenpy_numpy_hpp__
test_matrix.int32_t
int32_t
Definition: test_matrix.py:202
eigenpy::getPyArrayType
PyTypeObject * getPyArrayType()
Definition: numpy.hpp:264
eigenpy::PyArray_TypeNum
int EIGENPY_DLLAPI PyArray_TypeNum(PyTypeObject *type)
Definition: numpy.cpp:16
PyDataType_GetArrFuncs
static PyArray_ArrFuncs * PyDataType_GetArrFuncs(PyArray_Descr *descr)
Definition: numpy.hpp:36
eigenpy::call_PyArray_InitArrFuncs
void call_PyArray_InitArrFuncs(PyArray_ArrFuncs *funcs)
Definition: numpy.hpp:270
test_matrix.uint16_t
uint16_t
Definition: test_matrix.py:201
eigenpy::call_PyArray_DescrFromType
PyArray_Descr * call_PyArray_DescrFromType(int typenum)
Definition: numpy.hpp:266
eigenpy::isNumpyNativeType
bool isNumpyNativeType()
Definition: numpy.hpp:195
test_std_map.val
val
Definition: test_std_map.py:14
eigenpy::call_PyArray_RegisterDataType
int call_PyArray_RegisterDataType(PyArray_DescrProto *dtype)
Definition: numpy.hpp:274
test_matrix.uint32_t
uint32_t
Definition: test_matrix.py:203
eigenpy::import_numpy
void EIGENPY_DLLAPI import_numpy()
Definition: numpy.cpp:8
test_matrix.uint64_t
uint64_t
Definition: test_matrix.py:205
eigenpy::call_PyArray_Check
bool call_PyArray_Check(PyObject *py_obj)
Definition: numpy.hpp:237
eigenpy
Definition: alignment.hpp:14
eigenpy::call_PyArray_SimpleNew
PyObject * call_PyArray_SimpleNew(int nd, npy_intp *shape, int np_type)
Definition: numpy.hpp:241
eigenpy::call_PyArray_ObjectType
int call_PyArray_ObjectType(PyObject *obj, int val)
Definition: numpy.hpp:260
eigenpy::NumpyEquivalentType
Definition: numpy.hpp:66
test_matrix.int64_t
int64_t
Definition: test_matrix.py:204
eigenpy::call_PyArray_RegisterCanCast
int call_PyArray_RegisterCanCast(PyArray_Descr *descr, int totype, NPY_SCALARKIND scalar)
Definition: numpy.hpp:282
eigenpy::call_PyArray_MinScalarType
PyArray_Descr * call_PyArray_MinScalarType(PyArrayObject *arr)
Definition: numpy.hpp:278
eigenpy::call_PyArray_New
PyObject * call_PyArray_New(PyTypeObject *py_type_ptr, int nd, npy_intp *shape, int np_type, void *data_ptr, int options)
Definition: numpy.hpp:245
eigenpy::call_PyArray_RegisterCastFunc
int call_PyArray_RegisterCastFunc(PyArray_Descr *descr, int totype, PyArray_VectorUnaryFunc *castfunc)
Definition: numpy.hpp:287
test_matrix.int16_t
int16_t
Definition: test_matrix.py:200
eigenpy::NumpyEquivalentType::type_code
@ type_code
Definition: numpy.hpp:67
_Py_SET_TYPE
static void _Py_SET_TYPE(PyObject *o, PyTypeObject *type)
Definition: numpy.hpp:45
PyArray_DescrProto
#define PyArray_DescrProto
Definition: numpy.hpp:29
test_matrix.int8_t
int8_t
Definition: test_matrix.py:198


eigenpy
Author(s): Justin Carpentier, Nicolas Mansard
autogenerated on Sat Nov 2 2024 02:14:45