legendre_stieltjes_example.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright Nick Thompson 2017.
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <iostream>
  7. #include <string>
  8. #include <boost/math/constants/constants.hpp>
  9. #include <boost/multiprecision/cpp_bin_float.hpp>
  10. #include <boost/multiprecision/cpp_dec_float.hpp>
  11. #include <boost/math/special_functions/legendre_stieltjes.hpp>
  12. using boost::math::legendre_p;
  13. using boost::math::legendre_p_zeros;
  14. using boost::math::legendre_p_prime;
  15. using boost::math::legendre_stieltjes;
  16. using boost::multiprecision::cpp_bin_float_quad;
  17. using boost::multiprecision::cpp_bin_float_100;
  18. using boost::multiprecision::cpp_dec_float_100;
  19. template<class Real>
  20. void gauss_kronrod_rule(size_t order)
  21. {
  22. std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
  23. std::cout << std::fixed;
  24. auto gauss_nodes = boost::math::legendre_p_zeros<Real>(order);
  25. auto E = legendre_stieltjes<Real>(order + 1);
  26. std::vector<Real> gauss_weights(gauss_nodes.size(), std::numeric_limits<Real>::quiet_NaN());
  27. std::vector<Real> gauss_kronrod_weights(gauss_nodes.size(), std::numeric_limits<Real>::quiet_NaN());
  28. for (size_t i = 0; i < gauss_nodes.size(); ++i)
  29. {
  30. Real node = gauss_nodes[i];
  31. Real lp = legendre_p_prime<Real>(order, node);
  32. gauss_weights[i] = 2/( (1-node*node)*lp*lp);
  33. // P_n(x) = (2n)!/(2^n (n!)^2) pi_n(x), where pi_n is the monic Legendre polynomial.
  34. gauss_kronrod_weights[i] = gauss_weights[i] + static_cast<Real>(2)/(static_cast<Real>(order+1)*legendre_p_prime(order, node)*E(node));
  35. }
  36. std::cout << "static const std::vector<Real> gauss_nodes {\n";
  37. for (auto const & node : gauss_nodes)
  38. {
  39. std::cout << " boost::lexical_cast<Real>(\"" << node << "\"),\n";
  40. }
  41. std::cout << "};\n\n";
  42. std::cout << "static const std::vector<Real> gauss_weights {\n";
  43. for (auto const & weight : gauss_weights)
  44. {
  45. std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
  46. }
  47. std::cout << "};\n\n";
  48. std::cout << "static const std::vector<Real> gauss_kronrod_weights {\n";
  49. for (auto const & weight : gauss_kronrod_weights)
  50. {
  51. std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
  52. }
  53. std::cout << "};\n\n";
  54. auto kronrod_nodes = E.zeros();
  55. std::vector<Real> kronrod_weights(kronrod_nodes.size());
  56. for (size_t i = 0; i < kronrod_weights.size(); ++i)
  57. {
  58. Real node = kronrod_nodes[i];
  59. kronrod_weights[i] = static_cast<Real>(2)/(static_cast<Real>(order+1)*legendre_p(order, node)*E.prime(node));
  60. }
  61. std::cout << "static const std::vector<Real> kronrod_nodes {\n";
  62. for (auto node : kronrod_nodes)
  63. {
  64. std::cout << " boost::lexical_cast<Real>(\"" << node << "\"),\n";
  65. }
  66. std::cout << "};\n\n";
  67. std::cout << "static const std::vector<Real> kronrod_weights {\n";
  68. for (auto const & weight : kronrod_weights)
  69. {
  70. std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
  71. }
  72. std::cout << "};\n\n";
  73. }
  74. int main()
  75. {
  76. //std::cout << "Gauss-Kronrod 7-15 Rule:\n";
  77. //gauss_kronrod_rule<cpp_dec_float_100>(7);
  78. //std::cout << "\n\nGauss-Kronrod 10-21 Rule:\n";
  79. //gauss_kronrod_rule<cpp_dec_float_100>(10);
  80. std::cout << "\n\nGauss-Kronrod 15-31 Rule:\n";
  81. gauss_kronrod_rule<cpp_dec_float_100>(15);
  82. /*
  83. std::cout << "\n\nGauss-Kronrod 20-41 Rule:\n";
  84. gauss_kronrod_rule<cpp_dec_float_100>(20);
  85. std::cout << "\n\nGauss-Kronrod 25-51 Rule:\n";
  86. gauss_kronrod_rule<cpp_dec_float_100>(25);
  87. std::cout << "\n\nGauss-Kronrod 30-61 Rule:\n";
  88. gauss_kronrod_rule<cpp_dec_float_100>(30);
  89. std::cout << "\n\nGauss-Kronrod 35-71 Rule:\n";
  90. gauss_kronrod_rule<cpp_dec_float_100>(35);
  91. std::cout << "\n\nGauss-Kronrod 40-81 Rule:\n";
  92. gauss_kronrod_rule<cpp_dec_float_100>(40);*/
  93. }