bessel_derivative_data.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (c) 2014 Anton Bikineev
  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. //
  6. // Computes test data for the derivatives of the
  7. // various bessel functions. Results of derivatives
  8. // are generated by the relations between the derivatives
  9. // and Bessel functions, which actual implementation
  10. // doesn't use. Results are printed to ~ 50 digits.
  11. //
  12. #include <fstream>
  13. #include <boost/multiprecision/mpfr.hpp>
  14. #include <boost/math/tools/test_data.hpp>
  15. #include <boost/test/included/prg_exec_monitor.hpp>
  16. #include <boost/math/special_functions/bessel.hpp>
  17. using namespace boost::math::tools;
  18. using namespace boost::math;
  19. using namespace std;
  20. using namespace boost::multiprecision;
  21. template <class T>
  22. T bessel_j_derivative_bare(T v, T x)
  23. {
  24. return (v / x) * boost::math::cyl_bessel_j(v, x) - boost::math::cyl_bessel_j(v+1, x);
  25. }
  26. template <class T>
  27. T bessel_y_derivative_bare(T v, T x)
  28. {
  29. return (v / x) * boost::math::cyl_neumann(v, x) - boost::math::cyl_neumann(v+1, x);
  30. }
  31. template <class T>
  32. T bessel_i_derivative_bare(T v, T x)
  33. {
  34. return (v / x) * boost::math::cyl_bessel_i(v, x) + boost::math::cyl_bessel_i(v+1, x);
  35. }
  36. template <class T>
  37. T bessel_k_derivative_bare(T v, T x)
  38. {
  39. return (v / x) * boost::math::cyl_bessel_k(v, x) - boost::math::cyl_bessel_k(v+1, x);
  40. }
  41. template <class T>
  42. T sph_bessel_j_derivative_bare(T v, T x)
  43. {
  44. if((v < 0) || (floor(v) != v))
  45. throw std::domain_error("");
  46. if(v == 0)
  47. return -boost::math::sph_bessel(1, x);
  48. return boost::math::sph_bessel(itrunc(v-1), x) - ((v + 1) / x) * boost::math::sph_bessel(itrunc(v), x);
  49. }
  50. template <class T>
  51. T sph_bessel_y_derivative_bare(T v, T x)
  52. {
  53. if((v < 0) || (floor(v) != v))
  54. throw std::domain_error("");
  55. if(v == 0)
  56. return -boost::math::sph_neumann(1, x);
  57. return boost::math::sph_neumann(itrunc(v-1), x) - ((v + 1) / x) * boost::math::sph_neumann(itrunc(v), x);
  58. }
  59. enum
  60. {
  61. func_J = 0,
  62. func_Y,
  63. func_I,
  64. func_K,
  65. func_j,
  66. func_y
  67. };
  68. int cpp_main(int argc, char*argv [])
  69. {
  70. typedef number<mpfr_float_backend<200> > bignum;
  71. parameter_info<bignum> arg1, arg2;
  72. test_data<bignum> data;
  73. int functype = 0;
  74. std::string letter = "J";
  75. if(argc == 2)
  76. {
  77. if(std::strcmp(argv[1], "--Y") == 0)
  78. {
  79. functype = func_Y;
  80. letter = "Y";
  81. }
  82. else if(std::strcmp(argv[1], "--I") == 0)
  83. {
  84. functype = func_I;
  85. letter = "I";
  86. }
  87. else if(std::strcmp(argv[1], "--K") == 0)
  88. {
  89. functype = func_K;
  90. letter = "K";
  91. }
  92. else if(std::strcmp(argv[1], "--j") == 0)
  93. {
  94. functype = func_j;
  95. letter = "j";
  96. }
  97. else if(std::strcmp(argv[1], "--y") == 0)
  98. {
  99. functype = func_y;
  100. letter = "y";
  101. }
  102. else
  103. BOOST_ASSERT(0);
  104. }
  105. bool cont;
  106. std::string line;
  107. std::cout << "Welcome.\n"
  108. "This program will generate spot tests for the Bessel " << letter << " function derivative\n\n";
  109. do{
  110. if(0 == get_user_parameter_info(arg1, "a"))
  111. return 1;
  112. if(0 == get_user_parameter_info(arg2, "b"))
  113. return 1;
  114. bignum (*fp)(bignum, bignum) = 0;
  115. if(functype == func_J)
  116. fp = bessel_j_derivative_bare;
  117. else if(functype == func_I)
  118. fp = bessel_i_derivative_bare;
  119. else if(functype == func_K)
  120. fp = bessel_k_derivative_bare;
  121. else if(functype == func_Y)
  122. fp = bessel_y_derivative_bare;
  123. else if(functype == func_j)
  124. fp = sph_bessel_j_derivative_bare;
  125. else if(functype == func_y)
  126. fp = sph_bessel_y_derivative_bare;
  127. else
  128. BOOST_ASSERT(0);
  129. data.insert(fp, arg2, arg1);
  130. std::cout << "Any more data [y/n]?";
  131. std::getline(std::cin, line);
  132. boost::algorithm::trim(line);
  133. cont = (line == "y");
  134. }while(cont);
  135. std::cout << "Enter name of test data file [default=bessel_j_derivative_data.ipp]";
  136. std::getline(std::cin, line);
  137. boost::algorithm::trim(line);
  138. if(line == "")
  139. line = "bessel_j_derivative_data.ipp";
  140. std::ofstream ofs(line.c_str());
  141. line.erase(line.find('.'));
  142. ofs << std::scientific << std::setprecision(50);
  143. write_code(ofs, data, line.c_str());
  144. return 0;
  145. }