Subversion Repositories programming

Rev

Rev 146 | Go to most recent revision | Details | Compare with Previous | 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
 
147 ira 6
// Global Variables
7
enum {IDX0, IDX1, IDX5, IDX10, IDX15, IDX19, IDX20}; // Constants' Indices
144 ira 8
 
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
 
147 ira 21
// Global Defines
22
#define ARRAY_SIZE 21
23
 
24
// Function Prototypes
25
float Bessel_BottomUp (int n, float x, float *constants);
26
float Bessel_TopDown (int n, float x, float *constants);
27
void print_table_bottomup (float x);
28
void print_table_topdown (float x);
29
void print_equals (int num);
30
 
144 ira 31
/* Find the Bessel Function.
32
 * Algorithm: I[n+1](x) = I[n-1](x) - (2*n/x) * I[n](x)
33
 * Which is equvalent to: I[n](x) = I[n-2](x) - (2 * (n-1)/x) * I[n-1](x)
34
 * by simple substitution.
35
 *
36
 * This is the recurrence relation for PART #1.
37
 */
145 ira 38
float Bessel_BottomUp (int n, float x, float *constants)
144 ira 39
{
40
    int i = 0;
41
    float  answer;
42
    float *storage = new float[ARRAY_SIZE];
43
 
44
    // Prime the array
145 ira 45
    storage[0] = constants[IDX0];
46
    storage[1] = constants[IDX1];
144 ira 47
 
48
    // Calculate each value in turn
147 ira 49
    for (i=2; i<=n; i++)
144 ira 50
        storage[i] = storage[i-2] - (2.0 * (n-1) / x) * storage[i-1];
51
 
52
    // Store the answer, delete the memory
53
    answer = storage[n];
54
    delete[] storage;
55
 
56
    // Return the result
57
    return answer;
58
}
59
 
60
/* Find the Bessel Function, from the Top -> Down.
61
 * Algorithm: I[n-1](x) = (2*n/x)*I[n](x) + I[n+1](x)
62
 * Which is equivalent to: I[n](x) = (2 * (n+1) / x) * I[n+1](x) + I[n+2](x)
63
 * by simple substitution.
64
 *
65
 * This is the recurrence relation for PART #2.
66
 */
145 ira 67
float Bessel_TopDown (int n, float x, float *constants)
144 ira 68
{
69
    int i = 18;
70
    float answer;
71
    float *storage = new float[ARRAY_SIZE];
72
 
73
    // Prime the array
145 ira 74
    storage[20] = constants[IDX20];
75
    storage[19] = constants[IDX19];
144 ira 76
 
77
    // Calculate each value in turn
147 ira 78
    for (i=18; i>=n; i--)
144 ira 79
        storage[i] = (2.0 * (n+1) / x) * storage[i+1] + storage[i+2];
80
 
81
    // Store the answer, free the memory
82
    answer = storage[n];
83
    delete[] storage;
84
 
85
    // Return the result
86
    return answer;
87
}
88
 
89
/* Print out a table for a given x value, and function.
90
 * Call like this: print_table (1.0, &BesselFunc);
91
 *
92
 * It chooses the correct constants appropriately.
93
 */
147 ira 94
void print_table_bottomup (float x)
144 ira 95
{
147 ira 96
    int n, tblwidth = 6+16+16+16+16+16+20;
97
    float true_val, calc_val, abs_err, rel_err, part1, part2;
144 ira 98
    float *constants;
99
 
145 ira 100
    if (x == 1.0) constants = x1_const;
101
    if (x == 2.0) constants = x2_const;
102
    if (x == 5.0) constants = x5_const;
144 ira 103
 
147 ira 104
    // Reset the output flags
105
    cout << resetiosflags (ios_base::scientific | ios_base::showpoint);
144 ira 106
 
145 ira 107
    // A line of equal signs
147 ira 108
    print_equals (tblwidth);
145 ira 109
 
110
    // Print the x value we're using
147 ira 111
    cout << "Using x = " << x
112
         << "          "
113
         << "Working Bottom-up" << endl;
145 ira 114
 
147 ira 115
    // Set the output flags we're using
116
    cout << setiosflags (ios_base::scientific | ios_base::showpoint);
117
 
144 ira 118
    // Print the table header
147 ira 119
    cout << setw(6) << "n Val."
120
         << setw(16) << "TRUE VAL"
121
         << setw(16) << "COMPUTED"
122
         << setw(16) << "ABS ERROR"
123
         << setw(16) << "REL ERROR"
124
         << setw(16) << "I[n-2](x)"
125
         << setw(20) << "(2(n-1)/x)I[n-1](x)"
126
         << setw(16) << "IraVal"
144 ira 127
         << endl;
128
 
129
    // A line of equal signs
147 ira 130
    print_equals (tblwidth);
144 ira 131
 
145 ira 132
    // Run once for n = 5,10,15,20
133
    for (n=5; n<=20; n+=5)
134
    {
135
        if (n==5 ) true_val = constants[IDX5];
136
        if (n==10) true_val = constants[IDX10];
137
        if (n==15) true_val = constants[IDX15];
138
        if (n==20) true_val = constants[IDX20];
144 ira 139
 
147 ira 140
        calc_val = Bessel_BottomUp(n, x, constants);
145 ira 141
        abs_err  = abs (true_val - calc_val);
142
        rel_err  = abs_err / abs (true_val);
147 ira 143
        part1    = Bessel_BottomUp(n-2, x, constants);
144
        part2    = (2.0 * (n-1) / x) * Bessel_BottomUp(n-1, x, constants);
144 ira 145
 
147 ira 146
        cout << setw(6) << n
147
             << setw(16) << true_val
148
             << setw(16) << calc_val
149
             << setw(16) << abs_err
150
             << setw(16) << rel_err
151
             << setw(16) << part1
152
             << setw(20) << part2
153
             << setw(16) << part1 - part2
145 ira 154
             << endl;
155
    }
146 ira 156
 
157
    cout << endl;
144 ira 158
}
159
 
