Subversion Repositories programming

Rev

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

Rev Author Line No. Line
154 ira 1
/* Copyright: Ira W. Snyder
2
 * Start Date: 2005-11-13
3
 * End Date: 2005-11-13
4
 * License: Public Domain
5
 *
6
 * Changelog Follows:
7
 *
8
 * 2005-11-13
9
 * - Implemented Functions 1-3 from the Project #3 Handout.
10
 * - Implemented Algorithm 7 (LaGrange) from Notes Set #3.
11
 * - Implemented Algorithm 8-9 (Newton Divided Diff) from Notes Set #3.
155 ira 12
 * - Implemented GenEvenPts() which will generate evenly spaced points.
13
 * - Implemented GenChebychevPts() which will generate Chebychev points.
157 ira 14
 * - Split the Newton algorithm into two parts: NewtonMethod() and NewtonCoef().
158 ira 15
 * - Implemented brute_search_lagrange() and brute_search_newton() to find the
16
 *   worst values. This is taken from the Project #3 Handout.
17
 * - Added each needed call to main().
154 ira 18
 *
159 ira 19
 * 2005-11-17
20
 * - Changed stupid global variables used to return values from a function to
21
 *   a new type (called bsf_type) and use that instead. What was I thinking???
22
 *
154 ira 23
 */
24
 
25
#include <cstdio>
26
#include <cmath>
27
using namespace std;
28
 
157 ira 29
#define MAX_POINTS 26
154 ira 30
 
159 ira 31
// A convienent brute-force-search return type
32
typedef struct { double absmax, xsave; } bsf_type;
157 ira 33
 
155 ira 34
/**
35
 * Function #1 from the Project #3 Handout.
36
 *
37
 * @param x the place to calculate the value of this function
38
 * @return the value of the function at x
39
 */
154 ira 40
double func1 (double x)
41
{
42
    return 1.0 / (1.0 + pow(x, 2));
43
}
44
 
155 ira 45
/**
46
 * Function #2 from the Project #3 Handout.
47
 *
48
 * @param x the place to calculate the value of this function
49
 * @return the value of the function at x
50
 */
154 ira 51
double func2 (double x)
52
{
53
    // NOTE: M_E is the value of e defined by the math.h header
54
    return (pow(M_E, x) + pow(M_E, -x)) / 2.0;
55
}
56
 
155 ira 57
/**
58
 * Function #3 from the Project #3 Handout.
59
 *
60
 * @param x the place to calculate the value of this function
61
 * @return the value of the function at x
62
 */
154 ira 63
double func3 (double x)
64
{
65
    return pow(x, 14) + pow(x, 10) + pow(x, 4) + x + 1;
66
}
67
 
155 ira 68
/**
69
 * Find the value of the LaGrange Interpolating Polynomial at a point.
70
 *
71
 * @param x the x[i] values
72
 * @param y the y[i] values
73
 * @param n the number of points
74
 * @param point the point to evaluate at
75
 * @return the value of the Interpolating Poly at point
76
 */
154 ira 77
double LaGrangeMethod (double *x, double *y, int n, double point)
78
{
79
    double value = 0;
80
    double term  = 0;
81
    int i, j;
82
 
83
    for (i=0; i<n; i++)
84
    {
85
        term = y[i];
86
 
87
        for (j=0; j<n; j++)
88
            if (i != j)
89
                term *= (point - x[j])/(x[i] - x[j]);
90
 
91
        value += term;
92
    }
93
 
94
    return value;
95
}
96
 
155 ira 97
/**
157 ira 98
 * Find the Newton Coefficients.
99
 * This only needs to be called once per set of x,y values.
155 ira 100
 *
101
 * @param x the x[i] values
102
 * @param y the y[i] values
157 ira 103
 * @param a the a[i] values will be returned here
155 ira 104
 * @param n the number of points
105
 */
157 ira 106
void NewtonCoef (double *x, double *y, double *a, int n)
154 ira 107
{
108
    int i, j;
109
 
110
    for (i=0; i<n; i++)
111
        a[i] = y[i];
112
 
113
    for (i=1; i<n; i++)
114
        for (j=n-1; j>=i; j--)
115
            a[j] = (a[j] - a[j-1]) / (x[j] - x[j-i]);
157 ira 116
}
154 ira 117
 
157 ira 118
/**
119
 * Find the value of the Newton Interpolating Polynomial at a point.
120
 * The a[i]'s are found using a divided difference table.
121
 *
122
 * @param x the x[i] values
123
 * @param y the y[i] values
124
 * @param a the a[i] values (Newton Coefficients)
125
 * @param n the number of points
126
 * @param point the point to evaluate at
127
 * @return the value of the Interpolating Poly at point
128
 */
129
double NewtonMethod (double *x, double *y, double *a, int n, double point)
130
{
131
    int i;
154 ira 132
    double xterm = 1.0;
133
    double value = 0.0;
134
 
135
    for (i=0; i<n; i++)
136
    {
137
        value += a[i] * xterm;
138
        xterm *= (point - x[i]);
139
    }
140
 
141
    return value;
142
}
143
 
