Trapezoidal Rule
Numerical Methods
The trapezoidal rule is a simple and widely-used numerical integration method. For periodic functions, it converges exponentially, making it ideal for Fourier coefficient calculations.
Derivation
We start with the integral of a function over an interval :
Using the Fundamental Theorem of Calculus, we approximate by its linear interpolation between and :
Substituting this approximation into the integral gives:
Splitting the integral into two parts and solving:
Evaluating the first integral:
For the second integral, we compute:
Summing both parts:
Factoring :
This results in the basic trapezoidal rule for a single interval:
Formula
For an integral:
The trapezoidal rule with subintervals is:
where is the step size.
Error Analysis
The error for the trapezoidal rule is:
for some . This gives convergence for general functions.
Special case: For periodic functions, the trapezoidal rule converges exponentially, with error for some constant .
C++ Implementation
The following code implements the trapezoidal rule with a template for flexibility:
#include <functional>
#include <cmath>
// Template-based trapezoidal rule
template<typename F>
double trap(F f, double a, double b, int N) {
double h = (b - a) / N;
double s = 0.5 * (f(a) + f(b));
for (int i = 1; i < N; ++i)
s += f(a + i*h);
return s * h;
}
// Function-based version
double trapezoidalRule(double a, double b, double dx,
std::function<double(double)> func) {
size_t points = std::abs(std::ceil((b - a)/dx));
double result = 0.0;
for (int i = 0; i < points - 1; i++) {
result += func(a + i*dx) + func(a + (i+1)*dx);
}
result = result * dx * 0.5;
return result;
}
// Example: Integrate Gaussian
void testGaussianIntegration() {
double alpha = 1.0;
auto gauss = [alpha](double x) {
return std::exp(-alpha * x * x);
};
double analytical = std::sqrt(std::numbers::pi_v<double> / alpha);
// Using template version
double integral1 = trap(gauss, -5.0, 5.0, 10000);
// Using function version
std::function<double(double)> gauss_func = gauss;
double integral2 = trapezoidalRule(-5.0, 5.0, 0.001, gauss_func);
std::cout << "Analytical: " << analytical << std::endl;
std::cout << "Template version: " << integral1 << std::endl;
std::cout << "Function version: " << integral2 << std::endl;
}
// Example: Periodic function (exponential convergence)
void testPeriodicFunction() {
auto periodic = [](double x) {
return std::sin(2.0 * std::numbers::pi_v<double> * x);
};
// Integrate over one period [0, 1]
// Exact result is 0
double integral = trap(periodic, 0.0, 1.0, 100);
std::cout << "Integral of sin(2πx) over [0,1]: " << integral << std::endl;
std::cout << "Error: " << std::abs(integral) << std::endl;
// Error should be very small due to exponential convergence
}
int main() {
testGaussianIntegration();
testPeriodicFunction();
return 0;
} Key Features
- Template version for zero-overhead function calls
- Function-based version for runtime flexibility
- Exponential convergence for periodic functions
- Simple and robust implementation
Comparison with Other Methods
| Method | Convergence (General) | Convergence (Periodic) |
|---|---|---|
| Trapezoidal | ||
| Simpson's | ||
| Monte Carlo |