• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 // Copyright Christopher Kormanyos 2013.
3 // Copyright Paul A. Bristow 2013.
4 // Copyright John Maddock 2013.
5 
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or
8 // copy at http://www.boost.org/LICENSE_1_0.txt).
9 
10 #ifdef _MSC_VER
11 #  pragma warning (disable : 4512) // assignment operator could not be generated.
12 #  pragma warning (disable : 4996) // assignment operator could not be generated.
13 #endif
14 
15 #include <iostream>
16 #include <limits>
17 #include <vector>
18 #include <algorithm>
19 #include <iomanip>
20 #include <iterator>
21 
22 // Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
23 // http://mathworld.wolfram.com/BesselFunctionZeros.html
24 // Test values can be calculated using [@wolframalpha.com WolframAplha]
25 // See also http://dlmf.nist.gov/10.21
26 
27 //[airy_zeros_example_1
28 
29 /*`This example demonstrates calculating zeros of the Airy functions.
30 It also shows how Boost.Math and Boost.Multiprecision can be combined to provide
31 a many decimal digit precision. For 50 decimal digit precision we need to include
32 */
33 
34   #include <boost/multiprecision/cpp_dec_float.hpp>
35 
36 /*`and a `typedef` for `float_type` may be convenient
37 (allowing a quick switch to re-compute at built-in `double` or other precision)
38 */
39   typedef boost::multiprecision::cpp_dec_float_50 float_type;
40 
41 //`To use the functions for finding zeros of the functions we need
42 
43   #include <boost/math/special_functions/airy.hpp>
44 
45 /*`This example shows obtaining both a single zero of the Airy functions,
46 and then placing multiple zeros into a container like `std::vector` by providing an iterator.
47 The signature of the single-value Airy Ai function is:
48 
49   template <class T>
50   T airy_ai_zero(unsigned m); // 1-based index of the zero.
51 
52 The signature of multiple zeros Airy Ai function is:
53 
54   template <class T, class OutputIterator>
55   OutputIterator airy_ai_zero(
56                            unsigned start_index, // 1-based index of the zero.
57                            unsigned number_of_zeros, // How many zeros to generate.
58                            OutputIterator out_it); // Destination for zeros.
59 
60 There are also versions which allows control of the __policy_section for error handling and precision.
61 
62   template <class T, class OutputIterator, class Policy>
63   OutputIterator airy_ai_zero(
64                            unsigned start_index, // 1-based index of the zero.
65                            unsigned number_of_zeros, // How many zeros to generate.
66                            OutputIterator out_it, // Destination for zeros.
67                            const Policy& pol);  // Policy to use.
68 */
69 //] [/airy_zeros_example_1]
70 
main()71 int main()
72 {
73   try
74   {
75 //[airy_zeros_example_2
76 
77 /*`[tip It is always wise to place code using Boost.Math inside `try'n'catch` blocks;
78 this will ensure that helpful error messages are shown when exceptional conditions arise.]
79 
80 First, evaluate a single Airy zero.
81 
82 The precision is controlled by the template parameter `T`,
83 so this example has `double` precision, at least 15 but up to 17 decimal digits
84 (for the common 64-bit double).
85 */
86     double aiz1 = boost::math::airy_ai_zero<double>(1);
87     std::cout << "boost::math::airy_ai_zero<double>(1) = " << aiz1 << std::endl;
88     double aiz2 = boost::math::airy_ai_zero<double>(2);
89     std::cout << "boost::math::airy_ai_zero<double>(2) = " << aiz2 << std::endl;
90     double biz3 = boost::math::airy_bi_zero<double>(3);
91     std::cout << "boost::math::airy_bi_zero<double>(3) = " << biz3 << std::endl;
92 
93 /*`Other versions of `airy_ai_zero` and `airy_bi_zero`
94 allow calculation of multiple zeros with one call,
95 placing the results in a container, often `std::vector`.
96 For example, generate and display the first five `double` roots
97 [@http://mathworld.wolfram.com/AiryFunctionZeros.html Wolfram Airy Functions Zeros].
98 */
99     unsigned int n_roots = 5U;
100     std::vector<double> roots;
101     boost::math::airy_ai_zero<double>(1U, n_roots, std::back_inserter(roots));
102     std::cout << "airy_ai_zeros:" << std::endl;
103     std::copy(roots.begin(),
104               roots.end(),
105               std::ostream_iterator<double>(std::cout, "\n"));
106 
107 /*`The first few real roots of Ai(x) are approximately -2.33811, -4.08795, -5.52056, -6.7867144, -7.94413, -9.02265 ...
108 
109 Or we can use Boost.Multiprecision to generate 50 decimal digit roots.
110 
111 We set the precision of the output stream, and show trailing zeros to display a fixed 50 decimal digits.
112 */
113     std::cout.precision(std::numeric_limits<float_type>::digits10); // float_type has 50 decimal digits.
114     std::cout << std::showpoint << std::endl; // Show trailing zeros too.
115 
116     unsigned int m = 1U;
117     float_type r = boost::math::airy_ai_zero<float_type>(1U); // 1st root.
118     std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ")  = " << r << std::endl;
119     m = 2;
120     r = boost::math::airy_ai_zero<float_type>(2U); // 2nd root.
121     std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ")  = " << r << std::endl;
122     m = 7U;
123     r = boost::math::airy_bi_zero<float_type>(7U); // 7th root.
124     std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ")  = " << r << std::endl;
125 
126     std::vector<float_type> zeros;
127     boost::math::airy_ai_zero<float_type>(1U, 3, std::back_inserter(zeros));
128     std::cout << "airy_ai_zeros:" << std::endl;
129     // Print the roots to the output stream.
130     std::copy(zeros.begin(), zeros.end(),
131               std::ostream_iterator<float_type>(std::cout, "\n"));
132 //] [/airy_zeros_example_2]
133   }
134   catch (std::exception ex)
135   {
136     std::cout << "Thrown exception " << ex.what() << std::endl;
137   }
138 
139  } // int main()
140 
141 /*
142 
143  Output:
144 
145   Description: Autorun "J:\Cpp\big_number\Debug\airy_zeros_example.exe"
146   boost::math::airy_ai_zero<double>(1) = -2.33811
147   boost::math::airy_ai_zero<double>(2) = -4.08795
148   boost::math::airy_bi_zero<double>(3) = -4.83074
149   airy_ai_zeros:
150   -2.33811
151   -4.08795
152   -5.52056
153   -6.78671
154   -7.94413
155 
156   boost::math::airy_bi_zero<float_type>(1)  = -2.3381074104597670384891972524467354406385401456711
157   boost::math::airy_bi_zero<float_type>(2)  = -4.0879494441309706166369887014573910602247646991085
158   boost::math::airy_bi_zero<float_type>(7)  = -9.5381943793462388866329885451560196208390720763825
159   airy_ai_zeros:
160   -2.3381074104597670384891972524467354406385401456711
161   -4.0879494441309706166369887014573910602247646991085
162   -5.5205598280955510591298555129312935737972142806175
163 
164 */
165 
166