From 5c39159adfa53e46b7706cd07c8f43464f6cc7fc Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 31 Jan 2020 16:00:01 +0100 Subject: [PATCH 1/5] core: add guard --- include/eigenpy/map.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/eigenpy/map.hpp b/include/eigenpy/map.hpp index b8c218035..db5ffc89f 100644 --- a/include/eigenpy/map.hpp +++ b/include/eigenpy/map.hpp @@ -3,6 +3,9 @@ * Copyright 2018-2020, INRIA */ +#ifndef __eigenpy_map_hpp__ +#define __eigenpy_map_hpp__ + #include "eigenpy/fwd.hpp" #include #include "eigenpy/exception.hpp" @@ -126,3 +129,5 @@ namespace eigenpy } } // namespace eigenpy + +#endif // define __eigenpy_map_hpp__ From d78bfea725d9f718f1af53bd6ac3bb5dd9c67e36 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 31 Jan 2020 16:38:32 +0100 Subject: [PATCH 2/5] core: fix init bug for NumpyType --- include/eigenpy/details.hpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/include/eigenpy/details.hpp b/include/eigenpy/details.hpp index d32ec38f3..2f78813b5 100644 --- a/include/eigenpy/details.hpp +++ b/include/eigenpy/details.hpp @@ -79,18 +79,18 @@ namespace eigenpy return instance; } - operator bp::object () { return CurrentNumpyType; } + operator bp::object () { return getInstance().CurrentNumpyType; } - bp::object make(PyArrayObject* pyArray, bool copy = false) + static bp::object make(PyArrayObject* pyArray, bool copy = false) { return make((PyObject*)pyArray,copy); } - bp::object make(PyObject* pyObj, bool copy = false) + static bp::object make(PyObject* pyObj, bool copy = false) { bp::object m; - if(PyType_IsSubtype(reinterpret_cast(CurrentNumpyType.ptr()),NumpyMatrixType)) - m = NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy); + if(isMatrix()) + m = getInstance().NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy); // m = NumpyAsMatrixObject(bp::object(bp::handle<>(pyObj))); - else if(PyType_IsSubtype(reinterpret_cast(CurrentNumpyType.ptr()),NumpyArrayType)) + else if(isArray()) m = bp::object(bp::handle<>(pyObj)); // nothing to do here Py_INCREF(m.ptr()); @@ -109,19 +109,18 @@ namespace eigenpy static void switchToNumpyArray() { getInstance().CurrentNumpyType = getInstance().NumpyArrayObject; - getType() = ARRAY_TYPE; + getInstance().getType() = ARRAY_TYPE; } static void switchToNumpyMatrix() { getInstance().CurrentNumpyType = getInstance().NumpyMatrixObject; - getType() = MATRIX_TYPE; + getInstance().getType() = MATRIX_TYPE; } static NP_TYPE & getType() { - static NP_TYPE np_type; - return np_type; + return getInstance().np_type; } static bp::object getNumpyType() @@ -147,6 +146,7 @@ namespace eigenpy static bool isArray() { + if(getInstance().isMatrix()) return false; return PyType_IsSubtype(reinterpret_cast(getInstance().CurrentNumpyType.ptr()), getInstance().NumpyArrayType); } @@ -169,7 +169,7 @@ namespace eigenpy //NumpyAsMatrixType = reinterpret_cast(NumpyAsMatrixObject.ptr()); CurrentNumpyType = NumpyArrayObject; // default conversion - getType() = ARRAY_TYPE; + np_type = ARRAY_TYPE; } bp::object CurrentNumpyType; @@ -179,7 +179,8 @@ namespace eigenpy bp::object NumpyMatrixObject; PyTypeObject * NumpyMatrixType; //bp::object NumpyAsMatrixObject; PyTypeObject * NumpyAsMatrixType; bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType; - + + NP_TYPE np_type; }; template From 3ad7a2f733213c1f75c7370c64324cfe6f91fda5 Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 31 Jan 2020 17:23:34 +0100 Subject: [PATCH 3/5] core: add dedicated file for NumpyType --- CMakeLists.txt | 1 + include/eigenpy/details.hpp | 120 +--------------------------- include/eigenpy/numpy-type.hpp | 138 +++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 119 deletions(-) create mode 100644 include/eigenpy/numpy-type.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fcd917f88..a7bb4914f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ SET(${PROJECT_NAME}_HEADERS include/eigenpy/geometry.hpp include/eigenpy/geometry-conversion.hpp include/eigenpy/memory.hpp + include/eigenpy/numpy-type.hpp include/eigenpy/registration.hpp include/eigenpy/angle-axis.hpp include/eigenpy/quaternion.hpp diff --git a/include/eigenpy/details.hpp b/include/eigenpy/details.hpp index 2f78813b5..89ebdc400 100644 --- a/include/eigenpy/details.hpp +++ b/include/eigenpy/details.hpp @@ -13,6 +13,7 @@ #include #include "eigenpy/eigenpy.hpp" +#include "eigenpy/numpy-type.hpp" #include "eigenpy/registration.hpp" #include "eigenpy/map.hpp" #include "eigenpy/exception.hpp" @@ -64,125 +65,6 @@ namespace eigenpy namespace bp = boost::python; - enum NP_TYPE - { - MATRIX_TYPE, - ARRAY_TYPE - }; - - struct NumpyType - { - - static NumpyType & getInstance() - { - static NumpyType instance; - return instance; - } - - operator bp::object () { return getInstance().CurrentNumpyType; } - - static bp::object make(PyArrayObject* pyArray, bool copy = false) - { return make((PyObject*)pyArray,copy); } - - static bp::object make(PyObject* pyObj, bool copy = false) - { - bp::object m; - if(isMatrix()) - m = getInstance().NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy); -// m = NumpyAsMatrixObject(bp::object(bp::handle<>(pyObj))); - else if(isArray()) - m = bp::object(bp::handle<>(pyObj)); // nothing to do here - - Py_INCREF(m.ptr()); - return m; - } - - static void setNumpyType(bp::object & obj) - { - PyTypeObject * obj_type = PyType_Check(obj.ptr()) ? reinterpret_cast(obj.ptr()) : obj.ptr()->ob_type; - if(PyType_IsSubtype(obj_type,getInstance().NumpyMatrixType)) - switchToNumpyMatrix(); - else if(PyType_IsSubtype(obj_type,getInstance().NumpyArrayType)) - switchToNumpyArray(); - } - - static void switchToNumpyArray() - { - getInstance().CurrentNumpyType = getInstance().NumpyArrayObject; - getInstance().getType() = ARRAY_TYPE; - } - - static void switchToNumpyMatrix() - { - getInstance().CurrentNumpyType = getInstance().NumpyMatrixObject; - getInstance().getType() = MATRIX_TYPE; - } - - static NP_TYPE & getType() - { - return getInstance().np_type; - } - - static bp::object getNumpyType() - { - return getInstance().CurrentNumpyType; - } - - static const PyTypeObject * getNumpyMatrixType() - { - return getInstance().NumpyMatrixType; - } - - static const PyTypeObject * getNumpyArrayType() - { - return getInstance().NumpyArrayType; - } - - static bool isMatrix() - { - return PyType_IsSubtype(reinterpret_cast(getInstance().CurrentNumpyType.ptr()), - getInstance().NumpyMatrixType); - } - - static bool isArray() - { - if(getInstance().isMatrix()) return false; - return PyType_IsSubtype(reinterpret_cast(getInstance().CurrentNumpyType.ptr()), - getInstance().NumpyArrayType); - } - - protected: - NumpyType() - { - pyModule = bp::import("numpy"); -#if PY_MAJOR_VERSION >= 3 - // TODO I don't know why this Py_INCREF is necessary. - // Without it, the destructor of NumpyType SEGV sometimes. - Py_INCREF(pyModule.ptr()); -#endif - - NumpyMatrixObject = pyModule.attr("matrix"); - NumpyMatrixType = reinterpret_cast(NumpyMatrixObject.ptr()); - NumpyArrayObject = pyModule.attr("ndarray"); - NumpyArrayType = reinterpret_cast(NumpyArrayObject.ptr()); - //NumpyAsMatrixObject = pyModule.attr("asmatrix"); - //NumpyAsMatrixType = reinterpret_cast(NumpyAsMatrixObject.ptr()); - - CurrentNumpyType = NumpyArrayObject; // default conversion - np_type = ARRAY_TYPE; - } - - bp::object CurrentNumpyType; - bp::object pyModule; - - // Numpy types - bp::object NumpyMatrixObject; PyTypeObject * NumpyMatrixType; - //bp::object NumpyAsMatrixObject; PyTypeObject * NumpyAsMatrixType; - bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType; - - NP_TYPE np_type; - }; - template struct initEigenObject { diff --git a/include/eigenpy/numpy-type.hpp b/include/eigenpy/numpy-type.hpp new file mode 100644 index 000000000..07be4c99a --- /dev/null +++ b/include/eigenpy/numpy-type.hpp @@ -0,0 +1,138 @@ +/* + * Copyright 2018-2020, INRIA +*/ + +#ifndef __eigenpy_numpy_type_hpp__ +#define __eigenpy_numpy_type_hpp__ + +#include "eigenpy/fwd.hpp" + +#include +#include // For PY_MAJOR_VERSION + +namespace eigenpy +{ + namespace bp = boost::python; + + enum NP_TYPE + { + MATRIX_TYPE, + ARRAY_TYPE + }; + + struct NumpyType + { + + static NumpyType & getInstance() + { + static NumpyType instance; + return instance; + } + + operator bp::object () { return getInstance().CurrentNumpyType; } + + static bp::object make(PyArrayObject* pyArray, bool copy = false) + { return make((PyObject*)pyArray,copy); } + + static bp::object make(PyObject* pyObj, bool copy = false) + { + bp::object m; + if(isMatrix()) + m = getInstance().NumpyMatrixObject(bp::object(bp::handle<>(pyObj)), bp::object(), copy); +// m = NumpyAsMatrixObject(bp::object(bp::handle<>(pyObj))); + else if(isArray()) + m = bp::object(bp::handle<>(pyObj)); // nothing to do here + + Py_INCREF(m.ptr()); + return m; + } + + static void setNumpyType(bp::object & obj) + { + PyTypeObject * obj_type = PyType_Check(obj.ptr()) ? reinterpret_cast(obj.ptr()) : obj.ptr()->ob_type; + if(PyType_IsSubtype(obj_type,getInstance().NumpyMatrixType)) + switchToNumpyMatrix(); + else if(PyType_IsSubtype(obj_type,getInstance().NumpyArrayType)) + switchToNumpyArray(); + } + + static void switchToNumpyArray() + { + getInstance().CurrentNumpyType = getInstance().NumpyArrayObject; + getInstance().getType() = ARRAY_TYPE; + } + + static void switchToNumpyMatrix() + { + getInstance().CurrentNumpyType = getInstance().NumpyMatrixObject; + getInstance().getType() = MATRIX_TYPE; + } + + static NP_TYPE & getType() + { + return getInstance().np_type; + } + + static bp::object getNumpyType() + { + return getInstance().CurrentNumpyType; + } + + static const PyTypeObject * getNumpyMatrixType() + { + return getInstance().NumpyMatrixType; + } + + static const PyTypeObject * getNumpyArrayType() + { + return getInstance().NumpyArrayType; + } + + static bool isMatrix() + { + return PyType_IsSubtype(reinterpret_cast(getInstance().CurrentNumpyType.ptr()), + getInstance().NumpyMatrixType); + } + + static bool isArray() + { + if(getInstance().isMatrix()) return false; + return PyType_IsSubtype(reinterpret_cast(getInstance().CurrentNumpyType.ptr()), + getInstance().NumpyArrayType); + } + + protected: + NumpyType() + { + pyModule = bp::import("numpy"); +#if PY_MAJOR_VERSION >= 3 + // TODO I don't know why this Py_INCREF is necessary. + // Without it, the destructor of NumpyType SEGV sometimes. + Py_INCREF(pyModule.ptr()); +#endif + + NumpyMatrixObject = pyModule.attr("matrix"); + NumpyMatrixType = reinterpret_cast(NumpyMatrixObject.ptr()); + NumpyArrayObject = pyModule.attr("ndarray"); + NumpyArrayType = reinterpret_cast(NumpyArrayObject.ptr()); + //NumpyAsMatrixObject = pyModule.attr("asmatrix"); + //NumpyAsMatrixType = reinterpret_cast(NumpyAsMatrixObject.ptr()); + + CurrentNumpyType = NumpyArrayObject; // default conversion + np_type = ARRAY_TYPE; + } + + bp::object CurrentNumpyType; + bp::object pyModule; + + // Numpy types + bp::object NumpyMatrixObject; PyTypeObject * NumpyMatrixType; + //bp::object NumpyAsMatrixObject; PyTypeObject * NumpyAsMatrixType; + bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType; + + NP_TYPE np_type; + }; + +} + +#endif // ifndef __eigenpy_numpy_type_hpp__ From 7769170fcbf8842a1b58fe331e51baa3731aa3ec Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 31 Jan 2020 17:29:22 +0100 Subject: [PATCH 4/5] cmake: sync submodule --- cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake b/cmake index ba8e9f82f..61344038b 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit ba8e9f82f52d74865b42262de61bb884bf373550 +Subproject commit 61344038b1352d5a8de1e20db710c83be805d2eb From 3e93257557b4d8afff25689b9c22a04031d0a74a Mon Sep 17 00:00:00 2001 From: Justin Carpentier Date: Fri, 31 Jan 2020 17:57:47 +0100 Subject: [PATCH 5/5] test: fix test --- unittest/python/test_dimensions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/unittest/python/test_dimensions.py b/unittest/python/test_dimensions.py index 3ccc354b7..8a7892a95 100644 --- a/unittest/python/test_dimensions.py +++ b/unittest/python/test_dimensions.py @@ -5,6 +5,7 @@ quat = eigenpy.Quaternion() # By default, we convert as numpy.matrix +eigenpy.switchToNumpyMatrix() coeffs_vector = quat.coeffs() assert len(coeffs_vector.shape) == 2