/* * Copyright 2020 INRIA */ #include "eigenpy/eigenpy.hpp" #include "eigenpy/user-type.hpp" #include "eigenpy/ufunc.hpp" #include #include template struct CustomType; namespace Eigen { /// @brief Eigen::NumTraits<> specialization for casadi::SX /// template struct NumTraits< CustomType > { typedef CustomType Real; typedef CustomType NonInteger; typedef CustomType Literal; typedef CustomType Nested; enum { // does not support complex Base types IsComplex = 0 , // does not support integer Base types IsInteger = 0 , // only support signed Base types IsSigned = 1 , // must initialize an AD object RequireInitialization = 1 , // computational cost of the corresponding operations ReadCost = 1 , AddCost = 2 , MulCost = 2 }; static CustomType epsilon() { return CustomType(std::numeric_limits::epsilon()); } static CustomType dummy_precision() { return CustomType(NumTraits::dummy_precision()); } static CustomType highest() { return CustomType(std::numeric_limits::max()); } static CustomType lowest() { return CustomType(std::numeric_limits::min()); } static int digits10() { return std::numeric_limits::digits10; } }; } // namespace Eigen template struct CustomType { CustomType() {} explicit CustomType(const Scalar & value) : m_value(value) {} CustomType operator*(const CustomType & other) const { return CustomType(m_value * other.m_value); } CustomType operator+(const CustomType & other) const { return CustomType(m_value + other.m_value); } CustomType operator-(const CustomType & other) const { return CustomType(m_value - other.m_value); } CustomType operator/(const CustomType & other) const { return CustomType(m_value / other.m_value); } void operator+=(const CustomType & other) { m_value += other.m_value; } void operator-=(const CustomType & other) { m_value -= other.m_value; } void operator*=(const CustomType & other) { m_value *= other.m_value; } void operator/=(const CustomType & other) { m_value /= other.m_value; } void operator=(const Scalar & value) { m_value = value; } bool operator==(const CustomType & other) const { return m_value == other.m_value; } bool operator!=(const CustomType & other) const { return m_value != other.m_value; } bool operator<=(const CustomType & other) const { return m_value <= other.m_value; } bool operator<(const CustomType & other) const { return m_value < other.m_value; } bool operator>=(const CustomType & other) const { return m_value >= other.m_value; } bool operator>(const CustomType & other) const { return m_value > other.m_value; } CustomType operator-() const { return CustomType(-m_value); } operator Scalar () const { return m_value; } std::string print() const { std::stringstream ss; ss << "value: " << m_value << std::endl; return ss.str(); } friend std::ostream & operator <<(std::ostream & os, const CustomType & X) { os << X.m_value; return os; } //protected: Scalar m_value; }; template Eigen::Matrix,Eigen::Dynamic,Eigen::Dynamic> create(int rows, int cols) { typedef Eigen::Matrix,Eigen::Dynamic,Eigen::Dynamic> Matrix; return Matrix(rows,cols); } template void print(const Eigen::Matrix,Eigen::Dynamic,Eigen::Dynamic> & mat) { std::cout << mat << std::endl; } template Eigen::Matrix build_matrix(int rows, int cols) { typedef Eigen::Matrix Matrix; return Matrix(rows,cols); } template void expose_custom_type(const std::string & name) { using namespace Eigen; namespace bp = boost::python; typedef CustomType Type; bp::class_(name.c_str(),bp::init(bp::arg("value"))) .def(bp::self + bp::self) .def(bp::self - bp::self) .def(bp::self * bp::self) .def(bp::self / bp::self) .def(bp::self += bp::self) .def(bp::self -= bp::self) .def(bp::self *= bp::self) .def(bp::self /= bp::self) .def("__repr__",&Type::print) ; int code = eigenpy::registerNewType(); std::cout << "code: " << code << std::endl; eigenpy::registerCommonUfunc(); } BOOST_PYTHON_MODULE(user_type) { using namespace Eigen; namespace bp = boost::python; eigenpy::enableEigenPy(); expose_custom_type("CustomDouble"); typedef CustomType DoubleType; typedef Eigen::Matrix DoubleMatrix; eigenpy::EigenToPyConverter::registration(); eigenpy::EigenFromPyConverter::registration(); bp::def("create_double",create); expose_custom_type("CustomFloat"); typedef CustomType FloatType; typedef Eigen::Matrix FloatMatrix; eigenpy::EigenToPyConverter::registration(); eigenpy::EigenFromPyConverter::registration(); bp::def("create_float",create); bp::def("build_matrix",build_matrix); bp::def("print",print); bp::def("print",print); eigenpy::registerCast(true); eigenpy::registerCast(true); eigenpy::registerCast(false); eigenpy::registerCast(true); eigenpy::registerCast(false); eigenpy::registerCast(true); eigenpy::registerCast(false); eigenpy::registerCast(true); bp::implicitly_convertible(); bp::implicitly_convertible(); }