pinocchio  3.7.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
 
Loading...
Searching...
No Matches
number.hpp
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
8#include "pinocchio/math/multiprecision.hpp"
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
16namespace
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
35namespace eigenpy
36{
37 namespace internal
38 {
39 template<class Backend, ::boost::multiprecision::expression_template_option ExpressionTemplates>
40 struct getitem<::boost::multiprecision::number<Backend, 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
68namespace pinocchio
69{
70 namespace python
71 {
72 namespace bp = boost::python;
73
74 template<typename BoostNumber>
75 struct BoostNumberPythonVisitor
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
94 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
95 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_SELF_ASSIGN_OVERLOADED
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()));
112 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
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)
157 .def(BoostNumberPythonVisitor<BoostNumber>());
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__
Main pinocchio namespace.
Definition treeview.dox:11