multiprecision.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 INRIA
3 //
4 
5 #ifndef __pinocchio_math_mutliprecision_hpp__
6 #define __pinocchio_math_mutliprecision_hpp__
7 
8 #include "pinocchio/math/fwd.hpp"
9 
10 #include <boost/multiprecision/number.hpp>
11 #include <boost/random.hpp>
12 #include <Eigen/Dense>
13 
14 namespace pinocchio
15 {
16  // We check std::numeric_limits<_>::has_infinity to exclude integral, rational
17  // and complex types
18  template<typename Backend, boost::multiprecision::expression_template_option ET>
20  : boost::integral_constant<
21  bool,
22  ((!std::numeric_limits<boost::multiprecision::number<Backend, ET>>::is_integer
23  && std::numeric_limits<boost::multiprecision::number<Backend, ET>>::has_infinity))>
24  {
25  };
26 } // namespace pinocchio
27 
28 namespace Eigen
29 {
30  namespace internal
31  {
32  template<
33  class Backend,
34  boost::multiprecision::expression_template_option ExpressionTemplates,
35  typename Scalar>
36  struct cast_impl<boost::multiprecision::number<Backend, ExpressionTemplates>, Scalar>
37  {
38 #if EIGEN_VERSION_AT_LEAST(3, 2, 90)
40 #endif
41  static inline Scalar
42  run(const boost::multiprecision::number<Backend, ExpressionTemplates> & x)
43  {
44  return x.template convert_to<Scalar>();
45  }
46  };
47  } // namespace internal
48 } // namespace Eigen
49 
50 #ifndef BOOST_MP_EIGEN_HPP
51 
52 // Code adapted from <boost/multiprecision/eigen.hpp>
53 // Copyright 2018 John Maddock. Distributed under the Boost
54 // Software License, Version 1.0. (See accompanying file
55 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
56 namespace Eigen
57 {
58  template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
59  struct NumTraits<boost::multiprecision::number<Backend, ExpressionTemplates>>
60  {
61  typedef boost::multiprecision::number<Backend, ExpressionTemplates> self_type;
62  #if BOOST_VERSION / 100 % 1000 >= 68
63  typedef
65  #else
66  typedef self_type Real;
67  #endif
68  typedef self_type NonInteger; // Not correct but we can't do much better??
69  typedef double Literal;
70  typedef self_type Nested;
71  enum
72  {
73  #if BOOST_VERSION / 100 % 1000 >= 68
74  IsComplex = boost::multiprecision::number_category<self_type>::value
75  == boost::multiprecision::number_kind_complex,
76  #else
77  IsComplex = 0,
78  #endif
79  IsInteger = boost::multiprecision::number_category<self_type>::value
80  == boost::multiprecision::number_kind_integer,
81  ReadCost = 1,
82  AddCost = 4,
83  MulCost = 8,
84  IsSigned = std::numeric_limits<self_type>::is_specialized
85  ? std::numeric_limits<self_type>::is_signed
86  : true,
87  RequireInitialization = 1
88  };
89  static Real epsilon()
90  {
91  return std::numeric_limits<Real>::epsilon();
92  }
94  {
95  return 1000 * epsilon();
96  }
97  static Real highest()
98  {
100  }
101  static Real lowest()
102  {
104  }
105  static int digits10_imp(const boost::mpl::true_ &)
106  {
107  return std::numeric_limits<Real>::digits10;
108  }
109  template<bool B>
110  static int digits10_imp(const boost::mpl::bool_<B> &)
111  {
112  return static_cast<int>(Real::default_precision());
113  }
114  static int digits10()
115  {
116  return digits10_imp(
117  boost::mpl::bool_<
118  std::numeric_limits<Real>::digits10 && (std::numeric_limits<Real>::digits10 != INT_MAX)
119  ? true
120  : false>());
121  }
122 
123  constexpr static inline int digits()
124  {
126  }
127 
128  #if EIGEN_VERSION_AT_LEAST(3, 4, 90)
129  constexpr static inline int max_digits10()
130  {
132  }
133  #endif
134  };
135 
136  template<class tag, class Arg1, class Arg2, class Arg3, class Arg4>
137  struct NumTraits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>>
138  : public NumTraits<
139  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>
140  {
141  };
142 
143  #if EIGEN_VERSION_AT_LEAST(3, 4, 90)
144  // Fix random generator number in 3.4.90. TODO(jcarpent): Yet, we should wait for Eigen 3.5.0 to
145  // the proper fix in Eigen/src/Core/MathFunctions.h.
146  namespace internal
147  {
148  template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
149  struct random_default_impl<
150  boost::multiprecision::number<Backend, ExpressionTemplates>,
151  false,
152  false>
153  {
154  typedef boost::multiprecision::number<Backend, ExpressionTemplates> Scalar;
155 
156  static inline Scalar run(const Scalar & x, const Scalar & y)
157  {
158  return x + (y - x) * Scalar(std::rand()) / Scalar(RAND_MAX);
159  }
160  static inline Scalar run()
161  {
162  return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
163  }
164  };
165  } // namespace internal
166  #endif
167 
168  #if EIGEN_VERSION_AT_LEAST(3, 2, 93)
169  #define BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(A) \
170  template< \
171  class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, \
172  typename BinaryOp> \
173  struct ScalarBinaryOpTraits< \
174  boost::multiprecision::number<Backend, ExpressionTemplates>, A, BinaryOp> \
175  { \
176  /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, \
177  * boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability \
178  * with this arithmetic type is not supported.");*/ \
179  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
180  }; \
181  template< \
182  class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, \
183  typename BinaryOp> \
184  struct ScalarBinaryOpTraits< \
185  A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
186  { \
187  /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, \
188  * boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability \
189  * with this arithmetic type is not supported.");*/ \
190  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
191  };
192 
193  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(float)
194  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(double)
195  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long double)
196  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(char)
197  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned char)
198  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(signed char)
199  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(short)
200  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned short)
201  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(int)
202  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned int)
203  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long)
204  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned long)
205 
206  template<
207  class Backend,
208  boost::multiprecision::expression_template_option ExpressionTemplates,
209  class tag,
210  class Arg1,
211  class Arg2,
212  class Arg3,
213  class Arg4,
214  typename BinaryOp>
215  struct ScalarBinaryOpTraits<
216  boost::multiprecision::number<Backend, ExpressionTemplates>,
217  boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>,
218  BinaryOp>
219  {
220  static_assert(
221  boost::is_convertible<
222  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::
223  result_type,
224  boost::multiprecision::number<Backend, ExpressionTemplates>>::value,
225  "Interoperability with this arithmetic type is not supported.");
226  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
227  };
228 
229  template<
230  class tag,
231  class Arg1,
232  class Arg2,
233  class Arg3,
234  class Arg4,
235  class Backend,
236  boost::multiprecision::expression_template_option ExpressionTemplates,
237  typename BinaryOp>
238  struct ScalarBinaryOpTraits<
239  boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>,
240  boost::multiprecision::number<Backend, ExpressionTemplates>,
241  BinaryOp>
242  {
243  static_assert(
244  boost::is_convertible<
245  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::
246  result_type,
247  boost::multiprecision::number<Backend, ExpressionTemplates>>::value,
248  "Interoperability with this arithmetic type is not supported.");
249  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
250  };
251  #endif
252 
253  namespace internal
254  {
255 
256  template<
257  class Backend,
258  boost::multiprecision::expression_template_option ExpressionTemplates,
259  class tag,
260  class Arg1,
261  class Arg2,
262  class Arg3,
263  class Arg4>
264  struct scalar_product_traits<
265  boost::multiprecision::number<Backend, ExpressionTemplates>,
266  boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>>
267  {
268  static_assert(
269  boost::is_convertible<
270  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::
271  result_type,
272  boost::multiprecision::number<Backend, ExpressionTemplates>>::value,
273  "Interoperability with this arithmetic type is not supported.");
274  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
275  };
276 
277  template<
278  class tag,
279  class Arg1,
280  class Arg2,
281  class Arg3,
282  class Arg4,
283  class Backend,
284  boost::multiprecision::expression_template_option ExpressionTemplates>
285  struct scalar_product_traits<
286  boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>,
287  boost::multiprecision::number<Backend, ExpressionTemplates>>
288  {
289  static_assert(
290  boost::is_convertible<
291  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::
292  result_type,
293  boost::multiprecision::number<Backend, ExpressionTemplates>>::value,
294  "Interoperability with this arithmetic type is not supported.");
295  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
296  };
297 
298  template<typename Scalar>
299  struct conj_retval;
300 
301  template<typename Scalar, bool IsComplex>
302  #if EIGEN_VERSION_AT_LEAST(3, 3, 9)
303  struct conj_default_impl;
304  #else
305  struct conj_impl;
306  #endif
307 
308  template<class tag, class Arg1, class Arg2, class Arg3, class Arg4>
309  struct conj_retval<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>>
310  {
311  typedef
312  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type
314  };
315 
316  template<class tag, class Arg1, class Arg2, class Arg3, class Arg4>
317  #if EIGEN_VERSION_AT_LEAST(3, 3, 9)
318  struct conj_default_impl<
319  boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>,
320  true>
321  #else
322  struct conj_impl<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, true>
323  #endif
324  {
325  #if EIGEN_VERSION_AT_LEAST(3, 2, 90)
327  #endif
328  static inline
329  typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type
331  const typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> & x)
332  {
333  return conj(x);
334  }
335  };
336 
337  } // namespace internal
338 
339 } // namespace Eigen
340 
341 #endif // ifndef BOOST_MP_EIGEN_HPP
342 
343 #endif // ifndef __pinocchio_math_mutliprecision_hpp__
common_symbols.type
type
Definition: common_symbols.py:34
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::highest
static Real highest()
Definition: multiprecision.hpp:97
Eigen
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::epsilon
static Real epsilon()
Definition: multiprecision.hpp:89
Eigen::internal::conj_retval
Definition: multiprecision.hpp:299
omniidl_be_python_with_docstring.run
def run(tree, args)
Definition: cmake/hpp/idl/omniidl_be_python_with_docstring.py:140
y
y
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::self_type
boost::multiprecision::number< Backend, ExpressionTemplates > self_type
Definition: multiprecision.hpp:61
boost
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::NonInteger
self_type NonInteger
Definition: multiprecision.hpp:68
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::digits10
static int digits10()
Definition: multiprecision.hpp:114
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::Real
self_type Real
Definition: multiprecision.hpp:66
pinocchio::cholesky::min
JointCollectionTpl const DataTpl< Scalar, Options, JointCollectionTpl > const Eigen::MatrixBase< Mat > & min
Definition: cholesky.hpp:89
Eigen::internal::conj_impl< boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 >, true >::run
static boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 >::result_type run(const typename boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 > &x)
Definition: multiprecision.hpp:330
pinocchio::is_floating_point
Definition: math/fwd.hpp:17
fwd.hpp
value
float value
x
x
Eigen::internal::cast_impl< boost::multiprecision::number< Backend, ExpressionTemplates >, Scalar >::run
static Scalar run(const boost::multiprecision::number< Backend, ExpressionTemplates > &x)
Definition: multiprecision.hpp:42
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::digits10_imp
static int digits10_imp(const boost::mpl::bool_< B > &)
Definition: multiprecision.hpp:110
CppAD::conj
const AD< Base > & conj(const AD< Base > &x)
Definition: autodiff/cppad.hpp:150
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::Nested
self_type Nested
Definition: multiprecision.hpp:70
Eigen::internal::conj_impl
Definition: multiprecision.hpp:305
Eigen::internal::scalar_product_traits< boost::multiprecision::number< Backend, ExpressionTemplates >, boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 > >::ReturnType
boost::multiprecision::number< Backend, ExpressionTemplates > ReturnType
Definition: multiprecision.hpp:273
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::Literal
double Literal
Definition: multiprecision.hpp:69
Eigen::internal::scalar_product_traits< boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 >, boost::multiprecision::number< Backend, ExpressionTemplates > >::ReturnType
boost::multiprecision::number< Backend, ExpressionTemplates > ReturnType
Definition: multiprecision.hpp:294
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::digits10_imp
static int digits10_imp(const boost::mpl::true_ &)
Definition: multiprecision.hpp:105
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::dummy_precision
static Real dummy_precision()
Definition: multiprecision.hpp:93
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::lowest
static Real lowest()
Definition: multiprecision.hpp:101
Eigen::NumTraits< boost::multiprecision::number< Backend, ExpressionTemplates > >::digits
constexpr static int digits()
Definition: multiprecision.hpp:123
pinocchio.utils.rand
def rand(n)
Definition: bindings/python/pinocchio/utils.py:41
Scalar
double Scalar
Definition: timings-cppad-jit.cpp:37
Eigen::internal::conj_retval< boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 > >::type
boost::multiprecision::detail::expression< tag, Arg1, Arg2, Arg3, Arg4 >::result_type type
Definition: multiprecision.hpp:313
CppAD::max
AD< Scalar > max(const AD< Scalar > &x, const AD< Scalar > &y)
Definition: autodiff/cppad.hpp:181
EIGEN_DEVICE_FUNC
#define EIGEN_DEVICE_FUNC
Definition: tensor.hpp:11
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:33


pinocchio
Author(s):
autogenerated on Thu Apr 10 2025 02:42:21