pinocchio  2.7.1
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
multiprecision.hpp
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 #ifndef PINOCCHIO_WITH_CXX11_SUPPORT
11  #error C++11 compiler required.
12 #endif
13 
14 #include <boost/multiprecision/number.hpp>
15 #include <Eigen/Dense>
16 
17 namespace pinocchio
18 {
19 // We check std::numeric_limits<_>::has_infinity to exclude integral, rational
20 // and complex types
21 template <typename Backend,
22  boost::multiprecision::expression_template_option ET>
23 struct is_floating_point<boost::multiprecision::number<Backend, ET>>
24  : boost::integral_constant<
25  bool,
26  ((std::numeric_limits<
27  boost::multiprecision::number<Backend, ET>>::is_specialized and
28  std::numeric_limits<
29  boost::multiprecision::number<Backend, ET>>::has_infinity))>
30 {
31 };
32 } // namespace pinocchio
33 
34 namespace Eigen
35 {
36  namespace internal
37  {
38  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename Scalar>
39  struct cast_impl<boost::multiprecision::number<Backend, ExpressionTemplates>,Scalar>
40  {
41 #if EIGEN_VERSION_AT_LEAST(3,2,90)
42  EIGEN_DEVICE_FUNC
43 #endif
44  static inline Scalar run(const boost::multiprecision::number<Backend, ExpressionTemplates> & x)
45  {
46  return x.template convert_to<Scalar>();
47  }
48  };
49  }
50 } //namespace Eigen
51 
52 #ifndef BOOST_MP_EIGEN_HPP
53 
54 // Code adapted from <boost/multiprecision/eigen.hpp>
55 // Copyright 2018 John Maddock. Distributed under the Boost
56 // Software License, Version 1.0. (See accompanying file
57 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
58 namespace Eigen
59 {
60  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
61  struct NumTraits<boost::multiprecision::number<Backend, ExpressionTemplates> >
62  {
63  typedef boost::multiprecision::number<Backend, ExpressionTemplates> self_type;
64 #if BOOST_VERSION / 100 % 1000 >= 68
65  typedef typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type Real;
66 #else
67  typedef self_type Real;
68 #endif
69  typedef self_type NonInteger; // Not correct but we can't do much better??
70  typedef double Literal;
71  typedef self_type Nested;
72  enum
73  {
74 #if BOOST_VERSION / 100 % 1000 >= 68
75  IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
76 #else
77  IsComplex = 0,
78 #endif
79  IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
80  ReadCost = 1,
81  AddCost = 4,
82  MulCost = 8,
83  IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
84  RequireInitialization = 1
85  };
86  static Real epsilon()
87  {
88  return std::numeric_limits<Real>::epsilon();
89  }
90  static Real dummy_precision()
91  {
92  return 1000 * epsilon();
93  }
94  static Real highest()
95  {
96  return (std::numeric_limits<Real>::max)();
97  }
98  static Real lowest()
99  {
100  return (std::numeric_limits<Real>::min)();
101  }
102  static int digits10_imp(const boost::mpl::true_&)
103  {
104  return std::numeric_limits<Real>::digits10;
105  }
106  template <bool B>
107  static int digits10_imp(const boost::mpl::bool_<B>&)
108  {
109  return Real::default_precision();
110  }
111  static int digits10()
112  {
113  return digits10_imp(boost::mpl::bool_ < std::numeric_limits<Real>::digits10 && (std::numeric_limits<Real>::digits10 != INT_MAX) ? true : false > ());
114  }
115  };
116 
117  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
118  struct NumTraits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> > : public NumTraits<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type>
119  {
120  };
121 
122 #if EIGEN_VERSION_AT_LEAST(3,2,93)
123 #define BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(A) \
124  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
125  struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, A, BinaryOp> \
126  { \
127  /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");*/ \
128  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
129  }; \
130  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
131  struct ScalarBinaryOpTraits<A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
132  { \
133  /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");*/ \
134  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
135  };
136 
137  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(float)
138  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(double)
139  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long double)
140  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(char)
141  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned char)
142  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(signed char)
143  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(short)
144  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned short)
145  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(int)
146  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned int)
147  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long)
148  BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned long)
149 
150  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4, typename BinaryOp>
151  struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, BinaryOp>
152  {
153  static_assert(boost::is_convertible<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");
154  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
155  };
156 
157  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp>
158  struct ScalarBinaryOpTraits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp>
159  {
160  static_assert(boost::is_convertible<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");
161  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
162  };
163 #endif
164 
165  namespace internal
166  {
167 
168  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
169  struct scalar_product_traits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
170  {
171  static_assert(boost::is_convertible<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");
172  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
173  };
174 
175  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
176  struct scalar_product_traits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend, ExpressionTemplates> >
177  {
178  static_assert(boost::is_convertible<typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");
179  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
180  };
181 
182  template <typename Scalar>
183  struct conj_retval;
184 
185  template <typename Scalar, bool IsComplex>
186  struct conj_impl;
187 
188  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
189  struct conj_retval<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
190  {
191  typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type type;
192  };
193 
194  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
195  struct conj_impl<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, true>
196  {
197 #if EIGEN_VERSION_AT_LEAST(3,2,90)
198  EIGEN_DEVICE_FUNC
199 #endif
200  static inline typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type run(const typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>& x)
201  {
202  return conj(x);
203  }
204  };
205 
206  } // namespace internal
207 
208 } // namespace Eigen
209 
210 #endif // ifndef BOOST_MP_EIGEN_HPP
211 
212 #endif // ifndef __pinocchio_math_mutliprecision_hpp__
pinocchio::is_floating_point
Definition: fwd.hpp:17
pinocchio
Main pinocchio namespace.
Definition: treeview.dox:11