CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
calculuslab

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: calculuslab/Calculus_Lab
Path: blob/main/142-Labs/Lab 05 - Numerical Integration - The Trapezoidal Rule and Simpson's Rule.ipynb
Views: 491
Kernel: SageMath 9.2

Lab 05 - Numerical Integration: The Trapezoidal Rule and Simpson's Rule

Overview

As we learned in Calculus I, there are two ways to evaluate a definite integral: using the Fundamental Theorem of Calculus or using numerical approximations such as Reimann Sums. While the FTC is nice in theory, it cannnot be applied in many cases, as antiderivatives are often difficult or even impossible to find. With the help of computers, using numerical integration is the most practical way to evaluate definite integrals. In this lab, we will use the Trapezoidal Rule and Simpson's Rule to approximate definite integrals.

Important SageMath Commands Introduced in this Lab

ParseError: KaTeX parse error: Undefined control sequence: \hfill at position 32: …|l|l|} \hline \̲h̲f̲i̲l̲l̲ ̲\textbf{Command…
Section 8.7

In Calculus I, we learned how to use rectangles to approximate the definite integral. Another geometic figure which can be used to approximate the definite integeral is a trapezoid. Recall that the area of a trapzoid is A=12h(b1+b2)A = \frac{1}{2}h(b_1 + b_2). In order to use trapezoids to approximate the definite integral, we subdivide the interval [a,b][a,b] into nn subintervals of equal length Δx=ban\Delta x = \frac{b-a}{n}. Then, on each subinterval we let h=Δxh = \Delta x and b1=f(xi1)b_1 = f(x_{i-1}) and b2=f(xi)b_2 = f(x_i). Thus, the area of the trapzoid in the ithi^\text{th} subinterval is A=Δx2(f(xi1)+f(xi))A = \frac{\Delta x}{2}(f(x_{i-1}) + f(x_i)). Therefore, we have the following approximation of the definite integral using the Trapezoid Rule: abf(x) dxΔx2i=1n(f(xi1)+f(xi)),\displaystyle \int_a^b f(x) \ dx \approx \dfrac{\Delta x}{2}\sum_{i = 1}^{n} \big(f(x_{i-1}) + f(x_i)\big), where nn is the number of trapezoids we are using in our approximation and xi=a+iΔxx_i = a + i \Delta x.

By using trapezoids, we are essentially approximating the curve y=f(x)y=f(x) using piecewise linear functions. In Simpson's Rule, we will instead approximate y=f(x)y = f(x) using piecewise quadratic functions. This time, we start by subdividing the interval [a,b][a,b] into 2n2n subintervals of equal length Δx\Delta x = ba2n\frac{b - a}{2n}. On each pair of subintevals [i1,i][i-1,i] and [i,i+1][i, i+1] with ii odd, we approximate the area spanned by the two subintervals with A=Δx3(f(xi1)+4f(xi)+f(xi+1)A = \frac{\Delta x}{3}(f(x_{i-1}) + 4f(x_i) + f(x_{i+1}). Therefore, we have the following approximation of the definite integral using Simpson's Rule: abf(x) dxΔx3i=0n1(f(x2i)+4f(x2i+1)+f(x2i+2))\displaystyle \int_a^b f(x) \ dx \approx \dfrac{\Delta x}{3} \sum_{i=0}^{n-1} \big( f(x_{2i}) + 4f(x_{2i+1}) + f(x_{2i + 2})\big) where nn is half of the number of subintervals we are using in our approximation and xi=a+iΔxx_i = a + i \Delta x.

Example 1

Let us begin by practicing using lists (or arrays in some programming languages) and for\textbf{for} loops. In order to create a list of elements, simply surround the elements in [   \ ].

fruits = ['apple', 'banana', 'cherry']

We can return specific values of the list by adjoining ParseError: KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: \textbf{[iParseError: KaTeX parse error: Expected 'EOF', got '}' at position 2: ]}̲ immediately after the name of the name of the list. The number ii is refered to as the index which is the position of the element in the list.

Caution:\textbf{Caution:} The starting index of a list is 00, not 11 as you might expect. Therefore, a list which has five elements would use the indices 00 through 44 and not 11 through 55. This is common to most programming languages.

print(fruits[0]) print(fruits[1]) print(fruits[2])

We can adjoin two lists together by using the append\textbf{append} command.

fruits.append('durian') fruits

Caution:\textbf{Caution:} Be careful when appending elements to a list since if you reexecute the above code, fruits\textbf{fruits} will contain two elements of 'durian' .

Note that all of the elements in the list fruit\textbf{fruit} are strings. We can add non-strings to the list as well if we prefer. Also, we can adjoin multiple elements at once by using the extend\textbf{extend} command.

fruits.extend([1, 3/2, 2.5]) fruits

Suppose we wanted to print all of the elements of fruit\textbf{fruit} on individual lines. One way to do this is to have multiple lines containing print statements as we did previously. This method is not ideal, however, if our list contains many elements. A better way to accomplish this is to use a for\textbf{for} loop. If we type the code ParseError: KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: \textbf{"for iParseError: KaTeX parse error: Expected 'EOF', got '}' at position 13: in fruits:"}̲, then SageMath will iterate the variable ii through each element of the list fruits\textbf{fruits}. We can then follow the for\textbf{for} loop with the line "print(i)"\textbf{"print(i)"} which will print the element ii as ii iterates through all of the elements of fruits.\textbf{fruits}.

Note: the variable ii is arbitrary. You can use any letter or word you want as the iterative variable in the for\textbf{for} loop.

for i in fruits: print(i)

Example 2

Create a list called "lst" which contains the numbers 11 through 1010.

One way to do the above is to list all ten numbers from 1 through 10. This is doable, but not if we wanted to list the first one thousand numbers. The command ParseError: KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: \textbf{range(iParseError: KaTeX parse error: Expected 'EOF', got '}' at position 2: )}̲ returns the list containing the numbers 00 through i1i-1. This does not give us exactly the list we want, but we can use this along with a for\textbf{for} loop to create the desired list.

lst = [] for i in range(10): lst.append(i+1) lst

The above code creates a blank list, and then inserts the the numbers which are one more than the elements of $\textbf{range(10)10)}intothelist.Since into the list. Since \textbf{range(1010)}$ was the list containing the numbers 0 through 9, the new list contains the numbers 11 through 1010.

