Subversion Repositories programming

Rev

Rev 147 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
148 ira 1
/* Ira Snyder
2
 * Project #2
3
 * Due 2005-10-28
4
 */
5
 
6
/* Copyright: Ira W. Snyder
7
 * Start Date: 2005-10-23
8
 * End Date: 2005-10-27
9
 * License: Public Domain
10
 */
11
 
144 ira 12
#include <iostream>
13
#include <iomanip>
14
#include <cmath>
148 ira 15
#include <cstdio>
144 ira 16
using namespace std;
17
 
147 ira 18
// Global Variables
19
enum {IDX0, IDX1, IDX5, IDX10, IDX15, IDX19, IDX20}; // Constants' Indices
144 ira 20
 
21
float x1_const[7] = { 1.266065978,     5.651591040E-01, 2.714631560E-04,
22
                      2.752948040E-10, 2.370463051E-17, 1.587678369E-23,
23
                      3.966835986E-25 };
24
 
25
float x2_const[7] = { 2.279585302,     1.590636855,     9.825679323E-03,
26
                      3.016963879E-07, 8.139432531E-13, 8.641603385E-18,
27
                      4.310560576E-19 };
28
 
29
float x5_const[7] = { 2.723987182E+01, 2.433564214E+01, 2.157974547,
30
                      4.580044419E-03, 1.047977675E-6 , 4.078415017E-10,
31
                      5.024239358E-11 };
32
 
147 ira 33
// Global Defines
34
#define ARRAY_SIZE 21
35
 
36
// Function Prototypes
148 ira 37
float *Bessel_BottomUp (int n, float x, float *constants);
38
float *Bessel_TopDown (int n, float x, float *constants);
147 ira 39
void print_table_bottomup (float x);
40
void print_table_topdown (float x);
41
void print_equals (int num);
42
 
144 ira 43
/* Find the Bessel Function.
44
 * Algorithm: I[n+1](x) = I[n-1](x) - (2*n/x) * I[n](x)
45
 * Which is equvalent to: I[n](x) = I[n-2](x) - (2 * (n-1)/x) * I[n-1](x)
46
 * by simple substitution.
47
 *
48
 * This is the recurrence relation for PART #1.
148 ira 49
 *
50
 * Return values:
51
 * this returns an array of values, in the form:
52
 * array[0] = calculated value
53
 * array[1] = part before the subtraction: I[n-2](x)
54
 * array[2] = part after  the subtraction: (2(n-1)/x) * I[n-1](x)
144 ira 55
 */
148 ira 56
float *Bessel_BottomUp (int n, float x, float *constants)
144 ira 57
{
58
    int i = 0;
148 ira 59
    float *answer = new float[3];
144 ira 60
    float *storage = new float[ARRAY_SIZE];
61
 
62
    // Prime the array
145 ira 63
    storage[0] = constants[IDX0];
64
    storage[1] = constants[IDX1];
144 ira 65
 
66
    // Calculate each value in turn
147 ira 67
    for (i=2; i<=n; i++)
148 ira 68
    {
69
        storage[i] = storage[i-2] - (2.0 * (i-1) / x) * storage[i-1];
70
#ifdef DEBUG
71
        // This will print out some useful information to find out why this
72
        // is going right or wrong in it's calculation.
73
        printf ("storage[%d] = %e - %e * %e = %e - %e = %e\n", i, storage[i-2],
74
                (2.0 * (i-1)  / x), storage[i-1],
75
                storage[i-2], (2.0 * (i-1) / x) * storage[i-1], storage[i]);
76
#endif
77
    }
144 ira 78
 
79
    // Store the answer, delete the memory
148 ira 80
    answer[0] = storage[n];
81
    answer[1] = storage[n-2];
82
    answer[2] = (2.0 * (n-1) / x) * storage[n-1];
144 ira 83
    delete[] storage;
84
 
85
    // Return the result
86
    return answer;
87
}
88
 
89
/* Find the Bessel Function, from the Top -> Down.
90
 * Algorithm: I[n-1](x) = (2*n/x)*I[n](x) + I[n+1](x)
91
 * Which is equivalent to: I[n](x) = (2 * (n+1) / x) * I[n+1](x) + I[n+2](x)
92
 * by simple substitution.
93
 *
94
 * This is the recurrence relation for PART #2.
148 ira 95
 *
96
 * Return values:
97
 * this returns an array of values in the form:
98
 * array[0] = calculated value
99
 * array[1] = part before the addition: I[n+2](x)
100
 * array[2] = part after  the addition: (2(n+1)/x) * I[n+1](x)
144 ira 101
 */
