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)
6 #ifndef BOOST_MP_EIGEN_HPP
7 #define BOOST_MP_EIGEN_HPP
9 #include <boost/multiprecision/number.hpp>
13 // Generic Eigen support code:
16 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
17 struct NumTraits<boost::multiprecision::number<Backend, ExpressionTemplates> >
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;
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,
31 IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
32 RequireInitialization = 1,
36 return std::numeric_limits<Real>::epsilon();
38 static Real dummy_precision()
40 return 1000 * epsilon();
44 return (std::numeric_limits<Real>::max)();
48 return (std::numeric_limits<Real>::min)();
50 static int digits10_imp(const boost::mpl::true_&)
52 return std::numeric_limits<Real>::digits10;
55 static int digits10_imp(const boost::mpl::bool_<B>&)
57 return Real::default_precision();
61 return digits10_imp(boost::mpl::bool_ < std::numeric_limits<Real>::digits10 && (std::numeric_limits<Real>::digits10 != INT_MAX) ? true : false > ());
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>
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> \
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; \
76 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
77 struct ScalarBinaryOpTraits<A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
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; \
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)
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>
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;
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>
110 typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<D>, boost::multiprecision::et_on> ReturnType;
113 template<typename BinaryOp>
114 struct ScalarBinaryOpTraits<boost::multiprecision::mpfr_float, boost::multiprecision::mpc_complex, BinaryOp>
116 typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<0>, boost::multiprecision::et_on> ReturnType;
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>
122 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
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>
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;
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>
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;
141 template <typename Scalar>
144 template <typename Scalar, bool IsComplex>
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> >
150 typedef typename boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>::result_type type;
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>
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)
163 } // namespace internal