Subversion Repositories programming

Rev

Rev 145 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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