Motivation
Motivation¶
Examples¶
Example: Area of a Rectangle¶
The formula we’ve all learned for a rectangle is that the area is equal to the length of the base times the height:
We need to develop a general framework for working with areas, and we’ll take this as a starting point. As an example, let’s say the length is 5 and the height is 3. We can model this using the function :

Now we can say that the area of the rectangle is the area between the curve , the -axis, and .
In general, this means that our area function should have the property that for any constant ,
Example: Triangles¶
We also know how to find the area of triangles: . For simplicity, let’s stick with right triangles--any triangle can be broken up into right triangles. To model the triangle we can use
. For instance, if we take and , we have

Example: Trapezoids¶
We also know how to find the area of trapezoids: . For simplicity, let’s stick with right trapezoids--any trapezoid can be broken up into right trapezoids. To model the trapezoid we can use
. For instance, if we take and , we have

from this, we deduce the property that
Quadratics¶
What about something a little more interesting though?

Basic geometry can’t help us with something which curves all the time like this. Let’s see how far we can get though with some basic geometry.

We can approximate the area using rectangles like above.
a = 0; b = 2
f = lambda x: x**2
for number_of_rectangles in [2, 10, 100, 1_000, 100_000, 10**6]:
approximation = sum( f( (b-a)/number_of_rectangles * i + a )*(b-a)/number_of_rectangles
for i in range(number_of_rectangles)
)
print(f"N: {number_of_rectangles:,}, approximation: {approximation}")N: 2, approximation: 1.0
N: 10, approximation: 2.2800000000000007
N: 100, approximation: 2.626800000000001
N: 1,000, approximation: 2.6626680000000027
N: 100,000, approximation: 2.6666266667999796
N: 1,000,000, approximation: 2.66666266666797
It seems like we’re getting close to . Let’s see how far we can get algrebraically.
import math
s_0 = lambda n: n
s_1 = lambda n: 1/2 * n**2 + 1/2 * n
s_2 = lambda n: 1/3*n**3+1/2*n**2+1/6*n
plot_function_with_axes(
"Plot of Riemann Sum for $f(x)=x^2$",
lambda n: math.comb(2,0)*( (b-a)/n )*a**2*s_0(n-1)+
math.comb(2,1)*( (b-a)/n )**2*a**1*s_1(n-1)+
math.comb(2,2)*( (b-a)/n )**3*a**0*s_2(n-1)
,
(-1,100),
(-1,3)
)



# assuming you have setup_calc_axes(...) from earlier
g = lambda x: np.sin(x) + 0.8
fig, ax = plt.subplots(figsize=(6,4))
setup_calc_axes(ax, xlim=(0, 2*np.pi), ylim=(-0.8, 2.2))
S = plot_riemann_with_error(
ax, g, a=0, b=2*np.pi, n=10, method='midpoint',
rect_face='none', rect_edge='k', rect_lw=1.2,
error_color='red', error_alpha=0.35, curve_first=False
)
ax.set_title("Riemann sum with error regions (midpoint rule, n=10)")
plt.show()
a = 1
b = 3
xs = np.linspace(a, b, 50)
def f(x):
return x**2
plt.plot(xs, [x**2 for x in xs]);