A third way we could do this is to use the range(m,n)\textbf{range(m,n)} command.

lst = range(1,11) lst

If you are using SageMath 9.2 or other versions of SageMath which use Python3, then lstlst did return a list, but instead it just returned the command range(1,11).\textit{range(1,11)}. In order to convert this command into a list, you need to use the ParseError: KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: \textbf{list(\dotsParseError: KaTeX parse error: Expected 'EOF', got '}' at position 2: )}̲ command.

lst = list(range(1,11)) lst

Note that we used range(1,11)\textbf{range(1,11)} to obtain the list of numbers 1 through 10. This is because the range command starts at the first number and stops at the last number minus 1.

Now, add the numbers 11 through 13 to lst\textit{lst}.

Return the sum of the fourth and thirteenth elements of lst\textit{lst}.

Use a for\textbf{for} loop to print the square of each number in lst\textit{lst} on its own line.

If all of the elements in a list are numbers, then you can use the sum\textbf{sum} command to return the sum of all of the elements in the list.

sum(lst)

Example 3

We will use SageMath to approximate 01ex2 dx\displaystyle \int_0^1 e^{-x^2} \ dx using the Trapezoid Rule with n=10n = 10 trapezoids. First, we define our function and assign a,b,n,a, b, n, and Δx\Delta x to their appropriate values.

def f(x): return e^(-x^2) a = 0 b = 1 n = 10 DeltaX = (b-a)/n

Now, we will create a list which contains the summands of our Trapezoid Rule formula. Recall that the Trapezoid Rule is abf(x) dxΔx2i=1n(f(xi1)+f(xi)).\displaystyle \int_a^b f(x) \ dx \approx\dfrac{\Delta x}{2}\sum_{i = 1}^{n} \big(f(x_{i-1}) + f(x_i)\big).

We need to add the terms in the summation to our list. Note that the summation is a sum containing nn terms. Therefore, we will use a for\textbf{for} loop which goes through nn terms. Remember that if we use the ParseError: KaTeX parse error: Unexpected end of input in a macro argument, expected '}' at end of input: \textbf{range(nParseError: KaTeX parse error: Expected 'EOF', got '}' at position 2: )}̲ command, then ii will go from 00 to n1n-1, so we will instead use range(1,n+1)\textbf{range(1,n+1)} to go from 11 to nn.

summands = [] ## Creating a blank list for i in range(1,n+1): summands.append(f(a + (i-1)*DeltaX) + f(a + i*DeltaX)) ## Adding f(x_(i-1)) + f(x_i) to the list

Our list now contains all 1010 of our summands. We can check by calling the name of the list to see what it contains.

summands

