5 #ifndef __eigenpy_ufunc_hpp__ 6 #define __eigenpy_ufunc_hpp__ 15 #ifdef NPY_1_19_API_VERSION 16 #define EIGENPY_NPY_CONST_UFUNC_ARG const 18 #define EIGENPY_NPY_CONST_UFUNC_ARG 21 #define EIGENPY_REGISTER_BINARY_OPERATOR(name,op) \ 22 template<typename T1, typename T2, typename R> \ 23 void binary_op_##name(char** args, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * dimensions, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * steps, void * ) \ 25 npy_intp is0 = steps[0], is1 = steps[1], \ 26 os = steps[2], n = *dimensions; \ 27 char * i0 = args[0], *i1 = args[1], *o = args[2]; \ 29 for (k = 0; k < n; k++) \ 31 T1 & x = *static_cast<T1*>(static_cast<void*>(i0)); \ 32 T2 & y = *static_cast<T2*>(static_cast<void*>(i1)); \ 33 R & res = *static_cast<R*>(static_cast<void*>(o)); \ 35 i0 += is0; i1 += is1; o += os; \ 39 template<typename T> \ 40 void binary_op_##name(char** args, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * dimensions, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * steps, void * data) \ 42 binary_op_##name<T,T,T>(args,dimensions,steps,data); \ 56 #define EIGENPY_REGISTER_UNARY_OPERATOR(name,op) \ 57 template<typename T, typename R> \ 58 void unary_op_##name(char** args, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * dimensions, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * steps, void * ) \ 60 npy_intp is = steps[0], \ 61 os = steps[1], n = *dimensions; \ 62 char * i = args[0], *o = args[1]; \ 64 for (k = 0; k < n; k++) \ 66 T & x = *static_cast<T*>(static_cast<void*>(i)); \ 67 R & res = *static_cast<R*>(static_cast<void*>(o)); \ 73 template<typename T> \ 74 void unary_op_##name(char** args, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * dimensions, EIGENPY_NPY_CONST_UFUNC_ARG npy_intp * steps, void * data) \ 76 unary_op_##name<T,T>(args,dimensions,steps,data); \ 83 #define EIGENPY_REGISTER_BINARY_UFUNC(name,code,T1,T2,R) { \ 84 PyUFuncObject* ufunc = \ 85 (PyUFuncObject*)PyObject_GetAttrString(numpy, #name); \ 86 int _types[3] = { Register::getTypeCode<T1>(), Register::getTypeCode<T2>(), Register::getTypeCode<R>()}; \ 90 if (sizeof(_types)/sizeof(int)!=ufunc->nargs) { \ 91 PyErr_Format(PyExc_AssertionError, \ 92 "ufunc %s takes %d arguments, our loop takes %lu", \ 93 #name, ufunc->nargs, (unsigned long) \ 94 (sizeof(_types)/sizeof(int))); \ 97 if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, code, \ 98 internal::binary_op_##name<T1,T2,R>, _types, 0) < 0) { \ 105 #define EIGENPY_REGISTER_UNARY_UFUNC(name,code,T,R) { \ 106 PyUFuncObject* ufunc = \ 107 (PyUFuncObject*)PyObject_GetAttrString(numpy, #name); \ 108 int _types[2] = { Register::getTypeCode<T>(), Register::getTypeCode<R>()}; \ 112 if (sizeof(_types)/sizeof(int)!=ufunc->nargs) { \ 113 PyErr_Format(PyExc_AssertionError, \ 114 "ufunc %s takes %d arguments, our loop takes %lu", \ 115 #name, ufunc->nargs, (unsigned long) \ 116 (sizeof(_types)/sizeof(int))); \ 119 if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, code, \ 120 internal::unary_op_##name<T,R>, _types, 0) < 0) { \ 127 template<
typename Scalar>
130 const int code = Register::getTypeCode<Scalar>();
133 #if PY_MAJOR_VERSION >= 3 134 numpy_str = PyUnicode_FromString(
"numpy");
136 numpy_str = PyString_FromString(
"numpy");
139 numpy = PyImport_Import(numpy_str);
140 Py_DECREF(numpy_str);
166 #endif // __eigenpy_ufunc_hpp__ #define EIGENPY_REGISTER_UNARY_UFUNC(name, code, T, R)
#define EIGENPY_REGISTER_BINARY_UFUNC(name, code, T1, T2, R)
void registerCommonUfunc()
#define EIGENPY_REGISTER_BINARY_OPERATOR(name, op)
#define EIGENPY_REGISTER_UNARY_OPERATOR(name, op)