|
1 | 1 | #include <math.h>
|
2 |
| -#include <float.h> |
3 | 2 | #include <stdio.h>
|
4 |
| -#include <stdlib.h> |
5 | 3 |
|
6 |
| -#define SPREAD 4 |
| 4 | +#ifdef DEBUG |
| 5 | +#define debugf(x, ...) fprintf(stdout, x, ##__VA_ARGS__); |
| 6 | +#else |
| 7 | +#define debugf(x, ...) |
| 8 | +#endif |
| 9 | + |
7 | 10 | #define ABS(x)(((x)<0)?-(x):(x))
|
8 | 11 | #define MAX_ERROR 0.5*pow(10, -12)
|
9 | 12 |
|
10 |
| -int search(int traps, int tmin, int tmax, double a, double b); |
11 |
| -double calc_true_error(double true_val, double approx_val); |
| 13 | +double calc_approx(double a, double b, int traps); |
12 | 14 | double calc_actual(double a, double b);
|
13 |
| -double calc_approx(double a, double b, int traps, double h); |
14 | 15 | double func(double x);
|
15 | 16 | double func_int(double x);
|
16 | 17 |
|
17 |
| -double current_min; |
18 |
| - |
19 | 18 | int main(int argc, char **argv) {
|
20 |
| - int traps, mid, optimal_traps; |
21 |
| - double lend, rend, approx, actual; |
22 |
| - |
23 |
| - printf("Enter left, right, and trapezoids\n"); |
24 |
| - |
25 |
| - scanf("%lf%lf%d", &lend, &rend, &traps); |
26 |
| - |
27 |
| - mid = (traps/2); |
28 |
| - |
29 |
| - optimal_traps = search(mid, 0, traps, lend, rend); |
30 |
| - |
31 |
| - printf("t = %d\n", optimal_traps); |
32 |
| - |
33 |
| - approx = calc_approx(lend, rend, optimal_traps, (rend-lend)/optimal_traps); |
34 |
| - |
35 |
| - actual = calc_actual(lend, rend); |
36 |
| - |
37 |
| - printf("absolute relative true error %.16lf\n", calc_true_error(actual, approx)); |
38 |
| - |
39 |
| - return 0; |
40 |
| -} |
41 |
| - |
42 |
| -int search(int traps, int tmin, int tmax, double a, double b) { |
43 |
| - int x, lvalue, rvalue, lmid, rmid, min_index; |
44 |
| - double h, approx, actual, true_error, min_value; |
| 19 | + int stride, index; |
| 20 | + double a, b, actual, approx, true_error; |
45 | 21 |
|
46 |
| - if (traps <= tmin || traps > tmax) return traps; |
| 22 | + printf("Enter a and b\n"); |
| 23 | + |
| 24 | + scanf("%lf%lf", &a, &b); |
47 | 25 |
|
48 |
| - min_value = DBL_MAX; |
| 26 | + actual = calc_actual(a, b); |
49 | 27 |
|
50 |
| - for (x = traps-SPREAD; x < traps+SPREAD+1; ++x) { |
51 |
| - h = (b-a)/x; |
| 28 | + stride = 4096; |
52 | 29 |
|
53 |
| - approx = calc_approx(a, b, x, h); |
| 30 | + while (1) { |
| 31 | + if (stride == 1) break; |
54 | 32 |
|
55 |
| - actual = calc_actual(a, b); |
| 33 | + printf("Index at %d\n", index); |
| 34 | + printf("Stride at %d\n", stride); |
56 | 35 |
|
57 |
| - true_error = calc_true_error(actual, approx); |
| 36 | + while (1) { |
| 37 | + index += stride; |
58 | 38 |
|
59 |
| - if (true_error <= MAX_ERROR) { |
60 |
| - printf("traps %d\n", x); |
61 |
| - printf("h %.16lf\n", h); |
62 |
| - printf("approx %.16lf\n", approx); |
63 |
| - printf("actual %.16lf\n", actual); |
64 |
| - printf("true error %.13lf\n", true_error); |
65 |
| - printf("true error %.13lf\n", MAX_ERROR); |
| 39 | + approx = calc_approx(a, b, index); |
66 | 40 |
|
67 |
| - return x; |
68 |
| - } |
| 41 | + true_error = ABS(actual-approx)*100/actual; |
69 | 42 |
|
70 |
| - if (true_error < min_value) { |
71 |
| - min_index = x; |
| 43 | + printf("traps %d\n", index); |
| 44 | + printf("actual %.10lf\n", actual); |
| 45 | + printf("approx %.10lf\n", approx); |
| 46 | + printf("true error %.16e\n", true_error); |
72 | 47 |
|
73 |
| - min_value = true_error; |
74 |
| - } |
| 48 | + if (true_error <= MAX_ERROR) { |
| 49 | + printf("Found true error less than equal %.16e\n", MAX_ERROR); |
| 50 | + |
| 51 | + break; |
| 52 | + } |
| 53 | + } |
75 | 54 |
|
76 |
| - printf("traps %d\n", x); |
77 |
| - printf("h %.16lf\n", h); |
78 |
| - printf("approx %.16lf\n", approx); |
79 |
| - printf("actual %.16lf\n", actual); |
80 |
| - printf("true error %.13lf\n", true_error); |
81 |
| - printf("true error %.13lf\n", MAX_ERROR); |
82 |
| - } |
| 55 | + index -= stride; |
83 | 56 |
|
84 |
| - printf("Done looking at values found min index %d\n", min_index); |
| 57 | + stride /= 2; |
| 58 | + } |
85 | 59 |
|
86 |
| - if (min_value < current_min) { |
87 |
| - current_min = min_value; |
88 |
| - } else { |
89 |
| - min_index = traps+1; |
90 |
| - } |
91 |
| - |
92 |
| - if (min_index <= traps) { |
93 |
| - lvalue = floor((traps-tmin)/2); |
94 |
| - lmid = tmin+lvalue; |
| 60 | + return 0; |
| 61 | +} |
95 | 62 |
|
96 |
| - printf("We're going left\n"); |
97 |
| - return search(lmid, tmin, traps, a, b); |
98 |
| - } else { |
99 |
| - rvalue = floor((tmax-traps)/2); |
100 |
| - rmid = traps+rvalue; |
| 63 | +double calc_approx(double a, double b, int n) { |
| 64 | + int i; |
| 65 | + double h = (b-a)/n; |
| 66 | + double approx = (func(a)+func(b))/2; |
101 | 67 |
|
102 |
| - printf("We're going right\n"); |
103 |
| - return search(rmid, traps, tmax, a, b); |
104 |
| - } |
105 |
| -} |
| 68 | + for (i = 1; i <= n-1; ++i) { |
| 69 | + approx += func(a+i*h); |
| 70 | + } |
106 | 71 |
|
107 |
| -double calc_true_error(double true_val, double approx_val) { |
108 |
| - return ABS(true_val-approx_val)/true_val; |
| 72 | + return h * approx; |
109 | 73 | }
|
110 | 74 |
|
111 | 75 | double calc_actual(double a, double b) {
|
112 |
| - return func_int(b)-func_int(a); |
113 |
| -} |
114 |
| - |
115 |
| -double calc_approx(double a, double b, int traps, double h) { |
116 |
| - int x; |
117 |
| - double approx = 0.0; |
118 |
| - |
119 |
| - for (x = 1; x < traps-1; ++x) { |
120 |
| - approx += func(a+x*h); |
121 |
| - } |
122 |
| - |
123 |
| - approx *= 2; |
124 |
| - approx += func(a)+func(b); |
125 |
| - approx *= h/2; |
126 |
| - |
127 |
| - return approx; |
| 76 | + return func_int(b)-func_int(a); |
128 | 77 | }
|
129 | 78 |
|
130 | 79 | double func(double x) {
|
131 |
| - return cos(x/3)-2*cos(x/5)+5*sin(x/4)+8; |
| 80 | + return 8+5*sin(x/4)-2*cos(x/5)+cos(x/3); |
132 | 81 | }
|
133 | 82 |
|
134 | 83 | double func_int(double x) {
|
135 |
| - return 8*x-10*sin(x/5)+3*sin(x/3)-20*cos(x/4); |
| 84 | + return 8*x-10*sin(x/5)+3*sin(x/3)-20*cos(x/4); |
136 | 85 | }
|
0 commit comments