148 ira 102
float *Bessel_TopDown (int n, float x, float *constants)
144 ira 103
{
104
    int i = 18;
148 ira 105
    float *answer = new float[3];
144 ira 106
    float *storage = new float[ARRAY_SIZE];
107
 
108
    // Prime the array
145 ira 109
    storage[20] = constants[IDX20];
110
    storage[19] = constants[IDX19];
144 ira 111
 
112
    // Calculate each value in turn
147 ira 113
    for (i=18; i>=n; i--)
148 ira 114
    {
115
        storage[i] = (2.0 * (i+1) / x) * storage[i+1] + storage[i+2];
116
#ifdef DEBUG
117
        // This will print out some useful information to find out why this
118
        // is going right or wrong in it's calculation.
119
        printf ("storage[%d] = %e * %e + %e = %e + %e = %e\n", i,
120
                (2.0 * (i+1) / x), storage[i+1], storage[i+2],
121
                (2.0 * (i+1) / x) * storage[i+1], storage[i+2], storage[i]);
122
#endif
123
    }
144 ira 124
 
125
    // Store the answer, free the memory
148 ira 126
    answer[0] = storage[n];
127
    answer[1] = storage[n+2];
128
    answer[2] = (2.0 * (n+1) / x) * storage[n+1];
144 ira 129
    delete[] storage;
130
 
131
    // Return the result
132
    return answer;
133
}
134
 
148 ira 135
/* Print a table of the Bessel function (for PART #2)
136
 * for the given value of x */
147 ira 137
void print_table_bottomup (float x)
144 ira 138
{
147 ira 139
    int n, tblwidth = 6+16+16+16+16+16+20;
140
    float true_val, calc_val, abs_err, rel_err, part1, part2;
148 ira 141
    float *constants, *answer;
144 ira 142
 
148 ira 143
    // Find the right constants to use for the x value we're using.
145 ira 144
    if (x == 1.0) constants = x1_const;
145
    if (x == 2.0) constants = x2_const;
146
    if (x == 5.0) constants = x5_const;
144 ira 147
 
147 ira 148
    // Reset the output flags
149
    cout << resetiosflags (ios_base::scientific | ios_base::showpoint);
144 ira 150
 
145 ira 151
    // A line of equal signs
147 ira 152
    print_equals (tblwidth);
145 ira 153
 
154
    // Print the x value we're using
147 ira 155
    cout << "Using x = " << x
148 ira 156
         << " and working Bottom-up (PART #1)" << endl;
157
    // A line of equal signs
158
    print_equals (tblwidth);
145 ira 159
 
147 ira 160
    // Set the output flags we're using
161
    cout << setiosflags (ios_base::scientific | ios_base::showpoint);
162
 
144 ira 163
    // Print the table header
147 ira 164
    cout << setw(6) << "n Val."
165
         << setw(16) << "TRUE VAL"
166
         << setw(16) << "COMPUTED"
167
         << setw(16) << "ABS ERROR"
168
         << setw(16) << "REL ERROR"
169
         << setw(16) << "I[n-2](x)"
170
         << setw(20) << "(2(n-1)/x)I[n-1](x)"
144 ira 171
         << endl;
172
 
173
    // A line of equal signs
147 ira 174
    print_equals (tblwidth);
144 ira 175
 
145 ira 176
    // Run once for n = 5,10,15,20
177
    for (n=5; n<=20; n+=5)
178
    {
148 ira 179
        // Choose the true values
180
        switch (n)
181
        {
182
            case 5:  true_val = constants[IDX5];  break;
183
            case 10: true_val = constants[IDX10]; break;
184
            case 15: true_val = constants[IDX15]; break;
185
            case 20: true_val = constants[IDX20]; break;
186
        }
144 ira 187
 
148 ira 188
        // Get all of the pieces to print
189
        answer = Bessel_BottomUp(n, x, constants);
190
        calc_val = answer[0];
145 ira 191
        abs_err  = abs (true_val - calc_val);
192
        rel_err  = abs_err / abs (true_val);
148 ira 193
        part1    = answer[1];
194
        part2    = answer[2];
195
        delete[] answer;
144 ira 196
 
148 ira 197
        // Print a table line
147 ira 198
        cout << setw(6) << n
199
             << setw(16) << true_val
200
             << setw(16) << calc_val
201
             << setw(16) << abs_err
202
             << setw(16) << rel_err
203
             << setw(16) << part1
204
             << setw(20) << part2
145 ira 205
             << endl;
206
    }
146 ira 207
 
208
    cout << endl;
144 ira 209
}
210
 
