Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

 Open In Colab

Left and Right Riemann Integrals

Riemann’'s integral is the simplest of the Newton-Cotes formulae with a polynomial of degree 0, i.e. a constant over each subdivision. Variants exist depending on which point in the subdomain [xi,xi+1][x_i, x_{i+1}] is chosen to evaluate the constant.

If we take the function value at the left of the subdomain [xi,xi+1][x_i, x_{i+1}], we obtain the left Riemann integral:

∫abf(x) dx≈∑i=0n−1f(xi)h\int_a^b f(x) \,\mathrm{d}x \approx \sum_{i=0}^{n-1} f(x_i) h

Conversely, if we take the function value at the right limit, we obtain the right Riemann integral:

∫abf(x) dx≈∑i=1nf(xi)h\int_a^b f(x) \,\mathrm{d}x \approx \sum_{i=1}^{n} f(x_i) h
numerical_integration_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def left_riemann(f, a, b, n):
    h = (b - a) / n
    x_left = np.linspace(a, b - h, n)
    y_left = f(x_left)
    integral_approx = np.sum(y_left * h)

    return {
        "x_left": x_left,
        "y_left": y_left,
        "n": n,
        "integral_approx": integral_approx,
        "a": a,
        "b": b,
        "h": h,
    }

numerical_integration_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def right_riemann(f, a, b, n):
    h = (b - a) / n
    x_right = np.linspace(a + h, b, n)
    y_right = f(x_right)

    integral_approx = np.sum(y_right * h)

    return {
        "x_right": x_right,
        "y_right": y_right,
        "n": n,
        "integral_approx": integral_approx,
        "a": a,
        "b": b,
        "h": h,
    }

Error Analysis of One-Sided Riemann Sums

To analyze the error, consider integrating the Taylor expansion of the left integral (the right being trivially similar):

f(x)=f(xi)+f′(xi)h+O(h2)∫xixi+1f(x) dx=∫xixi+1[f(xi)+f′(xi)h+O(h2)] dx=f(xi)h+f′(xi)h22+O(h3)=f(xi)h+O(h2)\begin{aligned} f(x) &= f(x_i) + f'(x_i) h + O(h^2) \\ \int_{x_i}^{x_{i+1}} f(x) \,\mathrm{d}x &= \int_{x_i}^{x_{i+1}} [f(x_i) + f'(x_i) h + O(h^2)] \,\mathrm{d}x \\ &= f(x_i) h + f'(x_i) \frac{h^2}{2} + O(h^3) \\ &= f(x_i) h + O(h^2) \end{aligned}

The truncation error per element is O(h2)O(h^2). Since there are n=(b−a)/hn = (b-a)/h elements, the global composite error scales as:

Ecomposite=∑i=0n−1O(h2)=n⋅O(h2)=O(h)E_{composite} = \sum_{i=0}^{n-1} O(h^2) = n \cdot O(h^2) = O(h)

making left and right Riemann sums first-order accurate.

The Midpoint Riemann Integral

Rather than favor the left or right subdomain limit, let’'s take the midpoint yi=xi+1+xi2y_i = \frac{x_{i+1} + x_i}{2}. The Midpoint Rule states:

∫abf(x) dx≈∑i=0n−1f(yi)h\int_a^b f(x) \,\mathrm{d}x \approx \sum_{i=0}^{n-1} f(y_i) h
numerical_integration_module.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def midpoint_riemann(f, a, b, n):
    h = (b - a) / n
    x_mid = np.linspace(a + h / 2, b - h / 2, n)
    y_mid = f(x_mid)

    integral_approx = np.sum(y_mid * h)

    return {
        "x_mid": x_mid,
        "y_mid": y_mid,
        "n": n,
        "integral_approx": integral_approx,
        "a": a,
        "b": b,
        "h": h,
    }

Example: Midpoint Approximation of sin⁡(x)\sin(x)

Approximate ∫0πsin⁡(x) dx=2\int_0^\pi \sin(x) \,\mathrm{d}x = 2 using the Midpoint rule across 8 subdivisions:

Error Analysis: Second-Order Midpoint Accuracy

The error can be deduced considering the Taylor series of f(x)f(x) around the midpoint yiy_i:

f(x)=f(yi)+f′(yi)(x−yi)+f′′(yi)2(x−yi)2+O(h3)∫xixi+1f(x) dx=∫yi−h/2yi+h/2[f(yi)+f′(yi)(x−yi)+f′′(yi)2(x−yi)2+O(h3)] dx\begin{aligned} f(x) &= f(y_i) + f'(y_i)(x - y_i) + \frac{f''(y_i)}{2}(x - y_i)^2 + O(h^3) \\ \int_{x_i}^{x_{i+1}} f(x) \,\mathrm{d}x &= \int_{y_i - h/2}^{y_i + h/2} \left[f(y_i) + f'(y_i)(x - y_i) + \frac{f''(y_i)}{2}(x - y_i)^2 + O(h^3)\right] \,\mathrm{d}x \end{aligned}

Because the integration limits are symmetric around yiy_i, the odd term vanishes: ∫−h/2h/2(x−yi) dx=0\int_{-h/2}^{h/2} (x - y_i) \,\mathrm{d}x = 0.

Integrating the quadratic term yields:

∫xixi+1f(x) dx=f(yi)h+f′′(yi)24h3+O(h5)\int_{x_i}^{x_{i+1}} f(x) \,\mathrm{d}x = f(y_i) h + \frac{f''(y_i)}{24} h^3 + O(h^5)

Summing across all nn subdivisions gives a composite error of O(h2)O(h^2), a full order of accuracy higher than one-sided Riemann sums!

Note: If you only have discrete data measured at points xix_i, you cannot evaluate f(yi)f(y_i) without interpolating between samples.