155 ira 144
/**
145
 * Generate evenly spaced points for the function given.
146
 * The algorithm is taken from the Project #3 Handout.
147
 *
148
 * @param num_pts the number of points
149
 * @param *func the function that you want to use to find y[i]
150
 * @param x[] the array that will hold the x[i] values
151
 * @param y[] the array that will hold the y[i] values
152
 */
153
void GenEvenPts (int num_pts, double(*func)(double), double x[], double y[])
154
{
155
    int i;
156 ira 156
    double h = 10.0 / (double)(num_pts-1);
155 ira 157
    double xtemp = -5.0;
158
 
159
    for (i=0; i<num_pts; i++)
160
    {
161
        x[i] = xtemp;
162
        y[i] = func(x[i]);
163
        xtemp += h;
164
    }
165
}
166
 
167
/**
168
 * Generate Chebychev points for the function given.
169
 * The algorithm is taken from the Project #3 Handout.
170
 *
171
 * @param num_pts the number of points
172
 * @param *func the function that you want to use to find y[i]
173
 * @param x[] the array that will hold the x[i] values
174
 * @param y[] the array that will hold the y[i] values
175
 */
176
void GenChebychevPts (int num_pts, double(*func)(double), double x[], double y[])
177
{
178
    int i;
179
 
180
    for (i=0; i<num_pts; i++)
181
    {
156 ira 182
        x[i] = -5.0 * cos((float)i * M_PI / (float)(num_pts-1));
155 ira 183
        y[i] = func(x[i]);
184
    }
185
}
186
 
157 ira 187
/**
188
 * Brute-force search the Newton Interpolating Poly for the x and y values.
189
 * The error calculations will be for the given function (func1, func2, or func3).
190
 *
191
 * @param x the x[i] values
192
 * @param y the y[i] values
193
 * @param n the number of points for this polynomial
194
 * @param func the function to use for the error calculation
159 ira 195
 * @return a struct of the max abs error and the x value where it occurred
157 ira 196
 */
159 ira 197
bsf_type brute_search_newton (double *x, double *y, int n, double(*func)(double))
157 ira 198
{
159 ira 199
    bsf_type answer;
200
    answer.absmax = 0.0;
201
    answer.xsave = 0.0;
202
 
157 ira 203
    double xval = -5.0;
204
    double h = 10.0/500.0;
205
    double temp, error;
206
    double a[n];
207
    int i;
208
 
209
    NewtonCoef(x, y, a, n);
210
 
211
    for (i=0; i<=500; i++)
212
    {
213
        temp = NewtonMethod(x, y, a, n, xval);
214
        error = abs(temp - func(xval));
215
 
159 ira 216
        if (error > answer.absmax)
157 ira 217
        {
159 ira 218
            answer.absmax = error;
219
            answer.xsave = xval;
157 ira 220
        }
221
 
222
        xval += h;
223
    }
159 ira 224
 
225
    return answer;
157 ira 226
}
227
 
228
/**
229
 * Brute-force search the LaGrange Interpolating Poly for the x and y values.
230
 * The error calculations will be for the given function (func1, func2, or func3).
231
 *
232
 * @param x the x[i] values
233
 * @param y the y[i] values
234
 * @param n the number of points for this polynomial
235
 * @param func the function to use for the error calculation
159 ira 236
 * @return a struct of the max abs error and the x value where it occurred
157 ira 237
 */
159 ira 238
bsf_type brute_search_lagrange (double *x, double *y, int n, double(*func)(double))
157 ira 239
{
159 ira 240
    bsf_type answer;
241
    answer.absmax = 0.0;
242
    answer.xsave = 0.0;
243
 
157 ira 244
    double xval = -5.0;
245
    double h = 10.0/500.0;
246
    double temp, error;
247
    int i;
248
 
249
    for (i=0; i<=500; i++)
250
    {
251
        temp = LaGrangeMethod(x, y, n, xval);
252
        error = abs(temp - func(xval));
253
 
159 ira 254
        if (error > answer.absmax)
157 ira 255
        {
159 ira 256
            answer.absmax = error;
257
            answer.xsave = xval;
157 ira 258
        }
259
 
260
        xval += h;
261
    }
159 ira 262
 
263
    return answer;
157 ira 264
}
265
 
158 ira 266
/**
267
 * Print a nice error line in the format we need.
268
 *
269
 * @param points the number of points
159 ira 270
 * @param error a struct of the max abs error and the x value where it occurred
158 ira 271
 */
159 ira 272
void print_error_line (int points, bsf_type error)
158 ira 273
{
274
    printf ("For %-2d Points, MAX ERROR is: %e"
159 ira 275
            " -- OCCURS at x = %e\n", points, error.absmax, error.xsave);
158 ira 276
}
277
 
