]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/multiprecision/eigen.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / multiprecision / eigen.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright 2018 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef BOOST_MP_EIGEN_HPP
7 #define BOOST_MP_EIGEN_HPP
8
9 #include <boost/multiprecision/number.hpp>
10 #include <Eigen/Core>
11
12 //
13 // Generic Eigen support code:
14 //
15 namespace Eigen {
16 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
17 struct NumTraits<boost::multiprecision::number<Backend, ExpressionTemplates> >
18 {
19 typedef boost::multiprecision::number<Backend, ExpressionTemplates> self_type;
20 typedef typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type Real;
21 typedef self_type NonInteger; // Not correct but we can't do much better??
22 typedef double Literal;
23 typedef self_type Nested;
24 enum
25 {
26 IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
27 IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
28 ReadCost = 1,
29 AddCost = 4,
30 MulCost = 8,
31 IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
32 RequireInitialization = 1,
33 };
34 static Real epsilon()
35 {
36 return std::numeric_limits<Real>::epsilon();
37 }
38 static Real dummy_precision()
39 {
40 return 1000 * epsilon();
41 }
42 static Real highest()
43 {
44 return (std::numeric_limits<Real>::max)();
45 }
46 static Real lowest()
47 {
48 return (std::numeric_limits<Real>::min)();
49 }
50 static int digits10_imp(const boost::mpl::true_&)
51 {
52 return std::numeric_limits<Real>::digits10;
53 }
54 template <bool B>
55 static int digits10_imp(const boost::mpl::bool_<B>&)
56 {
57 return Real::default_precision();
58 }
59 static int digits10()
60 {
61 return digits10_imp(boost::mpl::bool_ < std::numeric_limits<Real>::digits10 && (std::numeric_limits<Real>::digits10 != INT_MAX) ? true : false > ());
62 }
63 };
64 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
65 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>
66 {
67 };
68
69 #define BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(A) \
70 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
71 struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, A, BinaryOp> \
72 { \
73 /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");*/ \
74 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
75 }; \
76 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
77 struct ScalarBinaryOpTraits<A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
78 { \
79 /*static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported.");*/ \
80 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
81 };
82
83 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(float)
84 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(double)
85 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long double)
86 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(char)
87 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned char)
88 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(signed char)
89 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(short)
90 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned short)
91 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(int)
92 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned int)
93 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long)
94 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned long)
95
96 #if 0
97 template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Backend2, boost::multiprecision::expression_template_option ExpressionTemplates2, typename BinaryOp>
98 struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend2, ExpressionTemplates2>, BinaryOp>
99 {
100 static_assert(
101 boost::multiprecision::is_compatible_arithmetic_type<boost::multiprecision::number<Backend2, ExpressionTemplates2>, boost::multiprecision::number<Backend, ExpressionTemplates> >::value
102 || boost::multiprecision::is_compatible_arithmetic_type<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend2, ExpressionTemplates2> >::value, "Interoperability with this arithmetic type is not supported.");
103 typedef typename boost::mpl::if_c<boost::is_convertible<boost::multiprecision::number<Backend2, ExpressionTemplates2>, boost::multiprecision::number<Backend, ExpressionTemplates> >::value,
104 boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend2, ExpressionTemplates2> >::type ReturnType;
105 };
106
107 template<unsigned D, typename BinaryOp>
108 struct ScalarBinaryOpTraits<boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<D>, boost::multiprecision::et_on>, boost::multiprecision::mpfr_float, BinaryOp>
109 {
110 typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<D>, boost::multiprecision::et_on> ReturnType;
111 };
112
113 template<typename BinaryOp>
114 struct ScalarBinaryOpTraits<boost::multiprecision::mpfr_float, boost::multiprecision::mpc_complex, BinaryOp>
115 {
116 typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<0>, boost::multiprecision::et_on> ReturnType;
117 };
118
119 template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp>
120 struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp>
121 {
122 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
123 };
124 #endif
125
126 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4, typename BinaryOp>
127 struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, BinaryOp>
128 {
129 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.");
130 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
131 };
132
133 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp>
134 struct ScalarBinaryOpTraits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp>
135 {
136 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.");
137 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
138 };
139
140 namespace internal {
141 template <typename Scalar>
142 struct conj_retval;
143
144 template <typename Scalar, bool IsComplex>
145 struct conj_impl;
146
147 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
148 struct conj_retval<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4> >
149 {
150 typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type type;
151 };
152
153 template <class tag, class Arg1, class Arg2, class Arg3, class Arg4>
154 struct conj_impl<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, true>
155 {
156 EIGEN_DEVICE_FUNC
157 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)
158 {
159 return conj(x);
160 }
161 };
162
163 } // namespace internal
164
165 } // namespace Eigen
166
167 #endif