forked from heavy3/programming-abstractions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
114 lines (94 loc) · 3.59 KB
/
Copy pathmain.cpp
File metadata and controls
114 lines (94 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//
// main.cpp
//
// Numerically integrate a continuous, single-valued function over an interval
// along the x-axis by subdividing the region under the curve into a given
// number of rectangles whose height corresponds to the value of the function
// at the midpoint of the rectangle.
//
// --------------------------------------------------------------------------
// Attribution: "Programming Abstractions in C++" by Eric Roberts
// Chapter 20, Exercise 07
// Stanford University, Autumn Quarter 2012
// http://web.stanford.edu/class/archive/cs/cs106b/cs106b.1136/materials/CS106BX-Reader.pdf
// --------------------------------------------------------------------------
//
// Created by Glenn Streiff on 4/3/17
// Copyright © 2017 Glenn Streiff. All rights reserved.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include "map.h"
#include "error.h"
using namespace std;
const std::string HEADER = "CS106B Programming Abstractions in C++: Ex 20.07\n";
const std::string DETAIL = "Integrate f(x) over an x-interval using rectangles";
const std::string BANNER = HEADER + DETAIL;
const std::string PROMPT = "=> ";
const double PI = M_PI;
typedef double (*doubleFn)(double);
typedef Map<std::string, doubleFn> FnMap;
// Function prototypes
double integrate(doubleFn fn, double minX, double maxX, int nRect);
double constantFn(double x);
double linearFn(double x);
void testDriver(const FnMap& testFunctions, double minX, double maxX);
// Main program
int main() {
cout << BANNER << endl << endl;
// Test integrate() against a few different continuous functions.
FnMap testFunctions;
testFunctions["1"] = constantFn;
testFunctions["x"] = linearFn;
testFunctions["sin(x)"] = sin;
double minX = 0;
double maxX = PI;
testDriver(testFunctions, minX, maxX);
return 0;
}
void testDriver(const FnMap& testFunctions, double minX, double maxX) {
cout << "The following functions are numerically integrated" << endl;
cout << "over the domain x = [0, pi], subdividing the region" << endl;
cout << "under the curve with varying numbers of rectangles." << endl;
cout << endl;
cout << "nRect f(x) ⎰f(x)" << endl;
for (std::string fnDesc: testFunctions) {
cout << string(25, '-') << endl;
doubleFn fn = testFunctions[fnDesc];
for (int nRect = 20; nRect <= 100; nRect += 20) {
double value = integrate(fn, minX, maxX, nRect);
cout << setw(3) << right << nRect << " ";
cout << setw(6) << right << fnDesc << " ";
cout << value << endl;
}
}
}
// Function: integrate
// Usage: area = integrate(sin, 0, PI, 20);
// ----------------------------------------
// Returns an approximation to the area under a curve for a given function
// over a specified domain and subdivision factor (number of rectangles).
//
// Approximates the area under a curve by the summation of one or more
// rectangles of fixed width and variable height. The height corresponds
// to the value of the fn evaluated at the midpoint of the rectangle.
double integrate(doubleFn fn, double minX, double maxX, int nRect) {
if (nRect == 0) error("integrate: Division by 0. Need non-zero nRect.");
double result = 0;
double dx = abs(maxX - minX)/double(nRect);
for (int i = 0; i < nRect; i++) {
double xMid = i * dx + dx/2.0;
double rectHeight = fn(xMid);
double rectArea = dx * rectHeight;
result += rectArea;
}
return result;
}
double constantFn(double x) {
return 1;
}
double linearFn(double x) {
return x;
}