Subversion Repositories programming

Rev

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