147 ira 160
void print_table_topdown (float x)
161
{
162
    int n, tblwidth = 6+16+16+16+16+16+20;
163
    float true_val, calc_val, abs_err, rel_err, part1, part2;
164
    float *constants;
165
    bool done = false;
166
 
167
    if (x == 1.0) constants = x1_const;
168
    if (x == 2.0) constants = x2_const;
169
    if (x == 5.0) constants = x5_const;
170
 
171
    // Reset the output flags
172
    cout << resetiosflags (ios_base::scientific | ios_base::showpoint);
173
 
174
    // A line of equal signs
175
    print_equals (tblwidth);
176
 
177
    // Print the x value we're using
178
    cout << "Using x = " << x
179
         << "          "
180
         << "Working Top-down" << endl;
181
 
182
    // Set the output flags we're using
183
    cout << setiosflags (ios_base::scientific | ios_base::showpoint);
184
 
185
    // Print the table header
186
    cout << setw(6) << "n Val."
187
         << setw(16) << "TRUE VAL"
188
         << setw(16) << "COMPUTED"
189
         << setw(16) << "ABS ERROR"
190
         << setw(16) << "REL ERROR"
191
         << setw(16) << "I[n+2](x)"
192
         << setw(20) << "(2(n+1)/x)I[n+1](x)"
193
         << setw(16) << "IraVal"
194
         << endl;
195
 
196
    // A line of equal signs
197
    print_equals (tblwidth);
198
 
199
    n = 0;
200
    // Run once for n = 0,1,5,10,15
201
    while (!done)
202
    {
203
        switch (n)
204
        {
205
            case 0:  true_val = constants[IDX0];  break;
206
            case 1:  true_val = constants[IDX1];  break;
207
            case 5:  true_val = constants[IDX5];  break;
208
            case 10: true_val = constants[IDX10]; break;
209
            case 15: true_val = constants[IDX15]; break;
210
        }
211
 
212
        calc_val = Bessel_TopDown(n, x, constants);
213
        abs_err  = abs (true_val - calc_val);
214
        rel_err  = abs_err / abs (true_val);
215
        part1    = Bessel_TopDown(n+2, x, constants);
216
        part2    = (2.0 * (n+1) / x) * Bessel_TopDown(n+1, x, constants);
217
 
218
        cout << setw(6) << n
219
             << setw(16) << true_val
220
             << setw(16) << calc_val
221
             << setw(16) << abs_err
222
             << setw(16) << rel_err
223
             << setw(16) << part1
224
             << setw(20) << part2
225
             << setw(16) << (part1 + part2)
226
             << endl;
227
 
228
        switch (n) // Set n for the next loop
229
        {
230
            case 0:  n = 1;  break;
231
            case 1:  n = 5;  break;
232
            case 5:  n = 10; break;
233
            case 10: n = 15; break;
234
            case 15: done = true; break;
235
        }
236
    }
237
 
238
    cout << endl;
239
}
240
 
241
void print_equals (int num)
242
{
243
    int i;
244
 
245
    for (i=0; i<num; i++)
246
        cout << "=";
247
 
248
    cout << endl;
249
}
250
 
144 ira 251
int main (void)
252
{
147 ira 253
    print_table_bottomup (1.0);
254
    print_table_bottomup (2.0);
255
    print_table_bottomup (5.0);
256
    print_table_topdown  (1.0);
257
    print_table_topdown  (2.0);
258
    print_table_topdown  (5.0);
144 ira 259
 
260
    return 0;
261
}
262