In this exercise, you are tasked with implementing the simple trapezoid rule formula for numerical integration. If we want to compute the definite integral
$$ \int_{a}^{b}f(x)dx $$we can partition the integration interval $[a,b]$ into smaller subintervals. We then approximate the area under the curve for each subinterval by calculating the area of the trapezoid created by linearly interpolating between the two function values at each end of the subinterval:
For a pre-computed $y$ array (where $y = f(x)$ at discrete samples) the trapezoidal rule equation is:
$$ \int_{a}^{b}f(x)dx\approx\frac{1}{2}\sum_{i=1}^{n}\left(x_{i}-x_{i-1}\right)\left(y_{i}+y_{i-1}\right). $$In pure python, this can be written as:
def trapz_slow(x, y):
area = 0.
for i in range(1, len(x)):
area += (x[i] - x[i-1]) * (y[i] + y[i-1])
return area / 2
In [1]:
import numpy as np
x = np.linspace(0, 3, 10)
y = x ** 2
print(x)
print(y)
In [2]:
y_roll_sum = y[:-1] + y[1:]
print(y_roll_sum)
In [3]:
def trapz(x, y):
return 0.5 * np.sum((x[1:] - x[:-1]) * (y[:-1] + y[1:]))
In [4]:
trapz(x, y)
Out[4]:
In [5]:
print(np.trapz(y, x))
Write a function trapzf(f, a, b, npts=100)
that accepts a function f
, the endpoints a
and b
and the number of samples to take npts
. Sample the function uniformly at these
points and return the value of the integral.
Use the trapzf function to identify the minimum number of sampling points needed to approximate the integral $\int_0^3 x^2$ with an absolute error of $<=0.0001$. (A loop is necessary here)
In [6]:
def trapzf(f, a, b, npts=100):
x = np.linspace(a, b, npts)
y = f(x)
return trapz(x, y)
def x_squared(x):
return x ** 2
abs_err = 1.0
n_samples = 0
expected = 9
while abs_err > 0.0001:
n_samples += 1
integral = trapzf(x_squared, 0, 3, npts=n_samples)
abs_err = np.abs(integral - 9)
print('Minimum samples for absolute error less than or equal to 0.0001:', n_samples)