| 144 |
ira |
1 |
#include <iostream>
|
|
|
2 |
#include <iomanip>
|
|
|
3 |
#include <cmath>
|
|
|
4 |
using namespace std;
|
|
|
5 |
|
|
|
6 |
enum {IDX0, IDX1, IDX5, IDX10, IDX15, IDX19, IDX20};
|
|
|
7 |
|
|
|
8 |
#define ARRAY_SIZE 21
|
|
|
9 |
float x1_const[7] = { 1.266065978, 5.651591040E-01, 2.714631560E-04,
|
|
|
10 |
2.752948040E-10, 2.370463051E-17, 1.587678369E-23,
|
|
|
11 |
3.966835986E-25 };
|
|
|
12 |
|
|
|
13 |
float x2_const[7] = { 2.279585302, 1.590636855, 9.825679323E-03,
|
|
|
14 |
3.016963879E-07, 8.139432531E-13, 8.641603385E-18,
|
|
|
15 |
4.310560576E-19 };
|
|
|
16 |
|
|
|
17 |
float x5_const[7] = { 2.723987182E+01, 2.433564214E+01, 2.157974547,
|
|
|
18 |
4.580044419E-03, 1.047977675E-6 , 4.078415017E-10,
|
|
|
19 |
5.024239358E-11 };
|
|
|
20 |
|
|
|
21 |
/* Copied from the Project #2 Handout.
|
|
|
22 |
*
|
|
|
23 |
* FOR TESTING ONLY
|
|
|
24 |
*/
|
|
|
25 |
float Bessel_Recursive_BU (int n, float x, float base0, float base1)
|
|
|
26 |
{
|
|
|
27 |
if (n == 0)
|
|
|
28 |
return base0;
|
|
|
29 |
else if (n == 1)
|
|
|
30 |
return base1;
|
|
|
31 |
|
|
|
32 |
return Bessel_Recursive_BU (n-2, x, base0, base1)
|
|
|
33 |
+ 2.0F * (float)(n-1) * Bessel_Recursive_BU (n-1, x, base0, base1) / x;
|
|
|
34 |
}
|
|
|
35 |
|
|
|
36 |
float Bessel_Recursive_TD (int n, float x, float base19, float base20)
|
|
|
37 |
{
|
|
|
38 |
if (n == 19)
|
|
|
39 |
return base19;
|
|
|
40 |
else if (n == 20)
|
|
|
41 |
return base20;
|
|
|
42 |
|
|
|
43 |
return (2.0F * (float)(n+1) / x) * Bessel_Recursive_TD (n+1, x, base19, base20)
|
|
|
44 |
+ Bessel_Recursive_TD (n+2, x, base19, base20);
|
|
|
45 |
}
|
|
|
46 |
|
|
|
47 |
|
|
|
48 |
/* Find the Bessel Function.
|
|
|
49 |
* Algorithm: I[n+1](x) = I[n-1](x) - (2*n/x) * I[n](x)
|
|
|
50 |
* Which is equvalent to: I[n](x) = I[n-2](x) - (2 * (n-1)/x) * I[n-1](x)
|
|
|
51 |
* by simple substitution.
|
|
|
52 |
*
|
|
|
53 |
* This is the recurrence relation for PART #1.
|
|
|
54 |
*/
|
|
|
55 |
float Bessel_BottomUp (int n, float x, float base0, float base1)
|
|
|
56 |
{
|
|
|
57 |
int i = 0;
|
|
|
58 |
float answer;
|
|
|
59 |
float *storage = new float[ARRAY_SIZE];
|
|
|
60 |
|
|
|
61 |
// Prime the array
|
|
|
62 |
storage[0] = base0;
|
|
|
63 |
storage[1] = base1;
|
|
|
64 |
|
|
|
65 |
// Calculate each value in turn
|
|
|
66 |
for (i=2; i<=20; i++)
|
|
|
67 |
storage[i] = storage[i-2] - (2.0 * (n-1) / x) * storage[i-1];
|
|
|
68 |
|
|
|
69 |
// Store the answer, delete the memory
|
|
|
70 |
answer = storage[n];
|
|
|
71 |
delete[] storage;
|
|
|
72 |
|
|
|
73 |
// Return the result
|
|
|
74 |
return answer;
|
|
|
75 |
}
|
|
|
76 |
|
|
|
77 |
/* Find the Bessel Function, from the Top -> Down.
|
|
|
78 |
* Algorithm: I[n-1](x) = (2*n/x)*I[n](x) + I[n+1](x)
|
|
|
79 |
* Which is equivalent to: I[n](x) = (2 * (n+1) / x) * I[n+1](x) + I[n+2](x)
|
|
|
80 |
* by simple substitution.
|
|
|
81 |
*
|
|
|
82 |
* This is the recurrence relation for PART #2.
|
|
|
83 |
*/
|
|
|
84 |
float Bessel_TopDown (int n, float x, float base19, float base20)
|
|
|
85 |
{
|
|
|
86 |
int i = 18;
|
|
|
87 |
float answer;
|
|
|
88 |
float *storage = new float[ARRAY_SIZE];
|
|
|
89 |
|
|
|
90 |
// Prime the array
|
|
|
91 |
storage[20] = base20;
|
|
|
92 |
storage[19] = base19;
|
|
|
93 |
|
|
|
94 |
// Calculate each value in turn
|
|
|
95 |
for (i=18; i>=0; i--)
|
|
|
96 |
storage[i] = (2.0 * (n+1) / x) * storage[i+1] + storage[i+2];
|
|
|
97 |
|
|
|
98 |
// Store the answer, free the memory
|
|
|
99 |
answer = storage[n];
|
|
|
100 |
delete[] storage;
|
|
|
101 |
|
|
|
102 |
// Return the result
|
|
|
103 |
return answer;
|
|
|
104 |
}
|
|
|
105 |
|
|
|
106 |
/* Print out a table for a given x value, and function.
|
|
|
107 |
* Call like this: print_table (1.0, &BesselFunc);
|
|
|
108 |
*
|
|
|
109 |
* It chooses the correct constants appropriately.
|
|
|
110 |
*/
|
|
|
111 |
void print_table (float x, float (*bessel_func)(int, float, float, float))
|
|
|
112 |
{
|
|
|
113 |
int n;
|
|
|
114 |
float base0, base1, base19, base20;
|
|
|
115 |
float true_val, calc_val, abs_err, rel_err;
|
|
|
116 |
float *constants;
|
|
|
117 |
|
|
|
118 |
if (x == 1.0)
|
|
|
119 |
constants = x1_const;
|
|
|
120 |
|
|
|
121 |
if (x == 2.0)
|
|
|
122 |
constants = x2_const;
|
|
|
123 |
|
|
|
124 |
if (x == 5.0)
|
|
|
125 |
constants = x5_const;
|
|
|
126 |
|
|
|
127 |
// Set the output flags
|
|
|
128 |
cout << setiosflags (ios_base::scientific | ios_base::showpoint);
|
|
|
129 |
|
|
|
130 |
// Print the table header
|
|
|
131 |
cout << setw(10) << "n Val."
|
|
|
132 |
<< setw(20) << "TRUE"
|
|
|
133 |
<< setw(20) << "COMPUTED"
|
|
|
134 |
<< setw(20) << "ABS ERROR"
|
|
|
135 |
<< setw(20) << "REL ERROR"
|
|
|
136 |
<< endl;
|
|
|
137 |
|
|
|
138 |
// A line of equal signs
|
|
|
139 |
for (n=0; n<(20+20+20+20+10); n++)
|
|
|
140 |
cout << "=";
|
|
|
141 |
|
|
|
142 |
cout << endl;
|
|
|
143 |
|
|
|
144 |
// Print out the line for n = 5
|
|
|
145 |
n = 5;
|
|
|
146 |
true_val = constants[IDX5];
|
|
|
147 |
calc_val = bessel_func(n, x, constants[IDX0], constants[IDX1]);
|
|
|
148 |
abs_err = abs (true_val - calc_val);
|
|
|
149 |
rel_err = abs_err / abs (true_val);
|
|
|
150 |
|
|
|
151 |
cout << setw(10) << n
|
|
|
152 |
<< setw(20) << true_val
|
|
|
153 |
<< setw(20) << calc_val
|
|
|
154 |
<< setw(20) << abs_err
|
|
|
155 |
<< setw(20) << rel_err
|
|
|
156 |
<< endl;
|
|
|
157 |
|
|
|
158 |
// Print out the line for n = 10
|
|
|
159 |
n = 10;
|
|
|
160 |
true_val = constants[IDX10];
|
|
|
161 |
calc_val = bessel_func(n, x, constants[IDX0], constants[IDX1]);
|
|
|
162 |
abs_err = abs (true_val - calc_val);
|
|
|
163 |
rel_err = abs_err / abs (true_val);
|
|
|
164 |
|
|
|
165 |
cout << setw(10) << n
|
|
|
166 |
<< setw(20) << true_val
|
|
|
167 |
<< setw(20) << calc_val
|
|
|
168 |
<< setw(20) << abs_err
|
|
|
169 |
<< setw(20) << rel_err
|
|
|
170 |
<< endl;
|
|
|
171 |
|
|
|
172 |
// Print out the line for n = 15
|
|
|
173 |
n = 15;
|
|
|
174 |
true_val = constants[IDX15];
|
|
|
175 |
calc_val = bessel_func(n, x, constants[IDX0], constants[IDX1]);
|
|
|
176 |
abs_err = abs (true_val - calc_val);
|
|
|
177 |
rel_err = abs_err / abs (true_val);
|
|
|
178 |
|
|
|
179 |
cout << setw(10) << n
|
|
|
180 |
<< setw(20) << true_val
|
|
|
181 |
<< setw(20) << calc_val
|
|
|
182 |
<< setw(20) << abs_err
|
|
|
183 |
<< setw(20) << rel_err
|
|
|
184 |
<< endl;
|
|
|
185 |
|
|
|
186 |
// Print out the line for n = 20
|
|
|
187 |
n = 20;
|
|
|
188 |
true_val = constants[IDX20];
|
|
|
189 |
calc_val = bessel_func(n, x, constants[IDX0], constants[IDX1]);
|
|
|
190 |
abs_err = abs (true_val - calc_val);
|
|
|
191 |
rel_err = abs_err / abs (true_val);
|
|
|
192 |
|
|
|
193 |
cout << setw(10) << n
|
|
|
194 |
<< setw(20) << true_val
|
|
|
195 |
<< setw(20) << calc_val
|
|
|
196 |
<< setw(20) << abs_err
|
|
|
197 |
<< setw(20) << rel_err
|
|
|
198 |
<< endl;
|
|
|
199 |
}
|
|
|
200 |
|
|
|
201 |
int main (void)
|
|
|
202 |
{
|
|
|
203 |
print_table (1.0, &Bessel_BottomUp);
|
|
|
204 |
cout << endl;
|
|
|
205 |
print_table (2.0, &Bessel_BottomUp);
|
|
|
206 |
cout << endl;
|
|
|
207 |
print_table (5.0, &Bessel_BottomUp);
|
|
|
208 |
cout << endl;
|
|
|
209 |
|
|
|
210 |
|
|
|
211 |
return 0;
|
|
|
212 |
}
|
|
|
213 |
|