5 #ifndef __eigenpy_user_type_hpp__ 6 #define __eigenpy_user_type_hpp__ 17 template <
typename From,
typename To>
19 static To
run(
const From& from) {
20 #pragma GCC diagnostic push 21 #pragma GCC diagnostic ignored "-Wconversion" 22 #pragma GCC diagnostic ignored "-Wfloat-conversion" 23 return static_cast<To
>(from);
24 #pragma GCC diagnostic pop 30 template <
typename From,
typename To>
31 static void cast(
void* from_,
void* to_, npy_intp n,
void* ,
34 const From* from =
static_cast<From*
>(from_);
35 To* to =
static_cast<To*
>(to_);
36 for (npy_intp i = 0; i < n; i++) {
53 static PyObject*
run(
void*
data,
void* ) {
55 T* elt_ptr =
static_cast<T*
>(
data);
62 template <typename T, int type_code = NumpyEquivalentType<T>::type_code>
64 inline static void copyswap(
void* ,
void* ,
int ,
66 inline static PyObject*
getitem(
void* ,
68 inline static int setitem(PyObject* ,
void* ,
70 inline static void copyswapn(
void* ,
long ,
void* ,
73 inline static npy_bool nonzero(
75 inline static void dotfunc(
void* , npy_intp ,
void* ,
76 npy_intp ,
void* , npy_intp ,
78 inline static int fill(
void* data_, npy_intp length,
void* arr);
79 inline static int fillwithscalar(
void* buffer_, npy_intp length,
void*
value,
95 static void copyswap(
void* dst,
void* src,
int swap,
void* ) {
98 T& t1 = *
static_cast<T*
>(dst);
99 T& t2 = *
static_cast<T*
>(src);
104 T& t1 = *
static_cast<T*
>(dst);
105 T& t2 = *
static_cast<T*
>(src);
110 static PyObject*
getitem(
void* ip,
void* ap) {
129 inline static int setitem(PyObject* src_obj,
void* dest_ptr,
void* array) {
135 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
136 PyArray_Descr* descr = PyArray_DTYPE(py_array);
137 PyTypeObject* array_scalar_type = descr->typeobj;
138 PyTypeObject* src_obj_type = Py_TYPE(src_obj);
140 if (array_scalar_type != src_obj_type) {
141 std::stringstream ss;
142 ss <<
"The input type is of wrong type. ";
143 ss <<
"The expected type is " << bp::type_info(
typeid(T)).name()
149 bp::extract<T&> extract_src_obj(src_obj);
150 if (!extract_src_obj.check()) {
151 std::stringstream ss;
152 ss <<
"The input type is of wrong type. ";
153 ss <<
"The expected type is " << bp::type_info(
typeid(T)).name()
159 const T& src = extract_src_obj();
160 T& dest = *
static_cast<T*
>(dest_ptr);
166 inline static void copyswapn(
void* dst,
long dstride,
void* src,
long sstride,
167 long n,
int swap,
void* array) {
170 char* dstptr =
static_cast<char*
>(dst);
171 char* srcptr =
static_cast<char*
>(src);
173 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
174 PyArray_CopySwapFunc* copyswap = PyArray_DESCR(py_array)->f->copyswap;
176 for (npy_intp i = 0; i < n; i++) {
177 copyswap(dstptr, srcptr, swap, array);
183 inline static npy_bool
nonzero(
void* ip,
void* array) {
185 static const T ZeroValue = T(0);
186 PyArrayObject* py_array =
static_cast<PyArrayObject*
>(array);
187 if (py_array == NULL || PyArray_ISBEHAVED_RO(py_array)) {
188 const T&
value = *
static_cast<T*
>(ip);
189 return (npy_bool)(value != ZeroValue);
192 PyArray_DESCR(py_array)->f->copyswap(
193 &tmp_value, ip, PyArray_ISBYTESWAPPED(py_array), array);
194 return (npy_bool)(tmp_value != ZeroValue);
198 inline static void dotfunc(
void* ip0_, npy_intp is0,
void* ip1_, npy_intp is1,
199 void* op, npy_intp n,
void* ) {
201 typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VectorT;
202 typedef Eigen::InnerStride<Eigen::Dynamic> InputStride;
203 typedef const Eigen::Map<const VectorT, 0, InputStride> ConstMapType;
205 ConstMapType v0(static_cast<T*>(ip0_), n,
206 InputStride(is0 / (Eigen::DenseIndex)
sizeof(T))),
207 v1(static_cast<T*>(ip1_), n,
208 InputStride(is1 / (Eigen::DenseIndex)
sizeof(T)));
210 *
static_cast<T*
>(op) = v0.dot(v1);
216 T
r = *
static_cast<T*
>(
value);
217 T* buffer =
static_cast<T*
>(buffer_);
219 for (i = 0; i < length; i++) {
225 static int fill(
void* data_, npy_intp length,
void* ) {
227 T*
data =
static_cast<T*
>(data_);
228 const T delta = data[1] - data[0];
231 for (i = 2; i < length; i++) {
242 template <
typename From,
typename To>
244 PyArray_Descr* from_array_descr = Register::getPyArrayDescr<From>();
248 int to_typenum = Register::getTypeCode<To>();
249 assert(to_typenum >= 0 &&
"to_typenum is not valid");
250 assert(from_array_descr != NULL &&
"from_array_descr is not valid");
260 static_cast<PyArray_VectorUnaryFunc*>(
261 &eigenpy::internal::cast<From, To>)) <
263 std::stringstream ss;
264 ss <<
"PyArray_RegisterCastFunc of the cast from " 265 << bp::type_info(
typeid(From)).name() <<
" to " 266 << bp::type_info(
typeid(To)).name() <<
" has failed.";
273 std::stringstream ss;
274 ss <<
"PyArray_RegisterCanCast of the cast from " 275 << bp::type_info(
typeid(From)).name() <<
" to " 276 << bp::type_info(
typeid(To)).name() <<
" has failed.";
286 template <
typename T>
289 bp::type_info type = bp::type_id<T>();
290 const bp::converter::registration* registration =
291 bp::converter::registry::query(type);
299 bp::handle<PyTypeObject> handle(
300 bp::borrowed(registration->get_class_object()));
301 return bp::object(handle);
304 template <
typename Scalar>
308 if (isNumpyNativeType<Scalar>())
312 if (py_type_ptr == NULL) {
313 py_type_ptr = Register::getPyType<Scalar>();
324 PyArray_CopySwapNFunc* copyswapn =
reinterpret_cast<PyArray_CopySwapNFunc*
>(
328 PyArray_FillWithScalarFunc* fillwithscalar =
332 py_type_ptr, &
typeid(Scalar),
sizeof(Scalar),
334 copyswapn, dotfunc, fill, fillwithscalar);
344 #endif // __eigenpy_user_type_hpp__
static npy_bool nonzero(void *ip, void *array)
static PyObject * getitem(void *ip, void *ap)
static int setitem(PyObject *src_obj, void *dest_ptr, void *array)
Set a python object in an array. It sets the Python object "item" into the array, arr...
boost::python::object getInstanceClass()
Get the class object for a wrapped type that has been exposed through Boost.Python.
bool registerCast(const bool safe)
static void dotfunc(void *ip0_, npy_intp is0, void *ip1_, npy_intp is1, void *op, npy_intp n, void *)
static int fillwithscalar(void *buffer_, npy_intp length, void *value, void *)
static To run(const From &from)
static int fill(void *data_, npy_intp length, void *)
int call_PyArray_RegisterCastFunc(PyArray_Descr *descr, int totype, PyArray_VectorUnaryFunc *castfunc)
int call_PyArray_RegisterCanCast(PyArray_Descr *descr, int totype, NPY_SCALARKIND scalar)
Default cast algo to cast a From to To. Can be specialized for any types.
static bool isRegistered()
static PyObject * run(void *data, void *)
Get a python object from an array It returns a standard Python object from a single element of the ar...
Eigen::TensorRef< Tensor > ref(Eigen::TensorRef< Tensor > tensor)
static void copyswap(void *dst, void *src, int swap, void *)
int registerNewType(PyTypeObject *py_type_ptr=NULL)
PyArray_Descr * call_PyArray_DescrFromType(int typenum)
static void cast(void *from_, void *to_, npy_intp n, void *, void *)
static int registerNewType(PyTypeObject *py_type_ptr, const std::type_info *type_info_ptr, const int type_size, const int alignment, PyArray_GetItemFunc *getitem, PyArray_SetItemFunc *setitem, PyArray_NonzeroFunc *nonzero, PyArray_CopySwapFunc *copyswap, PyArray_CopySwapNFunc *copyswapn, PyArray_DotFunc *dotfunc, PyArray_FillFunc *fill, PyArray_FillWithScalarFunc *fillwithscalar)
static void copyswapn(void *dst, long dstride, void *src, long sstride, long n, int swap, void *array)
void fill(Eigen::Ref< MatType > mat, const typename MatType::Scalar &value)