test_eigen_interop.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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
  4. #include <boost/multiprecision/cpp_int.hpp>
  5. #include <boost/multiprecision/cpp_dec_float.hpp>
  6. #include <boost/multiprecision/cpp_bin_float.hpp>
  7. #include <iostream>
  8. #include <Eigen/Dense>
  9. #include <boost/multiprecision/mpfr.hpp>
  10. #include <boost/multiprecision/logged_adaptor.hpp>
  11. #include <boost/multiprecision/gmp.hpp>
  12. #include <boost/multiprecision/mpc.hpp>
  13. #include "test.hpp"
  14. using namespace Eigen;
  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 sqrt(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. #define BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(A) \
  65. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
  66. struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, A, BinaryOp> \
  67. { \
  68. static_assert(boost::multiprecision::is_compatible_arithmetic_type<A, boost::multiprecision::number<Backend, ExpressionTemplates> >::value, "Interoperability with this arithmetic type is not supported."); \
  69. typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType; \
  70. }; \
  71. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp> \
  72. struct ScalarBinaryOpTraits<A, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp> \
  73. { \
  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; \
  76. };
  77. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(float)
  78. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(double)
  79. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long double)
  80. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(char)
  81. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned char)
  82. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(signed char)
  83. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(short)
  84. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned short)
  85. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(int)
  86. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned int)
  87. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(long)
  88. BOOST_MP_EIGEN_SCALAR_TRAITS_DECL(unsigned long)
  89. #if 0
  90. template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class Backend2, boost::multiprecision::expression_template_option ExpressionTemplates2, typename BinaryOp>
  91. struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend2, ExpressionTemplates2>, BinaryOp>
  92. {
  93. static_assert(
  94. boost::multiprecision::is_compatible_arithmetic_type<boost::multiprecision::number<Backend2, ExpressionTemplates2>, boost::multiprecision::number<Backend, ExpressionTemplates> >::value
  95. || 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.");
  96. typedef typename boost::mpl::if_c<boost::is_convertible<boost::multiprecision::number<Backend2, ExpressionTemplates2>, boost::multiprecision::number<Backend, ExpressionTemplates> >::value,
  97. boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend2, ExpressionTemplates2> >::type ReturnType;
  98. };
  99. template<unsigned D, typename BinaryOp>
  100. struct ScalarBinaryOpTraits<boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<D>, boost::multiprecision::et_on>, boost::multiprecision::mpfr_float, BinaryOp>
  101. {
  102. typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<D>, boost::multiprecision::et_on> ReturnType;
  103. };
  104. template<typename BinaryOp>
  105. struct ScalarBinaryOpTraits<boost::multiprecision::mpfr_float, boost::multiprecision::mpc_complex, BinaryOp>
  106. {
  107. typedef boost::multiprecision::number<boost::multiprecision::backends::mpc_complex_backend<0>, boost::multiprecision::et_on> ReturnType;
  108. };
  109. template<class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp>
  110. struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp>
  111. {
  112. typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
  113. };
  114. #endif
  115. template <class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, class tag, class Arg1, class Arg2, class Arg3, class Arg4, typename BinaryOp>
  116. struct ScalarBinaryOpTraits<boost::multiprecision::number<Backend, ExpressionTemplates>, boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, BinaryOp>
  117. {
  118. 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.");
  119. typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
  120. };
  121. template <class tag, class Arg1, class Arg2, class Arg3, class Arg4, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates, typename BinaryOp>
  122. struct ScalarBinaryOpTraits<boost::multiprecision::detail::expression<tag, Arg1, Arg2, Arg3, Arg4>, boost::multiprecision::number<Backend, ExpressionTemplates>, BinaryOp>
  123. {
  124. 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.");
  125. typedef boost::multiprecision::number<Backend, ExpressionTemplates> ReturnType;
  126. };
  127. } // namespace Eigen
  128. template <class T>
  129. struct related_number
  130. {
  131. typedef T type;
  132. };
  133. /*
  134. template <>
  135. struct related_number<boost::multiprecision::cpp_bin_float_50>
  136. {
  137. typedef boost::multiprecision::cpp_bin_float_quad type;
  138. };
  139. template <>
  140. struct related_number<boost::multiprecision::cpp_dec_float_100>
  141. {
  142. typedef boost::multiprecision::cpp_dec_float_50 type;
  143. };*/
  144. template <class Num>
  145. void example1()
  146. {
  147. // expected results first:
  148. Matrix<Num, 2, 2> r1, r2;
  149. r1 << 3, 5, 4, 8;
  150. r2 << -1, -1, 2, 0;
  151. Matrix<Num, 3, 1> r3;
  152. r3 << -1, -4, -6;
  153. Matrix<Num, 2, 2> a;
  154. a << 1, 2, 3, 4;
  155. Matrix<Num, Dynamic, Dynamic> b(2, 2);
  156. b << 2, 3, 1, 4;
  157. std::cout << "a + b =\n"
  158. << a + b << std::endl;
  159. BOOST_CHECK_EQUAL(a + b, r1);
  160. std::cout << "a - b =\n"
  161. << a - b << std::endl;
  162. BOOST_CHECK_EQUAL(a - b, r2);
  163. std::cout << "Doing a += b;" << std::endl;
  164. a += b;
  165. std::cout << "Now a =\n"
  166. << a << std::endl;
  167. Matrix<Num, 3, 1> v(1, 2, 3);
  168. Matrix<Num, 3, 1> w(1, 0, 0);
  169. std::cout << "-v + w - v =\n"
  170. << -v + w - v << std::endl;
  171. BOOST_CHECK_EQUAL(-v + w - v, r3);
  172. }
  173. template <class Num>
  174. void example2()
  175. {
  176. Matrix<Num, 2, 2> a;
  177. a << 1, 2, 3, 4;
  178. Matrix<Num, 3, 1> v(1, 2, 3);
  179. std::cout << "a * 2.5 =\n"
  180. << a * 2.5 << std::endl;
  181. std::cout << "0.1 * v =\n"
  182. << 0.1 * v << std::endl;
  183. std::cout << "Doing v *= 2;" << std::endl;
  184. v *= 2;
  185. std::cout << "Now v =\n"
  186. << v << std::endl;
  187. Num n(4);
  188. std::cout << "Doing v *= Num;" << std::endl;
  189. v *= n;
  190. std::cout << "Now v =\n"
  191. << v << std::endl;
  192. typedef typename related_number<Num>::type related_type;
  193. related_type r(6);
  194. std::cout << "Doing v *= RelatedType;" << std::endl;
  195. v *= r;
  196. std::cout << "Now v =\n"
  197. << v << std::endl;
  198. std::cout << "RelatedType * v =\n"
  199. << r * v << std::endl;
  200. std::cout << "Doing v *= RelatedType^2;" << std::endl;
  201. v *= r * r;
  202. std::cout << "Now v =\n"
  203. << v << std::endl;
  204. std::cout << "RelatedType^2 * v =\n"
  205. << r * r * v << std::endl;
  206. static_assert(boost::is_same<typename Eigen::ScalarBinaryOpTraits<Num, related_type, Eigen::internal::scalar_product_op<Num, related_type> >::ReturnType, Num>::value, "Incorrect type.");
  207. }
  208. template <class Num>
  209. void example3()
  210. {
  211. using namespace std;
  212. Matrix<Num, Dynamic, Dynamic> a = Matrix<Num, Dynamic, Dynamic>::Random(2, 2);
  213. cout << "Here is the matrix a\n"
  214. << a << endl;
  215. cout << "Here is the matrix a^T\n"
  216. << a.transpose() << endl;
  217. cout << "Here is the conjugate of a\n"
  218. << a.conjugate() << endl;
  219. cout << "Here is the matrix a^*\n"
  220. << a.adjoint() << endl;
  221. }
  222. template <class Num>
  223. void example4()
  224. {
  225. Matrix<Num, 2, 2> mat;
  226. mat << 1, 2,
  227. 3, 4;
  228. Matrix<Num, 2, 1> u(-1, 1), v(2, 0);
  229. std::cout << "Here is mat*mat:\n"
  230. << mat * mat << std::endl;
  231. std::cout << "Here is mat*u:\n"
  232. << mat * u << std::endl;
  233. std::cout << "Here is u^T*mat:\n"
  234. << u.transpose() * mat << std::endl;
  235. std::cout << "Here is u^T*v:\n"
  236. << u.transpose() * v << std::endl;
  237. std::cout << "Here is u*v^T:\n"
  238. << u * v.transpose() << std::endl;
  239. std::cout << "Let's multiply mat by itself" << std::endl;
  240. mat = mat * mat;
  241. std::cout << "Now mat is mat:\n"
  242. << mat << std::endl;
  243. }
  244. template <class Num>
  245. void example5()
  246. {
  247. using namespace std;
  248. Matrix<Num, 3, 1> v(1, 2, 3);
  249. Matrix<Num, 3, 1> w(0, 1, 2);
  250. cout << "Dot product: " << v.dot(w) << endl;
  251. Num dp = v.adjoint() * w; // automatic conversion of the inner product to a scalar
  252. cout << "Dot product via a matrix product: " << dp << endl;
  253. cout << "Cross product:\n"
  254. << v.cross(w) << endl;
  255. }
  256. template <class Num>
  257. void example6()
  258. {
  259. using namespace std;
  260. Matrix<Num, 2, 2> mat;
  261. mat << 1, 2,
  262. 3, 4;
  263. cout << "Here is mat.sum(): " << mat.sum() << endl;
  264. cout << "Here is mat.prod(): " << mat.prod() << endl;
  265. cout << "Here is mat.mean(): " << mat.mean() << endl;
  266. cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  267. cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  268. cout << "Here is mat.trace(): " << mat.trace() << endl;
  269. }
  270. template <class Num>
  271. void example7()
  272. {
  273. using namespace std;
  274. Array<Num, Dynamic, Dynamic> m(2, 2);
  275. // assign some values coefficient by coefficient
  276. m(0, 0) = 1.0;
  277. m(0, 1) = 2.0;
  278. m(1, 0) = 3.0;
  279. m(1, 1) = m(0, 1) + m(1, 0);
  280. // print values to standard output
  281. cout << m << endl
  282. << endl;
  283. // using the comma-initializer is also allowed
  284. m << 1.0, 2.0,
  285. 3.0, 4.0;
  286. // print values to standard output
  287. cout << m << endl;
  288. }
  289. template <class Num>
  290. void example8()
  291. {
  292. using namespace std;
  293. Array<Num, Dynamic, Dynamic> a(3, 3);
  294. Array<Num, Dynamic, Dynamic> b(3, 3);
  295. a << 1, 2, 3,
  296. 4, 5, 6,
  297. 7, 8, 9;
  298. b << 1, 2, 3,
  299. 1, 2, 3,
  300. 1, 2, 3;
  301. // Adding two arrays
  302. cout << "a + b = " << endl
  303. << a + b << endl
  304. << endl;
  305. // Subtracting a scalar from an array
  306. cout << "a - 2 = " << endl
  307. << a - 2 << endl;
  308. }
  309. template <class Num>
  310. void example9()
  311. {
  312. using namespace std;
  313. Array<Num, Dynamic, Dynamic> a(2, 2);
  314. Array<Num, Dynamic, Dynamic> b(2, 2);
  315. a << 1, 2,
  316. 3, 4;
  317. b << 5, 6,
  318. 7, 8;
  319. cout << "a * b = " << endl
  320. << a * b << endl;
  321. }
  322. template <class Num>
  323. void example10()
  324. {
  325. using namespace std;
  326. Array<Num, Dynamic, 1> a = Array<Num, Dynamic, 1>::Random(5);
  327. a *= 2;
  328. cout << "a =" << endl
  329. << a << endl;
  330. cout << "a.abs() =" << endl
  331. << a.abs() << endl;
  332. cout << "a.abs().sqrt() =" << endl
  333. << a.abs().sqrt() << endl;
  334. cout << "a.min(a.abs().sqrt()) =" << endl
  335. << a.std::min)(a.abs().sqrt()) << endl;
  336. }
  337. template <class Num>
  338. void example11()
  339. {
  340. using namespace std;
  341. Matrix<Num, Dynamic, Dynamic> m(2, 2);
  342. Matrix<Num, Dynamic, Dynamic> n(2, 2);
  343. Matrix<Num, Dynamic, Dynamic> result(2, 2);
  344. m << 1, 2,
  345. 3, 4;
  346. n << 5, 6,
  347. 7, 8;
  348. result = m * n;
  349. cout << "-- Matrix m*n: --" << endl
  350. << result << endl
  351. << endl;
  352. result = m.array() * n.array();
  353. cout << "-- Array m*n: --" << endl
  354. << result << endl
  355. << endl;
  356. result = m.cwiseProduct(n);
  357. cout << "-- With cwiseProduct: --" << endl
  358. << result << endl
  359. << endl;
  360. result = m.array() + 4;
  361. cout << "-- Array m + 4: --" << endl
  362. << result << endl
  363. << endl;
  364. }
  365. template <class Num>
  366. void example12()
  367. {
  368. using namespace std;
  369. Matrix<Num, Dynamic, Dynamic> m(2, 2);
  370. Matrix<Num, Dynamic, Dynamic> n(2, 2);
  371. Matrix<Num, Dynamic, Dynamic> result(2, 2);
  372. m << 1, 2,
  373. 3, 4;
  374. n << 5, 6,
  375. 7, 8;
  376. result = (m.array() + 4).matrix() * m;
  377. cout << "-- Combination 1: --" << endl
  378. << result << endl
  379. << endl;
  380. result = (m.array() * n.array()).matrix() * m;
  381. cout << "-- Combination 2: --" << endl
  382. << result << endl
  383. << endl;
  384. }
  385. template <class Num>
  386. void example13()
  387. {
  388. using namespace std;
  389. Matrix<Num, Dynamic, Dynamic> m(4, 4);
  390. m << 1, 2, 3, 4,
  391. 5, 6, 7, 8,
  392. 9, 10, 11, 12,
  393. 13, 14, 15, 16;
  394. cout << "Block in the middle" << endl;
  395. cout << m.template block<2, 2>(1, 1) << endl
  396. << endl;
  397. for (int i = 1; i <= 3; ++i)
  398. {
  399. cout << "Block of size " << i << "x" << i << endl;
  400. cout << m.block(0, 0, i, i) << endl
  401. << endl;
  402. }
  403. }
  404. template <class Num>
  405. void example14()
  406. {
  407. using namespace std;
  408. Array<Num, 2, 2> m;
  409. m << 1, 2,
  410. 3, 4;
  411. Array<Num, 4, 4> a = Array<Num, 4, 4>::Constant(0.6);
  412. cout << "Here is the array a:" << endl
  413. << a << endl
  414. << endl;
  415. a.template block<2, 2>(1, 1) = m;
  416. cout << "Here is now a with m copied into its central 2x2 block:" << endl
  417. << a << endl
  418. << endl;
  419. a.block(0, 0, 2, 3) = a.block(2, 1, 2, 3);
  420. cout << "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl
  421. << a << endl
  422. << endl;
  423. }
  424. template <class Num>
  425. void example15()
  426. {
  427. using namespace std;
  428. Eigen::Matrix<Num, Dynamic, Dynamic> m(3, 3);
  429. m << 1, 2, 3,
  430. 4, 5, 6,
  431. 7, 8, 9;
  432. cout << "Here is the matrix m:" << endl
  433. << m << endl;
  434. cout << "2nd Row: " << m.row(1) << endl;
  435. m.col(2) += 3 * m.col(0);
  436. cout << "After adding 3 times the first column into the third column, the matrix m is:\n";
  437. cout << m << endl;
  438. }
  439. template <class Num>
  440. void example16()
  441. {
  442. using namespace std;
  443. Matrix<Num, 4, 4> m;
  444. m << 1, 2, 3, 4,
  445. 5, 6, 7, 8,
  446. 9, 10, 11, 12,
  447. 13, 14, 15, 16;
  448. cout << "m.leftCols(2) =" << endl
  449. << m.leftCols(2) << endl
  450. << endl;
  451. cout << "m.bottomRows<2>() =" << endl
  452. << m.template bottomRows<2>() << endl
  453. << endl;
  454. m.topLeftCorner(1, 3) = m.bottomRightCorner(3, 1).transpose();
  455. cout << "After assignment, m = " << endl
  456. << m << endl;
  457. }
  458. template <class Num>
  459. void example17()
  460. {
  461. using namespace std;
  462. Array<Num, Dynamic, 1> v(6);
  463. v << 1, 2, 3, 4, 5, 6;
  464. cout << "v.head(3) =" << endl
  465. << v.head(3) << endl
  466. << endl;
  467. cout << "v.tail<3>() = " << endl
  468. << v.template tail<3>() << endl
  469. << endl;
  470. v.segment(1, 4) *= 2;
  471. cout << "after 'v.segment(1,4) *= 2', v =" << endl
  472. << v << endl;
  473. }
  474. template <class Num>
  475. void example18()
  476. {
  477. using namespace std;
  478. Matrix<Num, 2, 2> mat;
  479. mat << 1, 2,
  480. 3, 4;
  481. cout << "Here is mat.sum(): " << mat.sum() << endl;
  482. cout << "Here is mat.prod(): " << mat.prod() << endl;
  483. cout << "Here is mat.mean(): " << mat.mean() << endl;
  484. cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  485. cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  486. cout << "Here is mat.trace(): " << mat.trace() << endl;
  487. BOOST_CHECK_EQUAL(mat.sum(), 10);
  488. BOOST_CHECK_EQUAL(mat.prod(), 24);
  489. BOOST_CHECK_EQUAL(mat.mean(), Num(5) / 2);
  490. BOOST_CHECK_EQUAL(mat.minCoeff(), 1);
  491. BOOST_CHECK_EQUAL(mat.maxCoeff(), 4);
  492. BOOST_CHECK_EQUAL(mat.trace(), 5);
  493. }
  494. template <class Num>
  495. void example18a()
  496. {
  497. using namespace std;
  498. Matrix<Num, 2, 2> mat;
  499. mat << 1, 2,
  500. 3, 4;
  501. cout << "Here is mat.sum(): " << mat.sum() << endl;
  502. cout << "Here is mat.prod(): " << mat.prod() << endl;
  503. cout << "Here is mat.mean(): " << mat.mean() << endl;
  504. //cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  505. //cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  506. cout << "Here is mat.trace(): " << mat.trace() << endl;
  507. }
  508. template <class Num>
  509. void example19()
  510. {
  511. using namespace std;
  512. Matrix<Num, Dynamic, 1> v(2);
  513. Matrix<Num, Dynamic, Dynamic> m(2, 2), n(2, 2);
  514. v << -1,
  515. 2;
  516. m << 1, -2,
  517. -3, 4;
  518. cout << "v.squaredNorm() = " << v.squaredNorm() << endl;
  519. cout << "v.norm() = " << v.norm() << endl;
  520. cout << "v.lpNorm<1>() = " << v.template lpNorm<1>() << endl;
  521. cout << "v.lpNorm<Infinity>() = " << v.template lpNorm<Infinity>() << endl;
  522. cout << endl;
  523. cout << "m.squaredNorm() = " << m.squaredNorm() << endl;
  524. cout << "m.norm() = " << m.norm() << endl;
  525. cout << "m.lpNorm<1>() = " << m.template lpNorm<1>() << endl;
  526. cout << "m.lpNorm<Infinity>() = " << m.template lpNorm<Infinity>() << endl;
  527. }
  528. template <class Num>
  529. void example20()
  530. {
  531. using namespace std;
  532. Matrix<Num, 3, 3> A;
  533. Matrix<Num, 3, 1> b;
  534. A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
  535. b << 3, 3, 4;
  536. cout << "Here is the matrix A:\n"
  537. << A << endl;
  538. cout << "Here is the vector b:\n"
  539. << b << endl;
  540. Matrix<Num, 3, 1> x = A.colPivHouseholderQr().solve(b);
  541. cout << "The solution is:\n"
  542. << x << endl;
  543. }
  544. template <class Num>
  545. void example21()
  546. {
  547. using namespace std;
  548. Matrix<Num, 2, 2> A, b;
  549. A << 2, -1, -1, 3;
  550. b << 1, 2, 3, 1;
  551. cout << "Here is the matrix A:\n"
  552. << A << endl;
  553. cout << "Here is the right hand side b:\n"
  554. << b << endl;
  555. Matrix<Num, 2, 2> x = A.ldlt().solve(b);
  556. cout << "The solution is:\n"
  557. << x << endl;
  558. }
  559. template <class Num>
  560. void example22()
  561. {
  562. using namespace std;
  563. Matrix<Num, Dynamic, Dynamic> A = Matrix<Num, Dynamic, Dynamic>::Random(100, 100);
  564. Matrix<Num, Dynamic, Dynamic> b = Matrix<Num, Dynamic, Dynamic>::Random(100, 50);
  565. Matrix<Num, Dynamic, Dynamic> x = A.fullPivLu().solve(b);
  566. Matrix<Num, Dynamic, Dynamic> axmb = A * x - b;
  567. double relative_error = static_cast<double>(abs(axmb.norm() / b.norm())); // norm() is L2 norm
  568. cout << "norm1 = " << axmb.norm() << endl;
  569. cout << "norm2 = " << b.norm() << endl;
  570. cout << "The relative error is:\n"
  571. << relative_error << endl;
  572. }
  573. template <class Num>
  574. void example23()
  575. {
  576. using namespace std;
  577. Matrix<Num, 2, 2> A;
  578. A << 1, 2, 2, 3;
  579. cout << "Here is the matrix A:\n"
  580. << A << endl;
  581. SelfAdjointEigenSolver<Matrix<Num, 2, 2> > eigensolver(A);
  582. if (eigensolver.info() != Success)
  583. {
  584. std::cout << "Eigenvalue solver failed!" << endl;
  585. }
  586. else
  587. {
  588. cout << "The eigenvalues of A are:\n"
  589. << eigensolver.eigenvalues() << endl;
  590. cout << "Here's a matrix whose columns are eigenvectors of A \n"
  591. << "corresponding to these eigenvalues:\n"
  592. << eigensolver.eigenvectors() << endl;
  593. }
  594. }
  595. template <class Num>
  596. void example24()
  597. {
  598. using namespace std;
  599. Matrix<Num, 3, 3> A;
  600. A << 1, 2, 1,
  601. 2, 1, 0,
  602. -1, 1, 2;
  603. cout << "Here is the matrix A:\n"
  604. << A << endl;
  605. cout << "The determinant of A is " << A.determinant() << endl;
  606. cout << "The inverse of A is:\n"
  607. << A.inverse() << endl;
  608. }
  609. template <class Num>
  610. void test_integer_type()
  611. {
  612. example1<Num>();
  613. //example2<Num>();
  614. example18<Num>();
  615. }
  616. template <class Num>
  617. void test_float_type()
  618. {
  619. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  620. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  621. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  622. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  623. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  624. example1<Num>();
  625. example2<Num>();
  626. example4<Num>();
  627. example5<Num>();
  628. example6<Num>();
  629. example7<Num>();
  630. example8<Num>();
  631. example9<Num>();
  632. example10<Num>();
  633. example11<Num>();
  634. example12<Num>();
  635. example13<Num>();
  636. example14<Num>();
  637. example15<Num>();
  638. example16<Num>();
  639. example17<Num>();
  640. example18<Num>();
  641. example19<Num>();
  642. example20<Num>();
  643. example21<Num>();
  644. example22<Num>();
  645. example23<Num>();
  646. example24<Num>();
  647. }
  648. template <class Num>
  649. void test_complex_type()
  650. {
  651. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  652. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  653. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  654. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  655. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  656. example1<Num>();
  657. example2<Num>();
  658. example3<Num>();
  659. example4<Num>();
  660. example5<Num>();
  661. example7<Num>();
  662. example8<Num>();
  663. example9<Num>();
  664. example11<Num>();
  665. example12<Num>();
  666. example13<Num>();
  667. example14<Num>();
  668. example15<Num>();
  669. example16<Num>();
  670. example17<Num>();
  671. example18a<Num>();
  672. example19<Num>();
  673. example20<Num>();
  674. example21<Num>();
  675. example22<Num>();
  676. // example23<Num>(); //requires comparisons.
  677. example24<Num>();
  678. }
  679. namespace boost {
  680. namespace multiprecision {
  681. template <unsigned D>
  682. inline void log_postfix_event(const mpc_complex_backend<D>& val, const char* event_description)
  683. {
  684. if (mpfr_nan_p(mpc_realref(val.data())))
  685. {
  686. std::cout << "Found a NaN! " << event_description << std::endl;
  687. }
  688. }
  689. }
  690. } // namespace boost::multiprecision
  691. int main()
  692. {
  693. using namespace boost::multiprecision;
  694. test_complex_type<mpc_complex>();
  695. #if 0
  696. test_integer_type<int>();
  697. test_float_type<double>();
  698. test_complex_type<std::complex<double> >();
  699. test_float_type<boost::multiprecision::cpp_dec_float_100>();
  700. test_float_type<boost::multiprecision::cpp_bin_float_50>();
  701. test_float_type<boost::multiprecision::mpfr_float>();
  702. test_integer_type<boost::multiprecision::int256_t>();
  703. test_integer_type<boost::multiprecision::cpp_int>();
  704. test_integer_type<boost::multiprecision::cpp_rational>();
  705. test_integer_type<boost::multiprecision::mpz_int>();
  706. test_integer_type<boost::multiprecision::mpq_rational>();
  707. #endif
  708. return 0;
  709. }