108 lines
2.1 KiB
Python
108 lines
2.1 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# Composite Numerical Integration:
|
||
|
# Trapezoid and Simpson Rules
|
||
|
#---------------------------------
|
||
|
|
||
|
import numpy as np
|
||
|
import scipy.integrate as integrate
|
||
|
|
||
|
def trapz(yk, dx):
|
||
|
""" Trapezoid Integration """
|
||
|
longsum = 2*np.sum(yk[1:-1])
|
||
|
|
||
|
return dx/2 * (longsum + yk[0] + yk[-1])
|
||
|
|
||
|
def test_trapz():
|
||
|
def test_func(x):
|
||
|
return np.exp(x**2 - x**3)
|
||
|
|
||
|
for _ in range(10):
|
||
|
N = 1e1
|
||
|
a = np.random.rand(1)
|
||
|
b = np.random.rand(1)
|
||
|
|
||
|
xk = np.linspace(a, b, N)
|
||
|
|
||
|
yk = test_func(xk)
|
||
|
h = (b-a)/N
|
||
|
|
||
|
assert np.isclose( trapz(yk, h) , integrate.trapz(yk, dx=h), rtol=1/N)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def simps(yk, dx):
|
||
|
""" Integration using Simpson's 1/3 Rule """
|
||
|
even_part = 2*np.sum(yk[2:-2:2])
|
||
|
odd_part = 4*np.sum(yk[1:-1:2])
|
||
|
|
||
|
return dx/3 * ( even_part + odd_part + yk[0] + yk[-1] )
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def main_2a():
|
||
|
N = 1e3
|
||
|
a = 0
|
||
|
b = 2
|
||
|
|
||
|
xk, h = np.linspace(a, b, N, retstep=True)
|
||
|
|
||
|
func = lambda x: np.exp(- x**2 - 1 )
|
||
|
|
||
|
yk = func(xk)
|
||
|
|
||
|
print("My Integrators")
|
||
|
print("Trapz:", trapz(yk,h))
|
||
|
print("Simps:", simps(yk,h))
|
||
|
print()
|
||
|
print("Scipy Integrators")
|
||
|
print("Trapz:", integrate.trapz(yk,dx=h))
|
||
|
print("Simps:", integrate.simps(yk,dx=h))
|
||
|
|
||
|
|
||
|
def main_2b():
|
||
|
import pytest
|
||
|
pytest.main(__file__)
|
||
|
|
||
|
|
||
|
def main_2c():
|
||
|
from matplotlib import pyplot
|
||
|
|
||
|
N = 10
|
||
|
funcs = [ lambda x: x, lambda x: x**2, lambda x: x**(1/2) ]
|
||
|
exact = [ 1/2, 1/3, 3/2 ]
|
||
|
diffs = np.zeros((np.size(funcs), N, 2))
|
||
|
|
||
|
Ns = np.logspace(1,4, N)
|
||
|
for i, f in enumerate(funcs):
|
||
|
for j, n in enumerate(Ns):
|
||
|
xk,h = np.linspace(0, 1, n, retstep=True)
|
||
|
yk = f(xk)
|
||
|
|
||
|
print(i,j)
|
||
|
diffs[i][j][0] = exact[j] - trapz(yk,h)
|
||
|
diffs[i][j][1] = exact[j] - simps(yk,h)
|
||
|
|
||
|
|
||
|
pyplot.subplots()
|
||
|
pyplot.title("Difference between the exact and numeric solution")
|
||
|
pyplot.xlabel("N")
|
||
|
pyplot.ylabel("difference")
|
||
|
pyplot.plot(Ns, diffs[0][:][0], label="Trapz f(x)=x")
|
||
|
|
||
|
pyplot.show()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main_2a()
|
||
|
#main_2b()
|
||
|
#main_2c()
|