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

Comparison with Other Methods

Method Convergence (General) Convergence (Periodic)
Trapezoidal
Simpson's
Monte Carlo

Worked examples

Browse all worked examples →