Subversion Repositories programming

Rev

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