Subversion Repositories programming

Rev

Rev 169 | Rev 171 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
168 ira 1
/* Copyright: Ira W. Snyder
2
 * Start Date: 2005-11-28
170 ira 3
 * End Date: 2005-11-29
168 ira 4
 * License: Public Domain
5
 *
6
 * Changelog Follows:
7
 * 2005-11-28
8
 * - Implement eval_euler() and eval_trapezoid().
9
 *
10
 * 2005-11-29
169 ira 11
 * - Implement eval_romberg() and eval_simpson().
168 ira 12
 *
13
 */
14
 
15
#include <cmath>
16
#include <cstdio>
17
using namespace std;
18
 
169 ira 19
/**
20
 * The function given in the Project #5 Handout.
21
 * This is 1 + x^28
22
 *
23
 * @param x the point at which to evaluate the function
24
 */
25
float func (float x)
168 ira 26
{
27
    return 1.0 + pow (x, 28);
28
}
29
 
169 ira 30
/**
31
 * Evaluate the integral of the function given, over the interval given,
32
 * using the Euler method.
33
 *
34
 * @param a the lower bound of the integral
35
 * @param b the upper bound of the integral
36
 * @param n the number of intervals to use
37
 * @param f the function to evaluate
38
 */
39
float eval_euler (const float a, const float b, const int n, float(*f)(float))
168 ira 40
{
41
    const float h = (b - a) / n;
42
    float answer = 0.0, xi = 0.0;
43
    int i = 0;
44
 
45
    for (i=0; i<=n; i++)
46
    {
47
        xi = a + (i * h);
48
        answer += f(xi);
49
    }
50
 
51
    return h * answer;
52
}
53
 
169 ira 54
/**
55
 * Evaluate the integral of the function given, over the interval given,
56
 * using the trapezoid method.
57
 *
58
 * @param a the lower bound of the integral
59
 * @param b the upper bound of the integral
60
 * @param n the number of intervals to use
61
 * @param f the function to evaluate
62
 */
63
float eval_trapezoid (const float a, const float b, const int n, float(*f)(float))
168 ira 64
{
65
    const float h = (b - a) / n;
66
    float answer = 0.0, xi_last = 0.0, xi_now = 0.0;
67
    int i = 0;
68
 
69
    xi_last = a + (i * h); // i = 0 here
70
 
71
    for (i=1; i<=n; i++)
72
    {
73
        xi_now = a + (i * h);
74
        answer += (f (xi_last) + f (xi_now) * (xi_now - xi_last));
75
        xi_last = xi_now; // shift xi's
76
    }
77
 
78
    return answer;
79
}
80
 
169 ira 81
/**
82
 * Evaluate the integral of the function given, over the interval given,
83
 * using the Romberg method.
84
 *
85
 * This is directly based on the pseudocode on Pg 223-224 of the textbook.
86
 *
87
 * @param a the lower bound of the integral
88
 * @param b the upper bound of the integral
89
 * @param n the number of intervals to use
90
 * @param f the function to evaluate
91
 */
92
float eval_romberg (const float a, const float b, const int n, float(*f)(float))
168 ira 93
{
94
    float R[n+1][n+1];
95
    int i, j, k;
96
    float h, sum;
97
 
98
    h = b - a;
99
    R[0][0] = (h/2.0) * (f(a) + f(b));
100
 
101
    for (i=1; i<=n; i++)
102
    {
103
        h = h/2.0;
104
        sum = 0.0;
105
 
106
        for (k=1; k<=(pow(2.0, i) - 1); k+=2)
107
            sum = sum + f(a + k * h);
108
 
109
        R[i][0] = (1.0/2.0) * R[i-1][0] + sum * h;
110
 
111
        for (j=1; j<=i; j++)
112
            R[i][j] = R[i][j-1] + (R[i][j-1] - R[i-1][j-1]) / (pow(4.0, j) - 1);
113
    }
114
 
115
    return R[n][n];
116
}
117
 
