bessel_errors_example.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright Christopher Kormanyos 2013.
  2. // Copyright Paul A. Bristow 2013.
  3. // Copyright John Maddock 2013.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or
  6. // copy at http://www.boost.org/LICENSE_1_0.txt).
  7. #ifdef _MSC_VER
  8. # pragma warning (disable : 4512) // assignment operator could not be generated.
  9. # pragma warning (disable : 4996) // assignment operator could not be generated.
  10. #endif
  11. #include <iostream>
  12. #include <limits>
  13. #include <vector>
  14. #include <algorithm>
  15. #include <iomanip>
  16. #include <exception>
  17. // Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
  18. // http://mathworld.wolfram.com/BesselFunctionZeros.html
  19. // Test values can be calculated using [@wolframalpha.com WolframAplha]
  20. // See also http://dlmf.nist.gov/10.21
  21. //[bessel_errors_example_1
  22. /*`[h5 Error messages from 'bad' input]
  23. Another example demonstrates calculating zeros of the Bessel functions
  24. showing the error messages from 'bad' input is handled by throwing exceptions.
  25. To use the functions for finding zeros of the functions we need:
  26. */
  27. #include <boost/math/special_functions/bessel.hpp>
  28. #include <boost/math/special_functions/airy.hpp>
  29. //] [/bessel_errors_example_1]
  30. int main()
  31. {
  32. //[bessel_errors_example_2
  33. /*`[tip It is always wise to place all code using Boost.Math inside try'n'catch blocks;
  34. this will ensure that helpful error messages can be shown when exceptional conditions arise.]
  35. Examples below show messages from several 'bad' arguments that throw a `domain_error` exception.
  36. */
  37. try
  38. { // Try a zero order v.
  39. float dodgy_root = boost::math::cyl_bessel_j_zero(0.F, 0);
  40. std::cout << "boost::math::cyl_bessel_j_zero(0.F, 0) " << dodgy_root << std::endl;
  41. // Thrown exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int):
  42. // Requested the 0'th zero of J0, but the rank must be > 0 !
  43. }
  44. catch (std::exception& ex)
  45. {
  46. std::cout << "Thrown exception " << ex.what() << std::endl;
  47. }
  48. /*`[note The type shown in the error message is the type [*after promotion],
  49. using __precision_policy and __promotion_policy, from `float` to `double` in this case.]
  50. In this example the promotion goes:
  51. # Arguments are `float` and `int`.
  52. # Treat `int` "as if" it were a `double`, so arguments are `float` and `double`.
  53. # Common type is `double` - so that's the precision we want (and the type that will be returned).
  54. # Evaluate internally as `double` for full `float` precision.
  55. See full code for other examples that promote from `double` to `long double`.
  56. Other examples of 'bad' inputs like infinity and NaN are below.
  57. Some compiler warnings indicate that 'bad' values are detected at compile time.
  58. */
  59. try
  60. { // order v = inf
  61. std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << std::endl;
  62. double inf = std::numeric_limits<double>::infinity();
  63. double inf_root = boost::math::cyl_bessel_j_zero(inf, 1);
  64. std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << inf_root << std::endl;
  65. // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
  66. // Order argument is 1.#INF, but must be finite >= 0 !
  67. }
  68. catch (std::exception& ex)
  69. {
  70. std::cout << "Thrown exception " << ex.what() << std::endl;
  71. }
  72. try
  73. { // order v = NaN, rank m = 1
  74. std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << std::endl;
  75. double nan = std::numeric_limits<double>::quiet_NaN();
  76. double nan_root = boost::math::cyl_bessel_j_zero(nan, 1);
  77. std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << nan_root << std::endl;
  78. // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
  79. // Order argument is 1.#QNAN, but must be finite >= 0 !
  80. }
  81. catch (std::exception& ex)
  82. {
  83. std::cout << "Thrown exception " << ex.what() << std::endl;
  84. }
  85. /*`The output from other examples are shown appended to the full code listing.
  86. */
  87. //] [/bessel_errors_example_2]
  88. try
  89. { // Try a zero rank m.
  90. std::cout << "boost::math::cyl_neumann_zero(0.0, 0) " << std::endl;
  91. double dodgy_root = boost::math::cyl_bessel_j_zero(0.0, 0);
  92. // warning C4146: unary minus operator applied to unsigned type, result still unsigned.
  93. std::cout << "boost::math::cyl_neumann_zero(0.0, -1) " << dodgy_root << std::endl;
  94. // boost::math::cyl_neumann_zero(0.0, -1) 6.74652e+009
  95. // This *should* fail because m is unreasonably large.
  96. }
  97. catch (std::exception& ex)
  98. {
  99. std::cout << "Thrown exception " << ex.what() << std::endl;
  100. }
  101. try
  102. { // m = inf
  103. std::cout << "boost::math::cyl_bessel_j_zero(0.0, inf) " << std::endl;
  104. double inf = std::numeric_limits<double>::infinity();
  105. double inf_root = boost::math::cyl_bessel_j_zero(0.0, inf);
  106. // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
  107. std::cout << "boost::math::cyl_bessel_j_zero(0.0, inf) " << inf_root << std::endl;
  108. // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int):
  109. // Requested the 0'th zero, but must be > 0 !
  110. }
  111. catch (std::exception& ex)
  112. {
  113. std::cout << "Thrown exception " << ex.what() << std::endl;
  114. }
  115. try
  116. { // m = NaN
  117. double nan = std::numeric_limits<double>::quiet_NaN();
  118. double nan_root = boost::math::airy_ai_zero<double>(nan);
  119. // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
  120. std::cout << "boost::math::airy_ai_zero<double>(nan) " << nan_root << std::endl;
  121. // Thrown exception Error in function boost::math::airy_ai_zero<double>(double,double):
  122. // The requested rank of the zero is 0, but must be 1 or more !
  123. }
  124. catch (std::exception& ex)
  125. {
  126. std::cout << "Thrown exception " << ex.what() << std::endl;
  127. }
  128. } // int main()
  129. /*
  130. Output:
  131. Description: Autorun "J:\Cpp\big_number\Debug\bessel_errors_example.exe"
  132. Thrown exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int): Requested the 0'th zero of J0, but the rank must be > 0 !
  133. boost::math::cyl_bessel_j_zero(inf, 1)
  134. Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#INF, but must be finite >= 0 !
  135. boost::math::cyl_bessel_j_zero(nan, 1)
  136. Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#QNAN, but must be finite >= 0 !
  137. boost::math::cyl_neumann_zero(0.0, 0)
  138. Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the 0'th zero of J0, but the rank must be > 0 !
  139. boost::math::cyl_bessel_j_zero(0.0, inf)
  140. Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the -2147483648'th zero, but the rank must be positive !
  141. Thrown exception Error in function boost::math::airy_ai_zero<double>(double,double): The requested rank of the zero is 0, but must be 1 or more !
  142. */