You know, people say they pick their nose.
But I feel like I was just born with mine.
\[ \int_0^1 e^{-x^2} dx \cong 0.746824132812 \]
\[ \small{ \int_a^b f(x)dx \cong \sum_{k=0}^{n-1} f \left( a + h k \right)h, \,\,\, h = \frac{b-a}{n} } \]
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
#Define the function to integrate
#The second function below is taken from book.
def f(x):
#return 1.0*x**2 + 1.0
return np.exp(-x**2)
#Left sum for n rectangles over [a,b]
#n+1 nodes gives n intervals and n rectangles
def leftsum(a,b,n):
h = (b-a)/n
nodes=np.zeros(n+1)
yvalues=np.zeros(n+1)
#Compute nodes and yvalues
for k in range(0,n+1): #from 0 to n
nodes[k] = a + k*h
yvalues[k] = f(nodes[k])
#Initialize S and add up yvalues
S = 0
for k in range(0,n):
S = S + yvalues[k]
#Left sum value
S = h*S
#These lines also indented 4 spaces
#as part of midsum definition.
#Compute Percent Relative Error (PRE)
Q = quad(f,a,b) #[scipy value, error estimate]
Q = Q[0] #scipy value only
PRE = (Q - S)/Q*100 #PRE
print('Q = %.6f, S = %.6f, PRE = %.6f' % (Q, S,PRE))
#Plot commands
plt.plot(nodes,yvalues,'-o')
plt.xlabel('x')
plt.legend(('f'),loc = 0)
plt.show()
S = 0.777817, Q = 0.746824, PRE = -4.149932
S = 0.762474, Q = 0.746824, PRE = -2.095502
import numpy as np
import matplotlib.pyplot as plt
def leftsum(a,b,n):
#Left sum for n rectangles over [a,b]
#n+1 nodes gives n intervals and n rectangles
f = lambda x: np.exp(-x**2) #This is f(x)
nodes=np.linspace(a,b,n+1) #n+1 nodes
xn = nodes[0:n] #n left nodes
fn = f(xn) #left sum y-values
h = (b-a)/n #interval width
S = sum(fn)*h #vectorized sum
print(S)
plt.plot(xn,fn,'-o')
plt.xlabel('x')
plt.legend(('f'),loc = 0)
plt.show()
leftsum(0,1,10)
0.7778168240731773
leftsum(0,1,20)
0.7624738509105875
\[ \small{ \int_a^b f(x)dx \cong \sum_{k=0}^{n-1} f \left( a + h \left(k + \frac{1}{2} \right) \right)h, \,\,\, h = \frac{b-a}{n} } \]
#Midpoint sum for n rectangles over [a,b]
#n+1 nodes gives n intervals and n rectangles
def midsum(a,b,n):
h = (b-a)/n #interval width
nodes=np.zeros(n+1) #initalize nodes
yvalues=np.zeros(n+1)
#Compute nodes and yvalues
for k in range(0,n+1): #from 0 to n
nodes[k] = a + (k+1/2)*h
yvalues[k] = f(nodes[k])
#Initialize S and add up yvalues
S = 0
for k in range(0,n):
S = S + yvalues[k]
#Midpoint sum value
S = h*S
S = 0.747131, Q = 0.746824, PRE = -0.041073
S = 0.746944, Q = 0.746824, PRE = -0.016039
np.linspace(a,b,2n+1) to create
a node vector that includes the endpoints and midpoints, then take every second entry for midpoints.import numpy as np
import matplotlib.pyplot as plt
def midsum(a,b,n):
#Midpoint sum for n rectangles over [a,b]
f = lambda x: np.exp(-x**2) #This is f(x)
N = 2*n+1 #Need this for midpoints
nodes=np.linspace(a,b,N) #2n+1 nodes in [a,b]
xn = nodes[1:N:2] #n midpts (step size = 2)
fn = f(xn) #midpoint y-values
h = (b-a)/n #interval width
S = sum(fn)*h #vectorized sum
print(S)
plt.plot(xn,fn,'-o')
plt.xlabel('x')
plt.legend(('f'),loc = 0)
plt.show()
midsum(0,1,10)
0.7471308777479975
midsum(0,1,20)
0.746900785538085
Use formula for area of trapezoid for each panel, then add up.
\[ \small{ \int_a^b f(x)dx \cong \sum_{k=0}^{n-1} \frac{f(x_k)+f(x_{k+1}) }{2}h, \,\,\,\, x_k = a + h k, \,\,\, h = \frac{b-a}{n} } \]
\[ \small{ T_n = \frac{h}{2}\left[ f(x_0) + 2f(x_1) + 2f(x_2) + \ldots + 2f(x_{n-1}) + f(x_n) \right]} \]
\[ \small{ \int_a^b f(x)dx \cong S_n, \,\,\, h = \frac{b-a}{n} } \]
\[ \small{ S_n = \frac{h}{3}\left[ f(x_1) + 4f(x_2) + 2f(x_3) + 4f(x_4) + 2f(x_5) + \cdots + 4f(x_{n}) + f(x_{n+1}) \right] } \]
#Simpson's Rule for n intervals over [a,b]
#n+1 nodes gives n intervals; n must be even
#Compute nodes and yvalues
for k in range(0,n+1): #from 0 to n
nodes[k] = a + k*h
yvalues[k] = f(nodes[k])
#Prepare summations
S4 = 0
for k in range(1,n,2):
S4 = S4 + 4*yvalues[k]
S2 = 0
for k in range(2,n-1,2):
S2 = S2 + 2*yvalues[k]
#Simpson Rule value
S = S4 + S2 + yvalues[0] + yvalues[n]
S = S*(h/3)
S = 0.746825, Q = 0.746824, PRE = -0.000109
import numpy as np
import matplotlib.pyplot as plt
def Simp(a,b,n):
#Simpson's Rule for n intervals over [a,b]
#n+1 nodes gives n intervals; n must be even
f = lambda x: np.exp(-x**2) #This is f(x)
xn = np.linspace(a,b,n+1) #n+1 nodes
fn = f(xn) #y-values at nodes
h = (b-a)/n #interval width
S = 4*sum(fn[1:n:2]) + 2*sum(fn[2:n-1:2])
S = ( S + fn[0] + fn[n])*(h/3)
print(S)
plt.plot(xn,fn,'-o')
plt.xlabel('x')
plt.legend(('f'),loc = 0)
plt.show()
Simp(0,1,10)
0.7468249482544436
Simp(0,1,20)
0.7468241838759146
\[ \small{ \begin{aligned} O(h^3): E_T &= \frac{h^3}{12n^2}f''(c), \,\,\, E_M = \frac{h^3}{24n^2}f''(c) \\ O(h^5): E_{S_{1/3}} & = \frac{h^5}{180n^4}f^{(4)}(c), \,\,\, E_{S_{3/8}} = \frac{h^5}{405n^4}f^{(4)}(c) \\ \end{aligned} } \]