148 ira 211
/* Print a table of the Bessel function (for PART #2)
212
 * for the given value of x */
147 ira 213
void print_table_topdown (float x)
214
{
215
    int n, tblwidth = 6+16+16+16+16+16+20;
216
    float true_val, calc_val, abs_err, rel_err, part1, part2;
148 ira 217
    float *constants, *answer;
147 ira 218
    bool done = false;
219
 
148 ira 220
    // Choose the correct constants for the value of x we're using
147 ira 221
    if (x == 1.0) constants = x1_const;
222
    if (x == 2.0) constants = x2_const;
223
    if (x == 5.0) constants = x5_const;
224
 
225
    // Reset the output flags
226
    cout << resetiosflags (ios_base::scientific | ios_base::showpoint);
227
 
228
    // A line of equal signs
229
    print_equals (tblwidth);
230
 
231
    // Print the x value we're using
232
    cout << "Using x = " << x
148 ira 233
         << " and working Top-down (PART #2)" << endl;
234
    // A line of equal signs
235
    print_equals (tblwidth);
147 ira 236
 
237
    // Set the output flags we're using
238
    cout << setiosflags (ios_base::scientific | ios_base::showpoint);
239
 
240
    // Print the table header
241
    cout << setw(6) << "n Val."
242
         << setw(16) << "TRUE VAL"
243
         << setw(16) << "COMPUTED"
244
         << setw(16) << "ABS ERROR"
245
         << setw(16) << "REL ERROR"
246
         << setw(16) << "I[n+2](x)"
247
         << setw(20) << "(2(n+1)/x)I[n+1](x)"
248
         << endl;
249
 
250
    // A line of equal signs
251
    print_equals (tblwidth);
252
 
253
    n = 0;
254
    // Run once for n = 0,1,5,10,15
255
    while (!done)
256
    {
148 ira 257
        // Choose the correct true values of the function
147 ira 258
        switch (n)
259
        {
260
            case 0:  true_val = constants[IDX0];  break;
261
            case 1:  true_val = constants[IDX1];  break;
262
            case 5:  true_val = constants[IDX5];  break;
263
            case 10: true_val = constants[IDX10]; break;
264
            case 15: true_val = constants[IDX15]; break;
265
        }
266
 
148 ira 267
        // Get all of the values to be printed
268
        answer = Bessel_TopDown(n, x, constants);
269
        calc_val = answer[0];
147 ira 270
        abs_err  = abs (true_val - calc_val);
271
        rel_err  = abs_err / abs (true_val);
148 ira 272
        part1    = answer[1];
273
        part2    = answer[2];
274
        delete[] answer;
147 ira 275
 
148 ira 276
        // Print a line in the table
147 ira 277
        cout << setw(6) << n
278
             << setw(16) << true_val
279
             << setw(16) << calc_val
280
             << setw(16) << abs_err
281
             << setw(16) << rel_err
282
             << setw(16) << part1
283
             << setw(20) << part2
284
             << endl;
285
 
286
        switch (n) // Set n for the next loop
287
        {
288
            case 0:  n = 1;  break;
289
            case 1:  n = 5;  break;
290
            case 5:  n = 10; break;
291
            case 10: n = 15; break;
292
            case 15: done = true; break;
293
        }
294
    }
295
 
296
    cout << endl;
297
}
298
 
148 ira 299
/* Print a line of equal signs on the screen */
147 ira 300
void print_equals (int num)
301
{
302
    int i;
303
 
304
    for (i=0; i<num; i++)
305
        cout << "=";
306
 
307
    cout << endl;
308
}
309
 
144 ira 310
int main (void)
311
{
148 ira 312
#ifdef DEBUG
313
    // Print out lots of good information to find out why these functions are
314
    // going right or wrong.
315
    float *answer;
316
    cout << "Bottom-up" << endl << endl;
317
    answer = Bessel_BottomUp(20, 1.0, x1_const);
318
    cout << endl << endl << "Top-down" << endl << endl;
319
    answer = Bessel_TopDown (0,  1.0, x1_const);
320
#else
321
    // Print the first line of output as my name
322
    cout << "Name: Ira Snyder" << endl << endl;
323
 
324
    // Print all of the tables we need
147 ira 325
    print_table_bottomup (1.0);
326
    print_table_bottomup (2.0);
327
    print_table_bottomup (5.0);
328
    print_table_topdown  (1.0);
329
    print_table_topdown  (2.0);
330
    print_table_topdown  (5.0);
148 ira 331
#endif
144 ira 332
    return 0;
333
}
334