123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- ///////////////////////////////////////////////////////////////////////////////
- // Copyright 2018 John Maddock. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/multiprecision/eigen.hpp>
- #include <iostream>
- #include <Eigen/Dense>
- #include "test.hpp"
- using namespace Eigen;
- template <class T>
- struct related_number
- {
- typedef T type;
- };
- template <class Num>
- void example1()
- {
- // expected results first:
- Matrix<Num, 2, 2> r1, r2;
- r1 << 3, 5, 4, 8;
- r2 << -1, -1, 2, 0;
- Matrix<Num, 3, 1> r3;
- r3 << -1, -4, -6;
- Matrix<Num, 2, 2> a;
- a << 1, 2, 3, 4;
- Matrix<Num, Dynamic, Dynamic> b(2, 2);
- b << 2, 3, 1, 4;
- std::cout << "a + b =\n"
- << a + b << std::endl;
- BOOST_CHECK_EQUAL(a + b, r1);
- std::cout << "a - b =\n"
- << a - b << std::endl;
- BOOST_CHECK_EQUAL(a - b, r2);
- std::cout << "Doing a += b;" << std::endl;
- a += b;
- std::cout << "Now a =\n"
- << a << std::endl;
- Matrix<Num, 3, 1> v(1, 2, 3);
- Matrix<Num, 3, 1> w(1, 0, 0);
- std::cout << "-v + w - v =\n"
- << -v + w - v << std::endl;
- BOOST_CHECK_EQUAL(-v + w - v, r3);
- }
- template <class Num>
- void example2()
- {
- Matrix<Num, 2, 2> a;
- a << 1, 2, 3, 4;
- Matrix<Num, 3, 1> v(1, 2, 3);
- std::cout << "a * 2.5 =\n"
- << a * 2.5 << std::endl;
- std::cout << "0.1 * v =\n"
- << 0.1 * v << std::endl;
- std::cout << "Doing v *= 2;" << std::endl;
- v *= 2;
- std::cout << "Now v =\n"
- << v << std::endl;
- Num n(4);
- std::cout << "Doing v *= Num;" << std::endl;
- v *= n;
- std::cout << "Now v =\n"
- << v << std::endl;
- typedef typename related_number<Num>::type related_type;
- related_type r(6);
- std::cout << "Doing v *= RelatedType;" << std::endl;
- v *= r;
- std::cout << "Now v =\n"
- << v << std::endl;
- std::cout << "RelatedType * v =\n"
- << r * v << std::endl;
- std::cout << "Doing v *= RelatedType^2;" << std::endl;
- v *= r * r;
- std::cout << "Now v =\n"
- << v << std::endl;
- std::cout << "RelatedType^2 * v =\n"
- << r * r * v << std::endl;
- }
- template <class Num>
- void example3()
- {
- using namespace std;
- Matrix<Num, Dynamic, Dynamic> a = Matrix<Num, Dynamic, Dynamic>::Random(2, 2);
- cout << "Here is the matrix a\n"
- << a << endl;
- cout << "Here is the matrix a^T\n"
- << a.transpose() << endl;
- cout << "Here is the conjugate of a\n"
- << a.conjugate() << endl;
- cout << "Here is the matrix a^*\n"
- << a.adjoint() << endl;
- }
- template <class Num>
- void example4()
- {
- Matrix<Num, 2, 2> mat;
- mat << 1, 2,
- 3, 4;
- Matrix<Num, 2, 1> u(-1, 1), v(2, 0);
- std::cout << "Here is mat*mat:\n"
- << mat * mat << std::endl;
- std::cout << "Here is mat*u:\n"
- << mat * u << std::endl;
- std::cout << "Here is u^T*mat:\n"
- << u.transpose() * mat << std::endl;
- std::cout << "Here is u^T*v:\n"
- << u.transpose() * v << std::endl;
- std::cout << "Here is u*v^T:\n"
- << u * v.transpose() << std::endl;
- std::cout << "Let's multiply mat by itself" << std::endl;
- mat = mat * mat;
- std::cout << "Now mat is mat:\n"
- << mat << std::endl;
- }
- template <class Num>
- void example5()
- {
- using namespace std;
- Matrix<Num, 3, 1> v(1, 2, 3);
- Matrix<Num, 3, 1> w(0, 1, 2);
- cout << "Dot product: " << v.dot(w) << endl;
- Num dp = v.adjoint() * w; // automatic conversion of the inner product to a scalar
- cout << "Dot product via a matrix product: " << dp << endl;
- cout << "Cross product:\n"
- << v.cross(w) << endl;
- }
- template <class Num>
- void example6()
- {
- using namespace std;
- Matrix<Num, 2, 2> mat;
- mat << 1, 2,
- 3, 4;
- cout << "Here is mat.sum(): " << mat.sum() << endl;
- cout << "Here is mat.prod(): " << mat.prod() << endl;
- cout << "Here is mat.mean(): " << mat.mean() << endl;
- cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
- cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
- cout << "Here is mat.trace(): " << mat.trace() << endl;
- }
- template <class Num>
- void example7()
- {
- using namespace std;
- Array<Num, Dynamic, Dynamic> m(2, 2);
- // assign some values coefficient by coefficient
- m(0, 0) = 1.0;
- m(0, 1) = 2.0;
- m(1, 0) = 3.0;
- m(1, 1) = m(0, 1) + m(1, 0);
- // print values to standard output
- cout << m << endl
- << endl;
- // using the comma-initializer is also allowed
- m << 1.0, 2.0,
- 3.0, 4.0;
- // print values to standard output
- cout << m << endl;
- }
- template <class Num>
- void example8()
- {
- using namespace std;
- Array<Num, Dynamic, Dynamic> a(3, 3);
- Array<Num, Dynamic, Dynamic> b(3, 3);
- a << 1, 2, 3,
- 4, 5, 6,
- 7, 8, 9;
- b << 1, 2, 3,
- 1, 2, 3,
- 1, 2, 3;
- // Adding two arrays
- cout << "a + b = " << endl
- << a + b << endl
- << endl;
- // Subtracting a scalar from an array
- cout << "a - 2 = " << endl
- << a - 2 << endl;
- }
- template <class Num>
- void example9()
- {
- using namespace std;
- Array<Num, Dynamic, Dynamic> a(2, 2);
- Array<Num, Dynamic, Dynamic> b(2, 2);
- a << 1, 2,
- 3, 4;
- b << 5, 6,
- 7, 8;
- cout << "a * b = " << endl
- << a * b << endl;
- }
- template <class Num>
- void example10()
- {
- using namespace std;
- Array<Num, Dynamic, 1> a = Array<Num, Dynamic, 1>::Random(5);
- a *= 2;
- cout << "a =" << endl
- << a << endl;
- cout << "a.abs() =" << endl
- << a.abs() << endl;
- cout << "a.abs().sqrt() =" << endl
- << a.abs().sqrt() << endl;
- cout << "a.min(a.abs().sqrt()) =" << endl
- << (a.min)(a.abs().sqrt()) << endl;
- }
- template <class Num>
- void example11()
- {
- using namespace std;
- Matrix<Num, Dynamic, Dynamic> m(2, 2);
- Matrix<Num, Dynamic, Dynamic> n(2, 2);
- Matrix<Num, Dynamic, Dynamic> result(2, 2);
- m << 1, 2,
- 3, 4;
- n << 5, 6,
- 7, 8;
- result = m * n;
- cout << "-- Matrix m*n: --" << endl
- << result << endl
- << endl;
- result = m.array() * n.array();
- cout << "-- Array m*n: --" << endl
- << result << endl
- << endl;
- result = m.cwiseProduct(n);
- cout << "-- With cwiseProduct: --" << endl
- << result << endl
- << endl;
- result = m.array() + 4;
- cout << "-- Array m + 4: --" << endl
- << result << endl
- << endl;
- }
- template <class Num>
- void example12()
- {
- using namespace std;
- Matrix<Num, Dynamic, Dynamic> m(2, 2);
- Matrix<Num, Dynamic, Dynamic> n(2, 2);
- Matrix<Num, Dynamic, Dynamic> result(2, 2);
- m << 1, 2,
- 3, 4;
- n << 5, 6,
- 7, 8;
- result = (m.array() + 4).matrix() * m;
- cout << "-- Combination 1: --" << endl
- << result << endl
- << endl;
- result = (m.array() * n.array()).matrix() * m;
- cout << "-- Combination 2: --" << endl
- << result << endl
- << endl;
- }
- template <class Num>
- void example13()
- {
- using namespace std;
- Matrix<Num, Dynamic, Dynamic> m(4, 4);
- m << 1, 2, 3, 4,
- 5, 6, 7, 8,
- 9, 10, 11, 12,
- 13, 14, 15, 16;
- cout << "Block in the middle" << endl;
- cout << m.template block<2, 2>(1, 1) << endl
- << endl;
- for (int i = 1; i <= 3; ++i)
- {
- cout << "Block of size " << i << "x" << i << endl;
- cout << m.block(0, 0, i, i) << endl
- << endl;
- }
- }
- template <class Num>
- void example14()
- {
- using namespace std;
- Array<Num, 2, 2> m;
- m << 1, 2,
- 3, 4;
- Array<Num, 4, 4> a = Array<Num, 4, 4>::Constant(0.6);
- cout << "Here is the array a:" << endl
- << a << endl
- << endl;
- a.template block<2, 2>(1, 1) = m;
- cout << "Here is now a with m copied into its central 2x2 block:" << endl
- << a << endl
- << endl;
- a.block(0, 0, 2, 3) = a.block(2, 1, 2, 3);
- cout << "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl
- << a << endl
- << endl;
- }
- template <class Num>
- void example15()
- {
- using namespace std;
- Eigen::Matrix<Num, Dynamic, Dynamic> m(3, 3);
- m << 1, 2, 3,
- 4, 5, 6,
- 7, 8, 9;
- cout << "Here is the matrix m:" << endl
- << m << endl;
- cout << "2nd Row: " << m.row(1) << endl;
- m.col(2) += 3 * m.col(0);
- cout << "After adding 3 times the first column into the third column, the matrix m is:\n";
- cout << m << endl;
- }
- template <class Num>
- void example16()
- {
- using namespace std;
- Matrix<Num, 4, 4> m;
- m << 1, 2, 3, 4,
- 5, 6, 7, 8,
- 9, 10, 11, 12,
- 13, 14, 15, 16;
- cout << "m.leftCols(2) =" << endl
- << m.leftCols(2) << endl
- << endl;
- cout << "m.bottomRows<2>() =" << endl
- << m.template bottomRows<2>() << endl
- << endl;
- m.topLeftCorner(1, 3) = m.bottomRightCorner(3, 1).transpose();
- cout << "After assignment, m = " << endl
- << m << endl;
- }
- template <class Num>
- void example17()
- {
- using namespace std;
- Array<Num, Dynamic, 1> v(6);
- v << 1, 2, 3, 4, 5, 6;
- cout << "v.head(3) =" << endl
- << v.head(3) << endl
- << endl;
- cout << "v.tail<3>() = " << endl
- << v.template tail<3>() << endl
- << endl;
- v.segment(1, 4) *= 2;
- cout << "after 'v.segment(1,4) *= 2', v =" << endl
- << v << endl;
- }
- template <class Num>
- void example18()
- {
- using namespace std;
- Matrix<Num, 2, 2> mat;
- mat << 1, 2,
- 3, 4;
- cout << "Here is mat.sum(): " << mat.sum() << endl;
- cout << "Here is mat.prod(): " << mat.prod() << endl;
- cout << "Here is mat.mean(): " << mat.mean() << endl;
- cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
- cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
- cout << "Here is mat.trace(): " << mat.trace() << endl;
- BOOST_CHECK_EQUAL(mat.sum(), 10);
- BOOST_CHECK_EQUAL(mat.prod(), 24);
- BOOST_CHECK_EQUAL(mat.mean(), Num(5) / 2);
- BOOST_CHECK_EQUAL(mat.minCoeff(), 1);
- BOOST_CHECK_EQUAL(mat.maxCoeff(), 4);
- BOOST_CHECK_EQUAL(mat.trace(), 5);
- }
- template <class Num>
- void example18a()
- {
- using namespace std;
- Matrix<Num, 2, 2> mat;
- mat << 1, 2,
- 3, 4;
- cout << "Here is mat.sum(): " << mat.sum() << endl;
- cout << "Here is mat.prod(): " << mat.prod() << endl;
- cout << "Here is mat.mean(): " << mat.mean() << endl;
- //cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;
- //cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;
- cout << "Here is mat.trace(): " << mat.trace() << endl;
- }
- template <class Num>
- void example19()
- {
- using namespace std;
- Matrix<Num, Dynamic, 1> v(2);
- Matrix<Num, Dynamic, Dynamic> m(2, 2), n(2, 2);
- v << -1,
- 2;
- m << 1, -2,
- -3, 4;
- cout << "v.squaredNorm() = " << v.squaredNorm() << endl;
- cout << "v.norm() = " << v.norm() << endl;
- cout << "v.lpNorm<1>() = " << v.template lpNorm<1>() << endl;
- cout << "v.lpNorm<Infinity>() = " << v.template lpNorm<Infinity>() << endl;
- cout << endl;
- cout << "m.squaredNorm() = " << m.squaredNorm() << endl;
- cout << "m.norm() = " << m.norm() << endl;
- cout << "m.lpNorm<1>() = " << m.template lpNorm<1>() << endl;
- cout << "m.lpNorm<Infinity>() = " << m.template lpNorm<Infinity>() << endl;
- }
- template <class Num>
- void example20()
- {
- using namespace std;
- Matrix<Num, 3, 3> A;
- Matrix<Num, 3, 1> b;
- A << 1, 2, 3, 4, 5, 6, 7, 8, 10;
- b << 3, 3, 4;
- cout << "Here is the matrix A:\n"
- << A << endl;
- cout << "Here is the vector b:\n"
- << b << endl;
- Matrix<Num, 3, 1> x = A.colPivHouseholderQr().solve(b);
- cout << "The solution is:\n"
- << x << endl;
- }
- template <class Num>
- void example21()
- {
- using namespace std;
- Matrix<Num, 2, 2> A, b;
- A << 2, -1, -1, 3;
- b << 1, 2, 3, 1;
- cout << "Here is the matrix A:\n"
- << A << endl;
- cout << "Here is the right hand side b:\n"
- << b << endl;
- Matrix<Num, 2, 2> x = A.ldlt().solve(b);
- cout << "The solution is:\n"
- << x << endl;
- }
- template <class Num>
- void example22()
- {
- using namespace std;
- Matrix<Num, Dynamic, Dynamic> A = Matrix<Num, Dynamic, Dynamic>::Random(100, 100);
- Matrix<Num, Dynamic, Dynamic> b = Matrix<Num, Dynamic, Dynamic>::Random(100, 50);
- Matrix<Num, Dynamic, Dynamic> x = A.fullPivLu().solve(b);
- Matrix<Num, Dynamic, Dynamic> axmb = A * x - b;
- double relative_error = static_cast<double>(abs(axmb.norm() / b.norm())); // norm() is L2 norm
- cout << "norm1 = " << axmb.norm() << endl;
- cout << "norm2 = " << b.norm() << endl;
- cout << "The relative error is:\n"
- << relative_error << endl;
- }
- template <class Num>
- void example23()
- {
- using namespace std;
- Matrix<Num, 2, 2> A;
- A << 1, 2, 2, 3;
- cout << "Here is the matrix A:\n"
- << A << endl;
- SelfAdjointEigenSolver<Matrix<Num, 2, 2> > eigensolver(A);
- if (eigensolver.info() != Success)
- {
- std::cout << "Eigenvalue solver failed!" << endl;
- }
- else
- {
- cout << "The eigenvalues of A are:\n"
- << eigensolver.eigenvalues() << endl;
- cout << "Here's a matrix whose columns are eigenvectors of A \n"
- << "corresponding to these eigenvalues:\n"
- << eigensolver.eigenvectors() << endl;
- }
- }
- template <class Num>
- void example24()
- {
- using namespace std;
- Matrix<Num, 3, 3> A;
- A << 1, 2, 1,
- 2, 1, 0,
- -1, 1, 2;
- cout << "Here is the matrix A:\n"
- << A << endl;
- cout << "The determinant of A is " << A.determinant() << endl;
- cout << "The inverse of A is:\n"
- << A.inverse() << endl;
- }
- template <class Num>
- void test_integer_type()
- {
- example1<Num>();
- //example2<Num>();
- example18<Num>();
- }
- template <class Num>
- void test_float_type()
- {
- std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
- std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
- std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
- std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
- std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
- example1<Num>();
- example2<Num>();
- example4<Num>();
- example5<Num>();
- example6<Num>();
- example7<Num>();
- example8<Num>();
- example9<Num>();
- example10<Num>();
- example11<Num>();
- example12<Num>();
- example13<Num>();
- example14<Num>();
- example15<Num>();
- example16<Num>();
- example17<Num>();
- /*
- example18<Num>();
- example19<Num>();
- example20<Num>();
- example21<Num>();
- example22<Num>();
- example23<Num>();
- example24<Num>();
- */
- }
- template <class Num>
- void test_float_type_2()
- {
- std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
- std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
- std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
- std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
- std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
- example18<Num>();
- example19<Num>();
- example20<Num>();
- example21<Num>();
- //example22<Num>();
- //example23<Num>();
- //example24<Num>();
- }
- template <class Num>
- void test_float_type_3()
- {
- std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
- std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
- std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
- std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
- std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
- example22<Num>();
- example23<Num>();
- example24<Num>();
- }
- template <class Num>
- void test_complex_type()
- {
- std::cout << "Epsilon = " << Eigen::NumTraits<Num>::epsilon() << std::endl;
- std::cout << "Dummy Prec = " << Eigen::NumTraits<Num>::dummy_precision() << std::endl;
- std::cout << "Highest = " << Eigen::NumTraits<Num>::highest() << std::endl;
- std::cout << "Lowest = " << Eigen::NumTraits<Num>::lowest() << std::endl;
- std::cout << "Digits10 = " << Eigen::NumTraits<Num>::digits10() << std::endl;
- example1<Num>();
- example2<Num>();
- example3<Num>();
- example4<Num>();
- example5<Num>();
- example7<Num>();
- example8<Num>();
- example9<Num>();
- example11<Num>();
- example12<Num>();
- example13<Num>();
- example14<Num>();
- example15<Num>();
- example16<Num>();
- example17<Num>();
- example18a<Num>();
- example19<Num>();
- example20<Num>();
- example21<Num>();
- example22<Num>();
- // example23<Num>(); //requires comparisons.
- example24<Num>();
- }
|