number.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2021-2022 INRIA
3 //
4 
5 #ifndef __pinocchio_python_math_multiprecision_boost_number_hpp__
6 #define __pinocchio_python_math_multiprecision_boost_number_hpp__
7 
9 
10 #include <boost/python.hpp>
11 #include <boost/python/return_value_policy.hpp>
12 #include <eigenpy/user-type.hpp>
13 #include <eigenpy/ufunc.hpp>
14 #include <sstream>
15 
16 namespace
17 {
18 
19  template<class Backend>
20  struct get_backend_precision
21  {
22  };
23 
24  template<unsigned Digits10, ::boost::multiprecision::mpfr_allocation_type AllocateType>
25  struct get_backend_precision<::boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>>
26  {
27  enum
28  {
29  value = Digits10
30  };
31  };
32 
33 } // namespace
34 
35 namespace eigenpy
36 {
37  namespace internal
38  {
39  template<class Backend, ::boost::multiprecision::expression_template_option ExpressionTemplates>
41  {
42 
43  typedef ::boost::multiprecision::number<Backend, ExpressionTemplates> Scalar;
44 
45  static PyObject * run(void * data, void * /* arr */)
46  {
47  Scalar & mpfr_scalar = *static_cast<Scalar *>(data);
48  Backend & backend = mpfr_scalar.backend();
49 
50  if (backend.data()[0]._mpfr_d == 0) // If the mpfr_scalar is not initialized, we have to
51  // init it.
52  {
53  mpfr_scalar = Scalar(0);
54  // unsigned int precision = get_backend_precision<Backend>::value ?
55  // get_backend_precision<Backend>::value : backend.default_precision();
56  // mpfr_init2(backend.data(),
57  // ::boost::multiprecision::detail::digits10_2_2(precision));
58  }
59  bp::object m(boost::ref(mpfr_scalar));
60  Py_INCREF(m.ptr());
61  return m.ptr();
62  }
63  };
64  } // namespace internal
65 
66 } // namespace eigenpy
67 
68 namespace pinocchio
69 {
70  namespace python
71  {
72  namespace bp = boost::python;
73 
74  template<typename BoostNumber>
76  : public boost::python::def_visitor<BoostNumberPythonVisitor<BoostNumber>>
77  {
78 
79  public:
80  template<class PyClass>
81  void visit(PyClass & cl) const
82  {
83  cl.def(bp::init<>("Default constructor.", bp::arg("self")))
84  .def(bp::init<BoostNumber>("Copy constructor.", bp::args("self", "value")))
85  // .def(bp::init<bool>("Copy constructor.",bp::args("self","value")))
86  // .def(bp::init<float>("Copy constructor.",bp::args("self","value")))
87  // .def(bp::init<double>("Copy constructor.",bp::args("self","value")))
88  // .def(bp::init<int>("Copy constructor.",bp::args("self","value")))
89  // .def(bp::init<long int>("Copy constructor.",bp::args("self","value")))
90  // .def(bp::init<unsigned int>("Copy constructor.",bp::args("self","value")))
91  // .def(bp::init<unsigned long int>("Copy constructor.",bp::args("self","value")))
92  .def(bp::init<std::string>("Constructor from a string.", bp::args("self", "str_value")));
93 
96  cl.def(bp::self + bp::self)
97  .def(bp::self += bp::self)
98  .def(bp::self - bp::self)
99  .def(bp::self -= bp::self)
100  .def(bp::self * bp::self)
101  .def(bp::self *= bp::self)
102  .def(bp::self / bp::self)
103  .def(bp::self /= bp::self)
104 
105  .def(bp::self < bp::self)
106  .def(bp::self <= bp::self)
107  .def(bp::self > bp::self)
108  .def(bp::self >= bp::self)
109  .def(bp::self == bp::self)
110  .def(bp::self != bp::self)
111  .def(bp::self_ns::pow(bp::self_ns::self, long()));
113 
114  cl.def("str", &BoostNumber::str, bp::args("self", "precision", "scientific"))
115 
116  .def(
117  "default_precision", static_cast<unsigned (*)()>(BoostNumber::default_precision),
118  "Get the default precision of the class.")
119  .def(
120  "default_precision", static_cast<void (*)(unsigned)>(BoostNumber::default_precision),
121  bp::arg("digits10"), "Set the default precision of the class.")
122  .staticmethod("default_precision")
123 
124  .def(
125  "precision", static_cast<unsigned (BoostNumber::*)() const>(&BoostNumber::precision),
126  bp::arg("self"), "Get the precision of this.")
127  .def(
128  "precision", static_cast<void (BoostNumber::*)(unsigned)>(&BoostNumber::precision),
129  bp::args("self", "digits10"), "Set the precision of this.")
130 
131  .def("__float__", &cast<double>, bp::arg("self"), "Cast to float.")
132  .def("__int__", &cast<int64_t>, bp::arg("self"), "Cast to int.")
133 
134  .def("__str__", &print, bp::arg("self"))
135  .def("__repr__", &print, bp::arg("self"))
136 
137  .def(
138  "set_display_precision", &set_display_precision, bp::arg("digit"),
139  "Set the precision when printing values.")
140  .staticmethod("set_display_precision")
141 
142  .def(
143  "get_display_precision", &get_display_precision,
144  "Get the precision when printing values.",
145  bp::return_value_policy<bp::copy_non_const_reference>())
146  .staticmethod("get_display_precision")
147 
148  // #ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
149  // .def_pickle(Pickle())
150  // #endif
151  ;
152  }
153 
154  static void expose(const std::string & type_name)
155  {
156  bp::class_<BoostNumber>(type_name.c_str(), "", bp::no_init)
158 
159  eigenpy::registerNewType<BoostNumber>();
160  eigenpy::registerCommonUfunc<BoostNumber>();
161 
162 #define IMPLICITLY_CONVERTIBLE(T1, T2) bp::implicitly_convertible<T1, T2>();
163  // bp::implicitly_convertible<T2,T1>();
164 
165  IMPLICITLY_CONVERTIBLE(double, BoostNumber);
166  IMPLICITLY_CONVERTIBLE(float, BoostNumber);
167  IMPLICITLY_CONVERTIBLE(long int, BoostNumber);
168  IMPLICITLY_CONVERTIBLE(int, BoostNumber);
169  IMPLICITLY_CONVERTIBLE(long, BoostNumber);
170  IMPLICITLY_CONVERTIBLE(unsigned int, BoostNumber);
171  IMPLICITLY_CONVERTIBLE(unsigned long int, BoostNumber);
172  IMPLICITLY_CONVERTIBLE(bool, BoostNumber);
173 
174 #undef IMPLICITLY_CONVERTIBLE
175 
176  eigenpy::registerCast<BoostNumber, double>(false);
177  eigenpy::registerCast<double, BoostNumber>(true);
178  eigenpy::registerCast<BoostNumber, float>(false);
179  eigenpy::registerCast<float, BoostNumber>(true);
180  eigenpy::registerCast<BoostNumber, long>(false);
181  eigenpy::registerCast<long, BoostNumber>(true);
182  eigenpy::registerCast<BoostNumber, int>(false);
183  eigenpy::registerCast<int, BoostNumber>(true);
184  ;
185  eigenpy::registerCast<BoostNumber, int64_t>(false);
186  eigenpy::registerCast<int64_t, BoostNumber>(true);
187  }
188 
189  private:
190  template<typename T>
191  static T cast(const BoostNumber & self)
192  {
193  return static_cast<T>(self);
194  }
195 
196  static std::string print(const BoostNumber & self)
197  {
198  return self.str(get_display_precision(), std::ios_base::dec);
199  }
200 
201  static void set_display_precision(const int digit)
202  {
203  get_display_precision() = digit;
204  }
205 
206  static int & get_display_precision()
207  {
208  static int precision = BoostNumber::default_precision();
209  return precision;
210  }
211 
212  // struct Pickle : bp::pickle_suite
213  // {
214  // static
215  // boost::python::tuple
216  // getinitargs(const SE3 & M)
217  // { return bp::make_tuple((Matrix3)M.rotation(),(Vector3)M.translation()); }
218  // };
219  };
220 
221  } // namespace python
222 } // namespace pinocchio
223 
224 #endif // ifndef __pinocchio_python_math_multiprecision_boost_number_hpp__
simulation-contact-dynamics.T
int T
Definition: simulation-contact-dynamics.py:89
boost::python
test-cpp2pybind11.m
m
Definition: test-cpp2pybind11.py:25
eigenpy::internal::getitem<::boost::multiprecision::number< Backend, ExpressionTemplates > >::run
static PyObject * run(void *data, void *)
Definition: number.hpp:45
eigenpy::internal::getitem
PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_SELF_ASSIGN_OVERLOADED
#define PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_SELF_ASSIGN_OVERLOADED
Definition: include/pinocchio/macros.hpp:133
setup.data
data
Definition: cmake/cython/setup.in.py:48
pinocchio::python::BoostNumberPythonVisitor::cast
static T cast(const BoostNumber &self)
Definition: number.hpp:191
PINOCCHIO_COMPILER_DIAGNOSTIC_POP
#define PINOCCHIO_COMPILER_DIAGNOSTIC_POP
Definition: include/pinocchio/macros.hpp:130
pinocchio::python::Scalar
context::Scalar Scalar
Definition: admm-solver.cpp:29
pinocchio::python::BoostNumberPythonVisitor
Definition: number.hpp:75
IMPLICITLY_CONVERTIBLE
#define IMPLICITLY_CONVERTIBLE(T1, T2)
eigenpy
eigenpy::internal::getitem<::boost::multiprecision::number< Backend, ExpressionTemplates > >::Scalar
::boost::multiprecision::number< Backend, ExpressionTemplates > Scalar
Definition: number.hpp:43
pinocchio::python::BoostNumberPythonVisitor::print
static std::string print(const BoostNumber &self)
Definition: number.hpp:196
python
value
float value
PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
#define PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
macros for pragma push/pop/ignore deprecated warnings
Definition: include/pinocchio/macros.hpp:129
user-type.hpp
pinocchio::python::BoostNumberPythonVisitor::set_display_precision
static void set_display_precision(const int digit)
Definition: number.hpp:201
multiprecision.hpp
cl
cl
ufunc.hpp
pinocchio::python::BoostNumberPythonVisitor::get_display_precision
static int & get_display_precision()
Definition: number.hpp:206
pinocchio::python::BoostNumberPythonVisitor::visit
void visit(PyClass &cl) const
Definition: number.hpp:81
pinocchio::python::BoostNumberPythonVisitor::expose
static void expose(const std::string &type_name)
Definition: number.hpp:154
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27


pinocchio
Author(s):
autogenerated on Sun Dec 22 2024 03:41:12