154 ira 278
int main (void)
279
{
158 ira 280
    int i; // number of points
157 ira 281
    double x[MAX_POINTS];
282
    double y[MAX_POINTS];
159 ira 283
    bsf_type error;
154 ira 284
 
157 ira 285
    // In the following code, the correct functions are run for each of the
286
    // 12 times this needs to be run.
287
 
288
    printf ("Newton Polynomial, Equal Points, Function #1\n");
289
    printf ("============================================================\n");
290
    for (i=6; i<=26; i+=5)
291
    {
158 ira 292
        GenEvenPts (i, &func1, x, y);
159 ira 293
        error = brute_search_newton (x, y, i, &func1);
294
        print_error_line (i, error);
155 ira 295
 
157 ira 296
    }
297
 
298
    printf ("\n\n");
299
    printf ("Newton Polynomial, Equal Points, Function #2\n");
300
    printf ("============================================================\n");
301
    for (i=6; i<=26; i+=5)
302
    {
158 ira 303
        GenEvenPts (i, &func2, x, y);
159 ira 304
        error = brute_search_newton (x, y, i, &func2);
305
        print_error_line (i, error);
157 ira 306
    }
307
 
308
    printf ("\n\n");
309
    printf ("Newton Polynomial, Equal Points, Function #3\n");
310
    printf ("============================================================\n");
311
    for (i=6; i<=26; i+=5)
312
    {
158 ira 313
        GenEvenPts (i, &func3, x, y);
159 ira 314
        error = brute_search_newton (x, y, i, &func3);
315
        print_error_line (i, error);
157 ira 316
    }
317
 
318
    printf ("\n\n");
319
    printf ("LaGrange Polynomial, Equal Points, Function #1\n");
320
    printf ("============================================================\n");
321
    for (i=6; i<=26; i+=5)
322
    {
158 ira 323
        GenEvenPts (i, &func1, x, y);
159 ira 324
        error = brute_search_lagrange (x, y, i, &func1);
325
        print_error_line (i, error);
157 ira 326
    }
327
 
328
    printf ("\n\n");
329
    printf ("LaGrange Polynomial, Equal Points, Function #2\n");
330
    printf ("============================================================\n");
331
    for (i=6; i<=26; i+=5)
332
    {
158 ira 333
        GenEvenPts (i, &func2, x, y);
159 ira 334
        error = brute_search_lagrange (x, y, i, &func2);
335
        print_error_line (i, error);
157 ira 336
    }
337
 
338
    printf ("\n\n");
339
    printf ("LaGrange Polynomial, Equal Points, Function #3\n");
340
    printf ("============================================================\n");
341
    for (i=6; i<=26; i+=5)
342
    {
158 ira 343
        GenEvenPts (i, &func3, x, y);
159 ira 344
        error = brute_search_lagrange (x, y, i, &func3);
345
        print_error_line (i, error);
157 ira 346
    }
347
 
348
    printf ("\n\n");
349
    printf ("Newton Polynomial, Chebychev Points, Function #1\n");
350
    printf ("============================================================\n");
351
    for (i=6; i<=26; i+=5)
352
    {
158 ira 353
        GenChebychevPts (i, &func1, x, y);
159 ira 354
        error = brute_search_newton (x, y, i, &func1);
355
        print_error_line (i, error);
157 ira 356
    }
357
 
358
    printf ("\n\n");
359
    printf ("Newton Polynomial, Chebychev Points, Function #2\n");
360
    printf ("============================================================\n");
361
    for (i=6; i<=26; i+=5)
362
    {
158 ira 363
        GenChebychevPts (i, &func2, x, y);
159 ira 364
        error = brute_search_newton (x, y, i, &func2);
365
        print_error_line (i, error);
157 ira 366
    }
367
 
368
    printf ("\n\n");
369
    printf ("Newton Polynomial, Chebychev Points, Function #3\n");
370
    printf ("============================================================\n");
371
    for (i=6; i<=26; i+=5)
372
    {
158 ira 373
        GenChebychevPts (i, &func3, x, y);
159 ira 374
        error = brute_search_newton (x, y, i, &func3);
375
        print_error_line (i, error);
157 ira 376
    }
377
 
378
    printf ("\n\n");
379
    printf ("LaGrange Polynomial, Chebychev Points, Function #1\n");
380
    printf ("============================================================\n");
381
    for (i=6; i<=26; i+=5)
382
    {
158 ira 383
        GenChebychevPts (i, &func1, x, y);
159 ira 384
        error = brute_search_lagrange (x, y, i, &func1);
385
        print_error_line (i, error);
157 ira 386
    }
387
 
388
    printf ("\n\n");
389
    printf ("LaGrange Polynomial, Chebychev Points, Function #2\n");
390
    printf ("============================================================\n");
391
    for (i=6; i<=26; i+=5)
392
    {
158 ira 393
        GenChebychevPts (i, &func2, x, y);
159 ira 394
        error = brute_search_lagrange (x, y, i, &func2);
395
        print_error_line (i, error);
157 ira 396
    }
397
 
398
    printf ("\n\n");
399
    printf ("LaGrange Polynomial, Chebychev Points, Function #3\n");
400
    printf ("============================================================\n");
401
    for (i=6; i<=26; i+=5)
402
    {
158 ira 403
        GenChebychevPts (i, &func3, x, y);
159 ira 404
        error = brute_search_lagrange (x, y, i, &func3);
405
        print_error_line (i, error);
157 ira 406
    }
407
 
154 ira 408
    return 0;
409
}
410