169 ira 118
/**
119
 * Evaluate the integral of the function given, over the interval given,
120
 * using the Simpson method.
121
 *
122
 * This is derived from the formula on Pg 237-238
123
 *
124
 * @param a the lower bound of the integral
125
 * @param b the upper bound of the integral
126
 * @param n the number of intervals to use
127
 * @param f the function to evaluate
128
 */
129
float eval_simpson (const float a, const float b, const int n, float(*f)(float))
168 ira 130
{
169 ira 131
    const float h = (b - a) / n;
132
    float sum1=0.0, sum2=0.0;
133
    int i;
168 ira 134
 
169 ira 135
    /* Get the first sum in the formula on Pg 238 */
136
    for (i=1, sum1=0.0; i<=n/2; i++)
137
        sum1 += f (a + (2 * i - 1) * h);
138
 
139
    sum1 *= 4;
140
 
141
    /* Get the second sum in the formula on Pg 238 */
142
    for (i=1, sum2=0.0; i<=(n-2)/2; i++)
143
        sum2 += f (a + 2 * i * h);
144
 
145
    sum2 *= 2;
146
 
147
    /* Add it all together, and return it */
148
    return (h / 3.0) * ((f(a) + f(b)) + sum1 + sum2);
168 ira 149
}
150
 
151
int main (void)
152
{
169 ira 153
    const float a = 0.0;
154
    const float b = 3.0;
170 ira 155
    const float real = 3.0 + (pow(3.0, 29.0) / 29.0);
156
    float h, comp, abs, rel;
157
    int i, n;
169 ira 158
 
170 ira 159
    /* Euler Method Header */
160
    printf ("Euler's Method\n");
161
    printf ("n       h               Computed        Abs Error       Rel Error\n");
162
    printf ("====================================================================\n");
163
 
164
    /* Euler Method Table */
165
    for (n=1; n<=25; n++)
166
    {
167
        h = (b - a) / n;
168
        comp = eval_euler (a, b, n, &func);
169
        abs = fabs(real - comp);
170
        rel = fabs(real - comp) / fabs(real);
171
 
172
        printf ("%.2d\t%e\t%e\t%e\t%e\n", n, h, comp, abs, rel);
173
    }
174
 
175
    /* Trapezoid Method Header */
176
    printf ("\n\nTrapezoid Method\n");
177
    printf ("n       h               Computed        Abs Error       Rel Error\n");
178
    printf ("====================================================================\n");
179
 
180
    /* Trapezoid Method Table */
181
    for (n=1; n<=25; n++)
182
    {
183
        h = (b - a) / n;
184
        comp = eval_trapezoid (a, b, n, &func);
185
        abs = fabs(real - comp);
186
        rel = fabs(real - comp) / fabs(real);
187
 
188
        printf ("%.2d\t%e\t%e\t%e\t%e\n", n, h, comp, abs, rel);
189
    }
190
 
191
    /* Romberg Method Header */
192
    printf ("\n\nRomberg's Method\n");
193
    printf ("n       h               Computed        Abs Error       Rel Error\n");
194
    printf ("====================================================================\n");
195
 
196
    /* Romberg Method Table */
197
    for (n=1; n<=25; n++)
198
    {
199
        h = (b - a) / n;
200
        comp = eval_romberg (a, b, n, &func);
201
        abs = fabs(real - comp);
202
        rel = fabs(real - comp) / fabs(real);
203
 
204
        printf ("%.2d\t%e\t%e\t%e\t%e\n", n, h, comp, abs, rel);
205
    }
206
 
207
    /* Simpson Method Header */
208
    printf ("\n\nSimpson's Method\n");
209
    printf ("n       h               Computed        Abs Error       Rel Error\n");
210
    printf ("====================================================================\n");
211
 
212
    /* Simpson Method Table */
213
    for (n=1; n<=25; n++)
214
    {
215
        h = (b - a) / n;
216
        comp = eval_simpson (a, b, n, &func);
217
        abs = fabs(real - comp);
218
        rel = fabs(real - comp) / fabs(real);
219
 
220
        printf ("%.2d\t%e\t%e\t%e\t%e\n", n, h, comp, abs, rel);
221
    }
222
 
168 ira 223
    return 0;
224
}
225