eigen.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  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. #include <boost/multiprecision/eigen.hpp>
  6. #include <iostream>
  7. #include <Eigen/Dense>
  8. #include "test.hpp"
  9. using namespace Eigen;
  10. template <class T>
  11. struct related_number
  12. {
  13. typedef T type;
  14. };
  15. template <class Num>
  16. void example1()
  17. {
  18. // expected results first:
  19. Matrix<Num, 2, 2> r1, r2;
  20. r1 << 3, 5, 4, 8;
  21. r2 << -1, -1, 2, 0;
  22. Matrix<Num, 3, 1> r3;
  23. r3 << -1, -4, -6;
  24. Matrix<Num, 2, 2> a;
  25. a << 1, 2, 3, 4;
  26. Matrix<Num, Dynamic, Dynamic> b(2, 2);
  27. b << 2, 3, 1, 4;
  28. std::cout << "a + b =\n"
  29. << a + b << std::endl;
  30. BOOST_CHECK_EQUAL(a + b, r1);
  31. std::cout << "a - b =\n"
  32. << a - b << std::endl;
  33. BOOST_CHECK_EQUAL(a - b, r2);
  34. std::cout << "Doing a += b;" << std::endl;
  35. a += b;
  36. std::cout << "Now a =\n"
  37. << a << std::endl;
  38. Matrix<Num, 3, 1> v(1, 2, 3);
  39. Matrix<Num, 3, 1> w(1, 0, 0);
  40. std::cout << "-v + w - v =\n"
  41. << -v + w - v << std::endl;
  42. BOOST_CHECK_EQUAL(-v + w - v, r3);
  43. }
  44. template <class Num>
  45. void example2()
  46. {
  47. Matrix<Num, 2, 2> a;
  48. a << 1, 2, 3, 4;
  49. Matrix<Num, 3, 1> v(1, 2, 3);
  50. std::cout << "a * 2.5 =\n"
  51. << a * 2.5 << std::endl;
  52. std::cout << "0.1 * v =\n"
  53. << 0.1 * v << std::endl;
  54. std::cout << "Doing v *= 2;" << std::endl;
  55. v *= 2;
  56. std::cout << "Now v =\n"
  57. << v << std::endl;
  58. Num n(4);
  59. std::cout << "Doing v *= Num;" << std::endl;
  60. v *= n;
  61. std::cout << "Now v =\n"
  62. << v << std::endl;
  63. typedef typename related_number<Num>::type related_type;
  64. related_type r(6);
  65. std::cout << "Doing v *= RelatedType;" << std::endl;
  66. v *= r;
  67. std::cout << "Now v =\n"
  68. << v << std::endl;
  69. std::cout << "RelatedType * v =\n"
  70. << r * v << std::endl;
  71. std::cout << "Doing v *= RelatedType^2;" << std::endl;
  72. v *= r * r;
  73. std::cout << "Now v =\n"
  74. << v << std::endl;
  75. std::cout << "RelatedType^2 * v =\n"
  76. << r * r * v << std::endl;
  77. }
  78. template <class Num>
  79. void example3()
  80. {
  81. using namespace std;
  82. Matrix<Num, Dynamic, Dynamic> a = Matrix<Num, Dynamic, Dynamic>::Random(2, 2);
  83. cout << "Here is the matrix a\n"
  84. << a << endl;
  85. cout << "Here is the matrix a^T\n"
  86. << a.transpose() << endl;
  87. cout << "Here is the conjugate of a\n"
  88. << a.conjugate() << endl;
  89. cout << "Here is the matrix a^*\n"
  90. << a.adjoint() << endl;
  91. }
  92. template <class Num>
  93. void example4()
  94. {
  95. Matrix<Num, 2, 2> mat;
  96. mat << 1, 2,
  97. 3, 4;
  98. Matrix<Num, 2, 1> u(-1, 1), v(2, 0);
  99. std::cout << "Here is mat*mat:\n"
  100. << mat * mat << std::endl;
  101. std::cout << "Here is mat*u:\n"
  102. << mat * u << std::endl;
  103. std::cout << "Here is u^T*mat:\n"
  104. << u.transpose() * mat << std::endl;
  105. std::cout << "Here is u^T*v:\n"
  106. << u.transpose() * v << std::endl;
  107. std::cout << "Here is u*v^T:\n"
  108. << u * v.transpose() << std::endl;
  109. std::cout << "Let's multiply mat by itself" << std::endl;
  110. mat = mat * mat;
  111. std::cout << "Now mat is mat:\n"
  112. << mat << std::endl;
  113. }
  114. template <class Num>
  115. void example5()
  116. {
  117. using namespace std;
  118. Matrix<Num, 3, 1> v(1, 2, 3);
  119. Matrix<Num, 3, 1> w(0, 1, 2);
  120. cout << "Dot product: " << v.dot(w) << endl;
  121. Num dp = v.adjoint() * w; // automatic conversion of the inner product to a scalar
  122. cout << "Dot product via a matrix product: " << dp << endl;
  123. cout << "Cross product:\n"
  124. << v.cross(w) << endl;
  125. }
  126. template <class Num>
  127. void example6()
  128. {
  129. using namespace std;
  130. Matrix<Num, 2, 2> mat;
  131. mat << 1, 2,
  132. 3, 4;
  133. cout << "Here is mat.sum(): " << mat.sum() << endl;
  134. cout << "Here is mat.prod(): " << mat.prod() << endl;
  135. cout << "Here is mat.mean(): " << mat.mean() << endl;
  136. cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  137. cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  138. cout << "Here is mat.trace(): " << mat.trace() << endl;
  139. }
  140. template <class Num>
  141. void example7()
  142. {
  143. using namespace std;
  144. Array<Num, Dynamic, Dynamic> m(2, 2);
  145. // assign some values coefficient by coefficient
  146. m(0, 0) = 1.0;
  147. m(0, 1) = 2.0;
  148. m(1, 0) = 3.0;
  149. m(1, 1) = m(0, 1) + m(1, 0);
  150. // print values to standard output
  151. cout << m << endl
  152. << endl;
  153. // using the comma-initializer is also allowed
  154. m << 1.0, 2.0,
  155. 3.0, 4.0;
  156. // print values to standard output
  157. cout << m << endl;
  158. }
  159. template <class Num>
  160. void example8()
  161. {
  162. using namespace std;
  163. Array<Num, Dynamic, Dynamic> a(3, 3);
  164. Array<Num, Dynamic, Dynamic> b(3, 3);
  165. a << 1, 2, 3,
  166. 4, 5, 6,
  167. 7, 8, 9;
  168. b << 1, 2, 3,
  169. 1, 2, 3,
  170. 1, 2, 3;
  171. // Adding two arrays
  172. cout << "a + b = " << endl
  173. << a + b << endl
  174. << endl;
  175. // Subtracting a scalar from an array
  176. cout << "a - 2 = " << endl
  177. << a - 2 << endl;
  178. }
  179. template <class Num>
  180. void example9()
  181. {
  182. using namespace std;
  183. Array<Num, Dynamic, Dynamic> a(2, 2);
  184. Array<Num, Dynamic, Dynamic> b(2, 2);
  185. a << 1, 2,
  186. 3, 4;
  187. b << 5, 6,
  188. 7, 8;
  189. cout << "a * b = " << endl
  190. << a * b << endl;
  191. }
  192. template <class Num>
  193. void example10()
  194. {
  195. using namespace std;
  196. Array<Num, Dynamic, 1> a = Array<Num, Dynamic, 1>::Random(5);
  197. a *= 2;
  198. cout << "a =" << endl
  199. << a << endl;
  200. cout << "a.abs() =" << endl
  201. << a.abs() << endl;
  202. cout << "a.abs().sqrt() =" << endl
  203. << a.abs().sqrt() << endl;
  204. cout << "a.min(a.abs().sqrt()) =" << endl
  205. << (a.min)(a.abs().sqrt()) << endl;
  206. }
  207. template <class Num>
  208. void example11()
  209. {
  210. using namespace std;
  211. Matrix<Num, Dynamic, Dynamic> m(2, 2);
  212. Matrix<Num, Dynamic, Dynamic> n(2, 2);
  213. Matrix<Num, Dynamic, Dynamic> result(2, 2);
  214. m << 1, 2,
  215. 3, 4;
  216. n << 5, 6,
  217. 7, 8;
  218. result = m * n;
  219. cout << "-- Matrix m*n: --" << endl
  220. << result << endl
  221. << endl;
  222. result = m.array() * n.array();
  223. cout << "-- Array m*n: --" << endl
  224. << result << endl
  225. << endl;
  226. result = m.cwiseProduct(n);
  227. cout << "-- With cwiseProduct: --" << endl
  228. << result << endl
  229. << endl;
  230. result = m.array() + 4;
  231. cout << "-- Array m + 4: --" << endl
  232. << result << endl
  233. << endl;
  234. }
  235. template <class Num>
  236. void example12()
  237. {
  238. using namespace std;
  239. Matrix<Num, Dynamic, Dynamic> m(2, 2);
  240. Matrix<Num, Dynamic, Dynamic> n(2, 2);
  241. Matrix<Num, Dynamic, Dynamic> result(2, 2);
  242. m << 1, 2,
  243. 3, 4;
  244. n << 5, 6,
  245. 7, 8;
  246. result = (m.array() + 4).matrix() * m;
  247. cout << "-- Combination 1: --" << endl
  248. << result << endl
  249. << endl;
  250. result = (m.array() * n.array()).matrix() * m;
  251. cout << "-- Combination 2: --" << endl
  252. << result << endl
  253. << endl;
  254. }
  255. template <class Num>
  256. void example13()
  257. {
  258. using namespace std;
  259. Matrix<Num, Dynamic, Dynamic> m(4, 4);
  260. m << 1, 2, 3, 4,
  261. 5, 6, 7, 8,
  262. 9, 10, 11, 12,
  263. 13, 14, 15, 16;
  264. cout << "Block in the middle" << endl;
  265. cout << m.template block<2, 2>(1, 1) << endl
  266. << endl;
  267. for (int i = 1; i <= 3; ++i)
  268. {
  269. cout << "Block of size " << i << "x" << i << endl;
  270. cout << m.block(0, 0, i, i) << endl
  271. << endl;
  272. }
  273. }
  274. template <class Num>
  275. void example14()
  276. {
  277. using namespace std;
  278. Array<Num, 2, 2> m;
  279. m << 1, 2,
  280. 3, 4;
  281. Array<Num, 4, 4> a = Array<Num, 4, 4>::Constant(0.6);
  282. cout << "Here is the array a:" << endl
  283. << a << endl
  284. << endl;
  285. a.template block<2, 2>(1, 1) = m;
  286. cout << "Here is now a with m copied into its central 2x2 block:" << endl
  287. << a << endl
  288. << endl;
  289. a.block(0, 0, 2, 3) = a.block(2, 1, 2, 3);
  290. cout << "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl
  291. << a << endl
  292. << endl;
  293. }
  294. template <class Num>
  295. void example15()
  296. {
  297. using namespace std;
  298. Eigen::Matrix<Num, Dynamic, Dynamic> m(3, 3);
  299. m << 1, 2, 3,
  300. 4, 5, 6,
  301. 7, 8, 9;
  302. cout << "Here is the matrix m:" << endl
  303. << m << endl;
  304. cout << "2nd Row: " << m.row(1) << endl;
  305. m.col(2) += 3 * m.col(0);
  306. cout << "After adding 3 times the first column into the third column, the matrix m is:\n";
  307. cout << m << endl;
  308. }
  309. template <class Num>
  310. void example16()
  311. {
  312. using namespace std;
  313. Matrix<Num, 4, 4> m;
  314. m << 1, 2, 3, 4,
  315. 5, 6, 7, 8,
  316. 9, 10, 11, 12,
  317. 13, 14, 15, 16;
  318. cout << "m.leftCols(2) =" << endl
  319. << m.leftCols(2) << endl
  320. << endl;
  321. cout << "m.bottomRows<2>() =" << endl
  322. << m.template bottomRows<2>() << endl
  323. << endl;
  324. m.topLeftCorner(1, 3) = m.bottomRightCorner(3, 1).transpose();
  325. cout << "After assignment, m = " << endl
  326. << m << endl;
  327. }
  328. template <class Num>
  329. void example17()
  330. {
  331. using namespace std;
  332. Array<Num, Dynamic, 1> v(6);
  333. v << 1, 2, 3, 4, 5, 6;
  334. cout << "v.head(3) =" << endl
  335. << v.head(3) << endl
  336. << endl;
  337. cout << "v.tail<3>() = " << endl
  338. << v.template tail<3>() << endl
  339. << endl;
  340. v.segment(1, 4) *= 2;
  341. cout << "after 'v.segment(1,4) *= 2', v =" << endl
  342. << v << endl;
  343. }
  344. template <class Num>
  345. void example18()
  346. {
  347. using namespace std;
  348. Matrix<Num, 2, 2> mat;
  349. mat << 1, 2,
  350. 3, 4;
  351. cout << "Here is mat.sum(): " << mat.sum() << endl;
  352. cout << "Here is mat.prod(): " << mat.prod() << endl;
  353. cout << "Here is mat.mean(): " << mat.mean() << endl;
  354. cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  355. cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  356. cout << "Here is mat.trace(): " << mat.trace() << endl;
  357. BOOST_CHECK_EQUAL(mat.sum(), 10);
  358. BOOST_CHECK_EQUAL(mat.prod(), 24);
  359. BOOST_CHECK_EQUAL(mat.mean(), Num(5) / 2);
  360. BOOST_CHECK_EQUAL(mat.minCoeff(), 1);
  361. BOOST_CHECK_EQUAL(mat.maxCoeff(), 4);
  362. BOOST_CHECK_EQUAL(mat.trace(), 5);
  363. }
  364. template <class Num>
  365. void example18a()
  366. {
  367. using namespace std;
  368. Matrix<Num, 2, 2> mat;
  369. mat << 1, 2,
  370. 3, 4;
  371. cout << "Here is mat.sum(): " << mat.sum() << endl;
  372. cout << "Here is mat.prod(): " << mat.prod() << endl;
  373. cout << "Here is mat.mean(): " << mat.mean() << endl;
  374. //cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
  375. //cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
  376. cout << "Here is mat.trace(): " << mat.trace() << endl;
  377. }
  378. template <class Num>
  379. void example19()
  380. {
  381. using namespace std;
  382. Matrix<Num, Dynamic, 1> v(2);
  383. Matrix<Num, Dynamic, Dynamic> m(2, 2), n(2, 2);
  384. v << -1,
  385. 2;
  386. m << 1, -2,
  387. -3, 4;
  388. cout << "v.squaredNorm() = " << v.squaredNorm() << endl;
  389. cout << "v.norm() = " << v.norm() << endl;
  390. cout << "v.lpNorm<1>() = " << v.template lpNorm<1>() << endl;
  391. cout << "v.lpNorm<Infinity>() = " << v.template lpNorm<Infinity>() << endl;
  392. cout << endl;
  393. cout << "m.squaredNorm() = " << m.squaredNorm() << endl;
  394. cout << "m.norm() = " << m.norm() << endl;
  395. cout << "m.lpNorm<1>() = " << m.template lpNorm<1>() << endl;
  396. cout << "m.lpNorm<Infinity>() = " << m.template lpNorm<Infinity>() << endl;
  397. }
  398. template <class Num>
  399. void example20()
  400. {
  401. using namespace std;
  402. Matrix<Num, 3, 3> A;
  403. Matrix<Num, 3, 1> b;
  404. A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
  405. b << 3, 3, 4;
  406. cout << "Here is the matrix A:\n"
  407. << A << endl;
  408. cout << "Here is the vector b:\n"
  409. << b << endl;
  410. Matrix<Num, 3, 1> x = A.colPivHouseholderQr().solve(b);
  411. cout << "The solution is:\n"
  412. << x << endl;
  413. }
  414. template <class Num>
  415. void example21()
  416. {
  417. using namespace std;
  418. Matrix<Num, 2, 2> A, b;
  419. A << 2, -1, -1, 3;
  420. b << 1, 2, 3, 1;
  421. cout << "Here is the matrix A:\n"
  422. << A << endl;
  423. cout << "Here is the right hand side b:\n"
  424. << b << endl;
  425. Matrix<Num, 2, 2> x = A.ldlt().solve(b);
  426. cout << "The solution is:\n"
  427. << x << endl;
  428. }
  429. template <class Num>
  430. void example22()
  431. {
  432. using namespace std;
  433. Matrix<Num, Dynamic, Dynamic> A = Matrix<Num, Dynamic, Dynamic>::Random(100, 100);
  434. Matrix<Num, Dynamic, Dynamic> b = Matrix<Num, Dynamic, Dynamic>::Random(100, 50);
  435. Matrix<Num, Dynamic, Dynamic> x = A.fullPivLu().solve(b);
  436. Matrix<Num, Dynamic, Dynamic> axmb = A * x - b;
  437. double relative_error = static_cast<double>(abs(axmb.norm() / b.norm())); // norm() is L2 norm
  438. cout << "norm1 = " << axmb.norm() << endl;
  439. cout << "norm2 = " << b.norm() << endl;
  440. cout << "The relative error is:\n"
  441. << relative_error << endl;
  442. }
  443. template <class Num>
  444. void example23()
  445. {
  446. using namespace std;
  447. Matrix<Num, 2, 2> A;
  448. A << 1, 2, 2, 3;
  449. cout << "Here is the matrix A:\n"
  450. << A << endl;
  451. SelfAdjointEigenSolver<Matrix<Num, 2, 2> > eigensolver(A);
  452. if (eigensolver.info() != Success)
  453. {
  454. std::cout << "Eigenvalue solver failed!" << endl;
  455. }
  456. else
  457. {
  458. cout << "The eigenvalues of A are:\n"
  459. << eigensolver.eigenvalues() << endl;
  460. cout << "Here's a matrix whose columns are eigenvectors of A \n"
  461. << "corresponding to these eigenvalues:\n"
  462. << eigensolver.eigenvectors() << endl;
  463. }
  464. }
  465. template <class Num>
  466. void example24()
  467. {
  468. using namespace std;
  469. Matrix<Num, 3, 3> A;
  470. A << 1, 2, 1,
  471. 2, 1, 0,
  472. -1, 1, 2;
  473. cout << "Here is the matrix A:\n"
  474. << A << endl;
  475. cout << "The determinant of A is " << A.determinant() << endl;
  476. cout << "The inverse of A is:\n"
  477. << A.inverse() << endl;
  478. }
  479. template <class Num>
  480. void test_integer_type()
  481. {
  482. example1<Num>();
  483. //example2<Num>();
  484. example18<Num>();
  485. }
  486. template <class Num>
  487. void test_float_type()
  488. {
  489. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  490. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  491. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  492. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  493. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  494. example1<Num>();
  495. example2<Num>();
  496. example4<Num>();
  497. example5<Num>();
  498. example6<Num>();
  499. example7<Num>();
  500. example8<Num>();
  501. example9<Num>();
  502. example10<Num>();
  503. example11<Num>();
  504. example12<Num>();
  505. example13<Num>();
  506. example14<Num>();
  507. example15<Num>();
  508. example16<Num>();
  509. example17<Num>();
  510. /*
  511. example18<Num>();
  512. example19<Num>();
  513. example20<Num>();
  514. example21<Num>();
  515. example22<Num>();
  516. example23<Num>();
  517. example24<Num>();
  518. */
  519. }
  520. template <class Num>
  521. void test_float_type_2()
  522. {
  523. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  524. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  525. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  526. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  527. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  528. example18<Num>();
  529. example19<Num>();
  530. example20<Num>();
  531. example21<Num>();
  532. //example22<Num>();
  533. //example23<Num>();
  534. //example24<Num>();
  535. }
  536. template <class Num>
  537. void test_float_type_3()
  538. {
  539. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  540. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  541. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  542. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  543. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  544. example22<Num>();
  545. example23<Num>();
  546. example24<Num>();
  547. }
  548. template <class Num>
  549. void test_complex_type()
  550. {
  551. std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
  552. std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
  553. std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
  554. std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
  555. std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
  556. example1<Num>();
  557. example2<Num>();
  558. example3<Num>();
  559. example4<Num>();
  560. example5<Num>();
  561. example7<Num>();
  562. example8<Num>();
  563. example9<Num>();
  564. example11<Num>();
  565. example12<Num>();
  566. example13<Num>();
  567. example14<Num>();
  568. example15<Num>();
  569. example16<Num>();
  570. example17<Num>();
  571. example18a<Num>();
  572. example19<Num>();
  573. example20<Num>();
  574. example21<Num>();
  575. example22<Num>();
  576. // example23<Num>(); //requires comparisons.
  577. example24<Num>();
  578. }