pinocchio  2.3.1-dirty
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 #include <boost/multiprecision/number.hpp>
11 #include <Eigen/Dense>
12 
13 namespace Eigen
14 {
15  namespace internal
16  {
17  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename Scalar>
18  struct cast_impl<boost::multiprecision::number<Backend, ExpressionTemplates>,Scalar>
19  {
20 #if EIGEN_VERSION_AT_LEAST(3,2,90)
21  EIGEN_DEVICE_FUNC
22 #endif
23  static inline Scalar run(const boost::multiprecision::number<Backend, ExpressionTemplates> & x)
24  {
25  return x.template convert_to<Scalar>();
26  }
27  };
28  }
29 } //namespace Eigen
30 
31 #ifndef BOOST_MP_EIGEN_HPP
32 
33 // Code adapted from <boost/multiprecision/eigen.hpp>
34 // Copyright 2018 John Maddock. Distributed under the Boost
35 // Software License, Version 1.0. (See accompanying file
36 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
37 namespace Eigen
38 {
39  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
40  struct NumTraits<boost::multiprecision::number<Backend, ExpressionTemplates> >
41  {
42  typedef boost::multiprecision::number<Backend, ExpressionTemplates> self_type;
43 #if BOOST_VERSION / 100 % 1000 >= 68
44  typedef typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type Real;
45 #else
46  typedef self_type Real;
47 #endif
48  typedef self_type NonInteger; // Not correct but we can't do much better??
49  typedef double Literal;
50  typedef self_type Nested;
51  enum
52  {
53 #if BOOST_VERSION / 100 % 1000 >= 68
54  IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
55 #else
56  IsComplex = 0,
57 #endif
58  IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
59  ReadCost = 1,
60  AddCost = 4,
61  MulCost = 8,
62  IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
63  RequireInitialization = 1
64  };
65  static Real epsilon()
66  {
67  return std::numeric_limits<Real>::epsilon();
68  }
69  static Real dummy_precision()
70  {
71  return 1000 * epsilon();
72  }
73  static Real highest()
74  {
75  return (std::numeric_limits<Real>::max)();
76  }
77  static Real lowest()
78  {
79  return (std::numeric_limits<Real>::min)();
80  }
81  static int digits10_imp(const boost::mpl::true_&)
82  {
83  return std::numeric_limits<Real>::digits10;
84  }
85  template <bool B>
86  static int digits10_imp(const boost::mpl::bool_<B>&)
87  {
88  return Real::default_precision();
89  }
90  static int digits10()
91  {
92  return digits10_imp(boost::mpl::bool_ < std::numeric_limits<Real>::digits10 && (std::numeric_limits<Real>::digits10 != INT_MAX) ? true : false > ());
93  }
94  };
95 
96  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
97  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>
98  {
99  };
100 
101  namespace internal
102  {
103 
104  template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4>
105  struct scalar_product_traits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
106  {
107 // BOOST_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.");
108  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
109  };
110 
111  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
112  struct scalar_product_traits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend, ExpressionTemplates> >
113  {
114 // BOOST_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.");
115  typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
116  };
117 
118  template <typename Scalar>
119  struct conj_retval;
120 
121  template <typename Scalar, bool IsComplex>
122  struct conj_impl;
123 
124  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
125  struct conj_retval<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
126  {
127  typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type type;
128  };
129 
130  template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
131  struct conj_impl<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, true>
132  {
133 #if EIGEN_VERSION_AT_LEAST(3,2,90)
134  EIGEN_DEVICE_FUNC
135 #endif
136  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)
137  {
138  return conj(x);
139  }
140  };
141 
142  } // namespace internal
143 
144 } // namespace Eigen
145 
146 #endif // ifndef BOOST_MP_EIGEN_HPP
147 
148 #endif // ifndef __pinocchio_math_mutliprecision_hpp__
Source from #include <cppad/example/cppad_eigen.hpp>