test_inplace_solve.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include <iostream>
  2. #include <boost/numeric/ublas/vector.hpp>
  3. #include <boost/numeric/ublas/matrix.hpp>
  4. #include <boost/numeric/ublas/matrix_sparse.hpp>
  5. #include <boost/numeric/ublas/triangular.hpp>
  6. #include <boost/numeric/ublas/io.hpp>
  7. #include "utils.hpp"
  8. namespace ublas = boost::numeric::ublas;
  9. static const double TOL(1.0e-5); ///< Used for comparing two real numbers.
  10. static const int n(10); ///< defines the test matrix size
  11. template<class mat, class vec>
  12. double diff(const mat& A, const vec& x, const vec& b) {
  13. return ublas::norm_2(prod(A, x) - b);
  14. }
  15. // efficiently fill matrix depending on majority
  16. template<class mat>
  17. void fill_matrix(mat& A, ublas::column_major_tag) {
  18. for (int i=0; i<n; ++i) {
  19. if (i-1>=0) {
  20. A(i-1, i) = -1;
  21. }
  22. A(i, i) = 1;
  23. if (i+1<n) {
  24. A(i+1, i) = -2;
  25. }
  26. }
  27. }
  28. template<class mat>
  29. void fill_matrix(mat& A, ublas::row_major_tag) {
  30. for (int i=0; i<n; ++i) {
  31. if (i-1>=0) {
  32. A(i, i-1) = -1;
  33. }
  34. A(i, i) = 1;
  35. if (i+1<n) {
  36. A(i, i+1) = -2;
  37. }
  38. }
  39. }
  40. template<class mat>
  41. BOOST_UBLAS_TEST_DEF ( test_inplace_solve )
  42. {
  43. mat A(n, n);
  44. A.clear();
  45. fill_matrix(A, typename mat::orientation_category());
  46. ublas::vector<double> b(n, 1.0);
  47. // The test matrix is not triangular, but is interpreted that way by
  48. // inplace_solve using the lower_tag/upper_tags. For checking, the
  49. // triangular_adaptor makes A triangular for comparison.
  50. {
  51. ublas::vector<double> x(b);
  52. ublas::inplace_solve(A, x, ublas::lower_tag());
  53. BOOST_UBLAS_TEST_CHECK(diff(ublas::triangular_adaptor<mat, ublas::lower>(A), x, b) < TOL);
  54. }
  55. {
  56. ublas::vector<double> x(b);
  57. ublas::inplace_solve(A, x, ublas::upper_tag());
  58. BOOST_UBLAS_TEST_CHECK(diff (ublas::triangular_adaptor<mat, ublas::upper>(A), x, b) < TOL);
  59. }
  60. {
  61. ublas::vector<double> x(b);
  62. ublas::inplace_solve(x, A, ublas::lower_tag());
  63. BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::lower>(A)), x, b) < TOL);
  64. }
  65. {
  66. ublas::vector<double> x(b);
  67. ublas::inplace_solve(x, A, ublas::upper_tag());
  68. BOOST_UBLAS_TEST_CHECK(diff (trans(ublas::triangular_adaptor<mat, ublas::upper>(A)), x , b) < TOL);
  69. }
  70. }
  71. int main() {
  72. // typedefs are needed as macros do not work with "," in template arguments
  73. BOOST_UBLAS_TEST_BEGIN();
  74. #ifdef USE_MATRIX
  75. typedef ublas::matrix<double, ublas::row_major> mat_doub_rowmaj;
  76. typedef ublas::matrix<double, ublas::column_major> mat_doub_colmaj;
  77. BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_rowmaj> );
  78. BOOST_UBLAS_TEST_DO( test_inplace_solve<mat_doub_colmaj> );
  79. #endif
  80. #ifdef USE_COMPRESSED_MATRIX
  81. typedef ublas::compressed_matrix<double, ublas::row_major> commat_doub_rowmaj;
  82. typedef ublas::compressed_matrix<double, ublas::column_major> commat_doub_colmaj;
  83. BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_rowmaj> );
  84. BOOST_UBLAS_TEST_DO( test_inplace_solve<commat_doub_colmaj> );
  85. #endif
  86. #ifdef USE_MAPPED_MATRIX
  87. typedef ublas::mapped_matrix<double, ublas::row_major> mapmat_doub_rowmaj;
  88. typedef ublas::mapped_matrix<double, ublas::column_major> mapmat_doub_colmaj;
  89. BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_rowmaj> );
  90. BOOST_UBLAS_TEST_DO( test_inplace_solve<mapmat_doub_colmaj> );
  91. #endif
  92. #ifdef USE_COORDINATE_MATRIX
  93. typedef ublas::coordinate_matrix<double, ublas::row_major> cormat_doub_rowmaj;
  94. typedef ublas::coordinate_matrix<double, ublas::column_major> cormat_doub_colmaj;
  95. BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_rowmaj> );
  96. BOOST_UBLAS_TEST_DO( test_inplace_solve<cormat_doub_colmaj> );
  97. #endif
  98. #ifdef USE_MAPPED_VECTOR_OF_MAPPED_VECTOR
  99. typedef ublas::mapped_vector_of_mapped_vector<double, ublas::row_major> mvmv_doub_rowmaj;
  100. typedef ublas::mapped_vector_of_mapped_vector<double, ublas::column_major> mvmv_doub_colmaj;
  101. BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_rowmaj> );
  102. BOOST_UBLAS_TEST_DO( test_inplace_solve<mvmv_doub_colmaj> );
  103. #endif
  104. BOOST_UBLAS_TEST_END();
  105. }