We can also have SageMath tell us exactly how many elements a list contains by using the len(lst)\textbf{len}(\textit{lst}) command.

len(summands)

Lastly, we can complete our approximation by adding all of the summands together using the sum\textbf{sum} command and multiplying by Δx2\dfrac{\Delta x}{2}.

TrapApprox = (DeltaX / 2) * sum(summands) TrapApprox

In order to get a comprehensable answer, we can use the round(num, n)\textbf{round}(\textit{num, n}) to round the answer to nn decimal places.

round(TrapApprox, 10)

Therefore, by using the Trapezoid Rule, we get 01ex2 dx0.7462107961.\displaystyle \int_0^1 e^{-x^2} \ dx \approx 0.7462107961.

We can use SageMath to see how close our approximation is to the actual answer.

Answer = integrate(f(x), x, 0,1) Error = abs(Answer - TrapApprox) round(Error, 10)

Therefore, our approximation is accurate to within three decimal places.

Note that, we can combine all of the steps we used to compute the Trapezoid Rule approximation into a single function which will allow us to approximate the definite integral quicker.

def TrapezoidRule(f, a, b, n): DeltaX = (b-a)/n summands = [] ## Creating a blank list for i in range(1,n+1): summands.append(f(a + (i-1)*DeltaX) + f(a + i*DeltaX)) ## Adding f(x_(i-1)) + f(x_i) to the list return (DeltaX / 2.0) * sum(summands)

We have just created a function which accepts arguments ff for our function, aa for our lower bound, bb for our upper bound, and nn for the number of trapezoids. We can check that this function does return what we expect by using it to calculate the Trapezoid Rule approximation we just did in detail.

def f(x): return e^(-x^2) TrapezoidRule(f, 0, 1, 10)

Again, to make sense of this answer, we can use the round\textbf{round} command.

round(TrapezoidRule(f, 0, 1, 10), 10)

Example 4

Now, we will use SageMath to approximate 01ex2 dx\displaystyle \int_0^1 e^{-x^2} \ dx using Simpson's Rule with n=5n = 5.

def f(x): return e^(-x^2) a = 0 b = 1 n = 5 DeltaX = (b-a) / (2*n)

Again, we will create a list which contains all of our summands of our Simpson's Rule formula. Recall that Simpson's Rule is abf(x) dxΔx3i=0n1(f(x2i)+4f(x2i+1)+f(x2i+2)).\displaystyle \int_a^b f(x) \ dx \approx \dfrac{\Delta x}{3} \sum_{i=0}^{n-1} \big( f(x_{2i}) + 4f(x_{2i+1}) + f(x_{2i + 2})\big). Note that this time our summation starts at i=0i = 0 and stops at i=n1i = n-1, so we can use range(n).\textbf{range(n)}.

summands = [] for i in range(n): summands.append(f(a + 2*i*DeltaX)) ## Adding f(x_2i) to summands summands.append(4 * f(a + (2*i + 1)*DeltaX)) ## Adding 4f(x_(2i+1)) to summands summands.append(f(a + (2*i + 2)*DeltaX)) ## Adding f(x_(2i+2)) to summands

Now, we can get our approximation by adding all of the elements in summand and multiplying by Δx3.\dfrac{\Delta x}{3}.

SimpApprox = (DeltaX / 3.0) * sum(summands) SimpApprox
round(SimpApprox,10)

Therefore, Simpson's Rule gives the approximation 01ex2 dx.7468249483.\displaystyle \int_0^1 e^{-x^2} \ dx \approx .7468249483. Now, check how close the approximation is to the actual answer.

It follows that our approximation using Simpson's Rule is accurate to 6 decimal places.

Create the function SimpsonsRule\textbf{SimpsonsRule} which combines all the steps used to estimate the definite integral using Simpson's Rule. Then check that your function gives the same result as above.

def SimpsonsRule(f, a, b, n): ## Insert your code here

Example 5

Use the functions TrapezoidRule\textbf{TrapezoidRule} and SimpsonsRule\textbf{SimpsonsRule} to approximate the following definite integrals with n=4n = 4. Also, determine the abosolute error in each approximation. Remember that in order to use a variable other than xx, you have to define it as a variable using the var\textbf{var} command.

  1. 02(t3+t) dt\displaystyle \int_0^2 (t^3 + t) \ dt

  2. 121s2 ds\displaystyle \int_1^2 \dfrac{1}{s^2} \ ds

  3. 0πsin(t) dt\displaystyle \int_0^\pi \sin(t) \ dt