1 // Copyright 2012 John Maddock. Distributed under the Boost
2 // Software License, Version 1.0. (See accompanying file
3 // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
5 #include <boost/multiprecision/cpp_int.hpp>
6 #include <boost/multiprecision/cpp_dec_float.hpp>
7 #include <boost/multiprecision/cpp_bin_float.hpp>
11 #include <boost/multiprecision/mpfr.hpp>
12 #include <boost/multiprecision/logged_adaptor.hpp>
13 #include <boost/multiprecision/gmp.hpp>
14 #include <boost/multiprecision/mpc.hpp>
18 using namespace Eigen
;
21 template <class Backend
, boost::multiprecision::expression_template_option ExpressionTemplates
>
22 struct NumTraits
<boost::multiprecision::number
<Backend
, ExpressionTemplates
> >
24 typedef boost::multiprecision::number
<Backend
, ExpressionTemplates
> self_type
;
25 typedef typename
boost::multiprecision::scalar_result_from_possible_complex
<self_type
>::type Real
;
26 typedef self_type NonInteger
; // Not correct but we can't do much better??
27 typedef double Literal
;
28 typedef self_type Nested
;
31 IsComplex
= boost::multiprecision::number_category
<self_type
>::value
== boost::multiprecision::number_kind_complex
,
32 IsInteger
= boost::multiprecision::number_category
<self_type
>::value
== boost::multiprecision::number_kind_integer
,
36 IsSigned
= std::numeric_limits
<self_type
>::is_specialized
? std::numeric_limits
<self_type
>::is_signed
: true,
37 RequireInitialization
= 1,
41 return std::numeric_limits
<Real
>::epsilon();
43 static Real
dummy_precision()
45 return sqrt(epsilon());
49 return (std::numeric_limits
<Real
>::max
)();
53 return (std::numeric_limits
<Real
>::min
)();
55 static int digits10_imp(const std::integral_constant
<bool, true>&)
57 return std::numeric_limits
<Real
>::digits10
;
60 static int digits10_imp(const std::integral_constant
<bool, B
>&)
62 return Real::default_precision();
66 return digits10_imp(std::integral_constant
<bool, std::numeric_limits
<Real
>::digits10
&& (std::numeric_limits
<Real
>::digits10
!= INT_MAX
) ? true : false > ());
70 #define BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(A) \
71 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
72 struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, A, BinaryOp> \
74 static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported."); \
75 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
77 template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
78 struct ScalarBinaryOpTraits<A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
80 static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported."); \
81 typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
84 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(float)
85 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(double)
86 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long double)
87 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(char)
88 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned char)
89 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(signed char)
90 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(short)
91 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned short)
92 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(int)
93 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned int)
94 BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long)
95 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
std::conditional
<std::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
;
125 template <class Backend
, boost::multiprecision::expression_template_option ExpressionTemplates
, class tag
, class Arg1
, class Arg2
, class Arg3
, class Arg4
, typename BinaryOp
>
126 struct ScalarBinaryOpTraits
<boost::multiprecision::number
<Backend
, ExpressionTemplates
>, boost::multiprecision::detail::expression
<tag
, Arg1
, Arg2
, Arg3
, Arg4
>, BinaryOp
>
128 static_assert(std::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.");
129 typedef boost::multiprecision::number
<Backend
, ExpressionTemplates
> ReturnType
;
132 template <class tag
, class Arg1
, class Arg2
, class Arg3
, class Arg4
, class Backend
, boost::multiprecision::expression_template_option ExpressionTemplates
, typename BinaryOp
>
133 struct ScalarBinaryOpTraits
<boost::multiprecision::detail::expression
<tag
, Arg1
, Arg2
, Arg3
, Arg4
>, boost::multiprecision::number
<Backend
, ExpressionTemplates
>, BinaryOp
>
135 static_assert(std::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.");
136 typedef boost::multiprecision::number
<Backend
, ExpressionTemplates
> ReturnType
;
142 struct related_number
148 struct related_number<boost::multiprecision::cpp_bin_float_50>
150 typedef boost::multiprecision::cpp_bin_float_quad type;
153 struct related_number<boost::multiprecision::cpp_dec_float_100>
155 typedef boost::multiprecision::cpp_dec_float_50 type;
161 // expected results first:
162 Matrix
<Num
, 2, 2> r1
, r2
;
165 Matrix
<Num
, 3, 1> r3
;
170 Matrix
<Num
, Dynamic
, Dynamic
> b(2, 2);
172 std::cout
<< "a + b =\n"
173 << a
+ b
<< std::endl
;
174 BOOST_CHECK_EQUAL(a
+ b
, r1
);
175 std::cout
<< "a - b =\n"
176 << a
- b
<< std::endl
;
177 BOOST_CHECK_EQUAL(a
- b
, r2
);
178 std::cout
<< "Doing a += b;" << std::endl
;
180 std::cout
<< "Now a =\n"
182 Matrix
<Num
, 3, 1> v(1, 2, 3);
183 Matrix
<Num
, 3, 1> w(1, 0, 0);
184 std::cout
<< "-v + w - v =\n"
185 << -v
+ w
- v
<< std::endl
;
186 BOOST_CHECK_EQUAL(-v
+ w
- v
, r3
);
194 Matrix
<Num
, 3, 1> v(1, 2, 3);
195 std::cout
<< "a * 2.5 =\n"
196 << a
* 2.5 << std::endl
;
197 std::cout
<< "0.1 * v =\n"
198 << 0.1 * v
<< std::endl
;
199 std::cout
<< "Doing v *= 2;" << std::endl
;
201 std::cout
<< "Now v =\n"
204 std::cout
<< "Doing v *= Num;" << std::endl
;
206 std::cout
<< "Now v =\n"
208 typedef typename related_number
<Num
>::type related_type
;
210 std::cout
<< "Doing v *= RelatedType;" << std::endl
;
212 std::cout
<< "Now v =\n"
214 std::cout
<< "RelatedType * v =\n"
215 << r
* v
<< std::endl
;
216 std::cout
<< "Doing v *= RelatedType^2;" << std::endl
;
218 std::cout
<< "Now v =\n"
220 std::cout
<< "RelatedType^2 * v =\n"
221 << r
* r
* v
<< std::endl
;
223 static_assert(std::is_same
<typename
Eigen::ScalarBinaryOpTraits
<Num
, related_type
, Eigen::internal::scalar_product_op
<Num
, related_type
> >::ReturnType
, Num
>::value
, "Incorrect type.");
230 Matrix
<Num
, Dynamic
, Dynamic
> a
= Matrix
<Num
, Dynamic
, Dynamic
>::Random(2, 2);
231 cout
<< "Here is the matrix a\n"
233 cout
<< "Here is the matrix a^T\n"
234 << a
.transpose() << endl
;
235 cout
<< "Here is the conjugate of a\n"
236 << a
.conjugate() << endl
;
237 cout
<< "Here is the matrix a^*\n"
238 << a
.adjoint() << endl
;
244 Matrix
<Num
, 2, 2> mat
;
247 Matrix
<Num
, 2, 1> u(-1, 1), v(2, 0);
248 std::cout
<< "Here is mat*mat:\n"
249 << mat
* mat
<< std::endl
;
250 std::cout
<< "Here is mat*u:\n"
251 << mat
* u
<< std::endl
;
252 std::cout
<< "Here is u^T*mat:\n"
253 << u
.transpose() * mat
<< std::endl
;
254 std::cout
<< "Here is u^T*v:\n"
255 << u
.transpose() * v
<< std::endl
;
256 std::cout
<< "Here is u*v^T:\n"
257 << u
* v
.transpose() << std::endl
;
258 std::cout
<< "Let's multiply mat by itself" << std::endl
;
260 std::cout
<< "Now mat is mat:\n"
268 Matrix
<Num
, 3, 1> v(1, 2, 3);
269 Matrix
<Num
, 3, 1> w(0, 1, 2);
270 cout
<< "Dot product: " << v
.dot(w
) << endl
;
271 Num dp
= v
.adjoint() * w
; // automatic conversion of the inner product to a scalar
272 cout
<< "Dot product via a matrix product: " << dp
<< endl
;
273 cout
<< "Cross product:\n"
274 << v
.cross(w
) << endl
;
281 Matrix
<Num
, 2, 2> mat
;
284 cout
<< "Here is mat.sum(): " << mat
.sum() << endl
;
285 cout
<< "Here is mat.prod(): " << mat
.prod() << endl
;
286 cout
<< "Here is mat.mean(): " << mat
.mean() << endl
;
287 cout
<< "Here is mat.minCoeff(): " << mat
.minCoeff() << endl
;
288 cout
<< "Here is mat.maxCoeff(): " << mat
.maxCoeff() << endl
;
289 cout
<< "Here is mat.trace(): " << mat
.trace() << endl
;
297 Array
<Num
, Dynamic
, Dynamic
> m(2, 2);
299 // assign some values coefficient by coefficient
303 m(1, 1) = m(0, 1) + m(1, 0);
305 // print values to standard output
309 // using the comma-initializer is also allowed
313 // print values to standard output
321 Array
<Num
, Dynamic
, Dynamic
> a(3, 3);
322 Array
<Num
, Dynamic
, Dynamic
> b(3, 3);
331 cout
<< "a + b = " << endl
334 // Subtracting a scalar from an array
335 cout
<< "a - 2 = " << endl
343 Array
<Num
, Dynamic
, Dynamic
> a(2, 2);
344 Array
<Num
, Dynamic
, Dynamic
> b(2, 2);
349 cout
<< "a * b = " << endl
357 Array
<Num
, Dynamic
, 1> a
= Array
<Num
, Dynamic
, 1>::Random(5);
359 cout
<< "a =" << endl
361 cout
<< "a.abs() =" << endl
363 cout
<< "a.abs().sqrt() =" << endl
364 << a
.abs().sqrt() << endl
;
365 cout
<< "a.min(a.abs().sqrt()) =" << endl
366 << a
.std::min
)(a
.abs().sqrt()) << endl
;
373 Matrix
<Num
, Dynamic
, Dynamic
> m(2, 2);
374 Matrix
<Num
, Dynamic
, Dynamic
> n(2, 2);
375 Matrix
<Num
, Dynamic
, Dynamic
> result(2, 2);
381 cout
<< "-- Matrix m*n: --" << endl
384 result
= m
.array() * n
.array();
385 cout
<< "-- Array m*n: --" << endl
388 result
= m
.cwiseProduct(n
);
389 cout
<< "-- With cwiseProduct: --" << endl
392 result
= m
.array() + 4;
393 cout
<< "-- Array m + 4: --" << endl
402 Matrix
<Num
, Dynamic
, Dynamic
> m(2, 2);
403 Matrix
<Num
, Dynamic
, Dynamic
> n(2, 2);
404 Matrix
<Num
, Dynamic
, Dynamic
> result(2, 2);
410 result
= (m
.array() + 4).matrix() * m
;
411 cout
<< "-- Combination 1: --" << endl
414 result
= (m
.array() * n
.array()).matrix() * m
;
415 cout
<< "-- Combination 2: --" << endl
424 Matrix
<Num
, Dynamic
, Dynamic
> m(4, 4);
429 cout
<< "Block in the middle" << endl
;
430 cout
<< m
.template block
<2, 2>(1, 1) << endl
432 for (int i
= 1; i
<= 3; ++i
)
434 cout
<< "Block of size " << i
<< "x" << i
<< endl
;
435 cout
<< m
.block(0, 0, i
, i
) << endl
447 Array
<Num
, 4, 4> a
= Array
<Num
, 4, 4>::Constant(0.6);
448 cout
<< "Here is the array a:" << endl
451 a
.template block
<2, 2>(1, 1) = m
;
452 cout
<< "Here is now a with m copied into its central 2x2 block:" << endl
455 a
.block(0, 0, 2, 3) = a
.block(2, 1, 2, 3);
456 cout
<< "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl
465 Eigen::Matrix
<Num
, Dynamic
, Dynamic
> m(3, 3);
469 cout
<< "Here is the matrix m:" << endl
471 cout
<< "2nd Row: " << m
.row(1) << endl
;
472 m
.col(2) += 3 * m
.col(0);
473 cout
<< "After adding 3 times the first column into the third column, the matrix m is:\n";
486 cout
<< "m.leftCols(2) =" << endl
487 << m
.leftCols(2) << endl
489 cout
<< "m.bottomRows<2>() =" << endl
490 << m
.template bottomRows
<2>() << endl
492 m
.topLeftCorner(1, 3) = m
.bottomRightCorner(3, 1).transpose();
493 cout
<< "After assignment, m = " << endl
501 Array
<Num
, Dynamic
, 1> v(6);
502 v
<< 1, 2, 3, 4, 5, 6;
503 cout
<< "v.head(3) =" << endl
506 cout
<< "v.tail<3>() = " << endl
507 << v
.template tail
<3>() << endl
509 v
.segment(1, 4) *= 2;
510 cout
<< "after 'v.segment(1,4) *= 2', v =" << endl
518 Matrix
<Num
, 2, 2> mat
;
521 cout
<< "Here is mat.sum(): " << mat
.sum() << endl
;
522 cout
<< "Here is mat.prod(): " << mat
.prod() << endl
;
523 cout
<< "Here is mat.mean(): " << mat
.mean() << endl
;
524 cout
<< "Here is mat.minCoeff(): " << mat
.minCoeff() << endl
;
525 cout
<< "Here is mat.maxCoeff(): " << mat
.maxCoeff() << endl
;
526 cout
<< "Here is mat.trace(): " << mat
.trace() << endl
;
528 BOOST_CHECK_EQUAL(mat
.sum(), 10);
529 BOOST_CHECK_EQUAL(mat
.prod(), 24);
530 BOOST_CHECK_EQUAL(mat
.mean(), Num(5) / 2);
531 BOOST_CHECK_EQUAL(mat
.minCoeff(), 1);
532 BOOST_CHECK_EQUAL(mat
.maxCoeff(), 4);
533 BOOST_CHECK_EQUAL(mat
.trace(), 5);
540 Matrix
<Num
, 2, 2> mat
;
543 cout
<< "Here is mat.sum(): " << mat
.sum() << endl
;
544 cout
<< "Here is mat.prod(): " << mat
.prod() << endl
;
545 cout
<< "Here is mat.mean(): " << mat
.mean() << endl
;
546 //cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
547 //cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
548 cout
<< "Here is mat.trace(): " << mat
.trace() << endl
;
555 Matrix
<Num
, Dynamic
, 1> v(2);
556 Matrix
<Num
, Dynamic
, Dynamic
> m(2, 2), n(2, 2);
563 cout
<< "v.squaredNorm() = " << v
.squaredNorm() << endl
;
564 cout
<< "v.norm() = " << v
.norm() << endl
;
565 cout
<< "v.lpNorm<1>() = " << v
.template lpNorm
<1>() << endl
;
566 cout
<< "v.lpNorm<Infinity>() = " << v
.template lpNorm
<Infinity
>() << endl
;
568 cout
<< "m.squaredNorm() = " << m
.squaredNorm() << endl
;
569 cout
<< "m.norm() = " << m
.norm() << endl
;
570 cout
<< "m.lpNorm<1>() = " << m
.template lpNorm
<1>() << endl
;
571 cout
<< "m.lpNorm<Infinity>() = " << m
.template lpNorm
<Infinity
>() << endl
;
580 A
<< 1, 2, 3, 4, 5, 6, 7, 8, 10;
582 cout
<< "Here is the matrix A:\n"
584 cout
<< "Here is the vector b:\n"
586 Matrix
<Num
, 3, 1> x
= A
.colPivHouseholderQr().solve(b
);
587 cout
<< "The solution is:\n"
595 Matrix
<Num
, 2, 2> A
, b
;
598 cout
<< "Here is the matrix A:\n"
600 cout
<< "Here is the right hand side b:\n"
602 Matrix
<Num
, 2, 2> x
= A
.ldlt().solve(b
);
603 cout
<< "The solution is:\n"
611 Matrix
<Num
, Dynamic
, Dynamic
> A
= Matrix
<Num
, Dynamic
, Dynamic
>::Random(100, 100);
612 Matrix
<Num
, Dynamic
, Dynamic
> b
= Matrix
<Num
, Dynamic
, Dynamic
>::Random(100, 50);
613 Matrix
<Num
, Dynamic
, Dynamic
> x
= A
.fullPivLu().solve(b
);
614 Matrix
<Num
, Dynamic
, Dynamic
> axmb
= A
* x
- b
;
615 double relative_error
= static_cast<double>(abs(axmb
.norm() / b
.norm())); // norm() is L2 norm
616 cout
<< "norm1 = " << axmb
.norm() << endl
;
617 cout
<< "norm2 = " << b
.norm() << endl
;
618 cout
<< "The relative error is:\n"
619 << relative_error
<< endl
;
628 cout
<< "Here is the matrix A:\n"
630 SelfAdjointEigenSolver
<Matrix
<Num
, 2, 2> > eigensolver(A
);
631 if (eigensolver
.info() != Success
)
633 std::cout
<< "Eigenvalue solver failed!" << endl
;
637 cout
<< "The eigenvalues of A are:\n"
638 << eigensolver
.eigenvalues() << endl
;
639 cout
<< "Here's a matrix whose columns are eigenvectors of A \n"
640 << "corresponding to these eigenvalues:\n"
641 << eigensolver
.eigenvectors() << endl
;
653 cout
<< "Here is the matrix A:\n"
655 cout
<< "The determinant of A is " << A
.determinant() << endl
;
656 cout
<< "The inverse of A is:\n"
657 << A
.inverse() << endl
;
661 void test_integer_type()
669 void test_float_type()
671 std::cout
<< "Epsilon = " << Eigen::NumTraits
<Num
>::epsilon() << std::endl
;
672 std::cout
<< "Dummy Prec = " << Eigen::NumTraits
<Num
>::dummy_precision() << std::endl
;
673 std::cout
<< "Highest = " << Eigen::NumTraits
<Num
>::highest() << std::endl
;
674 std::cout
<< "Lowest = " << Eigen::NumTraits
<Num
>::lowest() << std::endl
;
675 std::cout
<< "Digits10 = " << Eigen::NumTraits
<Num
>::digits10() << std::endl
;
703 void test_complex_type()
705 std::cout
<< "Epsilon = " << Eigen::NumTraits
<Num
>::epsilon() << std::endl
;
706 std::cout
<< "Dummy Prec = " << Eigen::NumTraits
<Num
>::dummy_precision() << std::endl
;
707 std::cout
<< "Highest = " << Eigen::NumTraits
<Num
>::highest() << std::endl
;
708 std::cout
<< "Lowest = " << Eigen::NumTraits
<Num
>::lowest() << std::endl
;
709 std::cout
<< "Digits10 = " << Eigen::NumTraits
<Num
>::digits10() << std::endl
;
731 // example23<Num>(); //requires comparisons.
736 namespace multiprecision
{
738 template <unsigned D
>
739 inline void log_postfix_event(const mpc_complex_backend
<D
>& val
, const char* event_description
)
741 if (mpfr_nan_p(mpc_realref(val
.data())))
743 std::cout
<< "Found a NaN! " << event_description
<< std::endl
;
748 } // namespace boost::multiprecision
752 using namespace boost::multiprecision
;
753 test_complex_type
<mpc_complex
>();
755 test_integer_type
<int>();
757 test_float_type
<double>();
758 test_complex_type
<std::complex<double> >();
760 test_float_type
<boost::multiprecision::cpp_dec_float_100
>();
761 test_float_type
<boost::multiprecision::cpp_bin_float_50
>();
762 test_float_type
<boost::multiprecision::mpfr_float
>();
764 test_integer_type
<boost::multiprecision::int256_t
>();
765 test_integer_type
<boost::multiprecision::cpp_int
>();
766 test_integer_type
<boost::multiprecision::cpp_rational
>();
767 test_integer_type
<boost::multiprecision::mpz_int
>();
768 test_integer_type
<boost::multiprecision::mpq_rational
>();