solve.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // (C) Copyright John Maddock 2006.
  2. // Use, modification and distribution are subject to the
  3. // Boost 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. #ifndef BOOST_MATH_TOOLS_SOLVE_HPP
  6. #define BOOST_MATH_TOOLS_SOLVE_HPP
  7. #ifdef _MSC_VER
  8. #pragma once
  9. #endif
  10. #include <boost/config.hpp>
  11. #include <boost/assert.hpp>
  12. #ifdef BOOST_MSVC
  13. #pragma warning(push)
  14. #pragma warning(disable:4996 4267 4244)
  15. #endif
  16. #include <boost/numeric/ublas/lu.hpp>
  17. #include <boost/numeric/ublas/matrix.hpp>
  18. #include <boost/numeric/ublas/vector.hpp>
  19. #ifdef BOOST_MSVC
  20. #pragma warning(pop)
  21. #endif
  22. namespace boost{ namespace math{ namespace tools{
  23. //
  24. // Find x such that Ax = b
  25. //
  26. // Caution: this uses undocumented, and untested ublas code,
  27. // however short of writing our own LU-decompostion code
  28. // it's the only game in town.
  29. //
  30. template <class T>
  31. boost::numeric::ublas::vector<T> solve(
  32. const boost::numeric::ublas::matrix<T>& A_,
  33. const boost::numeric::ublas::vector<T>& b_)
  34. {
  35. //BOOST_ASSERT(A_.size() == b_.size());
  36. boost::numeric::ublas::matrix<T> A(A_);
  37. boost::numeric::ublas::vector<T> b(b_);
  38. boost::numeric::ublas::permutation_matrix<> piv(b.size());
  39. lu_factorize(A, piv);
  40. lu_substitute(A, piv, b);
  41. //
  42. // iterate to reduce error:
  43. //
  44. boost::numeric::ublas::vector<T> delta(b.size());
  45. for(unsigned i = 0; i < 1; ++i)
  46. {
  47. noalias(delta) = prod(A_, b);
  48. delta -= b_;
  49. lu_substitute(A, piv, delta);
  50. b -= delta;
  51. T max_error = 0;
  52. for(unsigned i = 0; i < delta.size(); ++i)
  53. {
  54. T err = fabs(delta[i] / b[i]);
  55. if(err > max_error)
  56. max_error = err;
  57. }
  58. //std::cout << "Max change in LU error correction: " << max_error << std::endl;
  59. }
  60. return b;
  61. }
  62. }}} // namespaces
  63. #endif // BOOST_MATH_TOOLS_SOLVE_HPP