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