Finished Exercise 3
This commit is contained in:
parent
759d19d456
commit
bd7e39ca9c
1 changed files with 93 additions and 0 deletions
93
week1/ex3.py
Executable file
93
week1/ex3.py
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Runge's Phenomenon
|
||||
#----------------------------------
|
||||
|
||||
import numpy as np
|
||||
|
||||
def func_to_interpolate(x):
|
||||
return 1/( 1 + 25 * x**2 )
|
||||
|
||||
def equidistant_nodes(n):
|
||||
return 2*np.arange(0,n+1)/n -1
|
||||
|
||||
def chebychev_nodes(n):
|
||||
return np.cos( (2*np.arange(1,n+1) -1) * np.pi / (2*n) )
|
||||
|
||||
def random_nodes(n):
|
||||
return 2*np.random.rand(n) -1
|
||||
|
||||
def main():
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy.interpolate import lagrange as scipy_lagrange
|
||||
|
||||
np.random.seed(0)
|
||||
|
||||
|
||||
n_special = 20
|
||||
n_cheby = n_special
|
||||
n_equi = n_special
|
||||
n_random = n_special
|
||||
|
||||
n_func = 1e4
|
||||
x_func = np.linspace(-1, 1, n_func, endpoint = True )
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
ax.set_title("Lagrange Interpolations with different types of nodes")
|
||||
ax.grid()
|
||||
ax.set_xlabel("x")
|
||||
ax.set_ylabel("y")
|
||||
|
||||
func = func_to_interpolate
|
||||
# Plot the formula
|
||||
ax.plot(x_func, func(x_func), '--', label="Function $1/(1+25x^2)$")
|
||||
|
||||
# Using equidistant nodes
|
||||
x_equi = equidistant_nodes(n_equi)
|
||||
ax.plot(x_equi, scipy_lagrange(x_equi, func(x_equi))(x_equi), '^', label="Equidistant (n={})".format(n_equi))
|
||||
|
||||
# Using chebychev nodes
|
||||
x_cheby = chebychev_nodes(n_cheby)
|
||||
ax.plot(x_cheby, scipy_lagrange(x_cheby, func(x_cheby))(x_cheby), '>',label="Chebyshev (n={})".format(n_cheby))
|
||||
|
||||
# Using random nodes
|
||||
x_random = random_nodes(n_random)
|
||||
ax.plot(x_random, scipy_lagrange(x_random, func(x_random))(x_random), '.', label="Random (n={})".format(n_random))
|
||||
|
||||
|
||||
ax.legend()
|
||||
|
||||
|
||||
print("""
|
||||
Runge's Phenomenon
|
||||
------------------
|
||||
|
||||
According to the docs [1], the scipy Lagrange
|
||||
interpolation is unstable and there should not be more
|
||||
than 20 points.
|
||||
|
||||
|
||||
The region where the equidistant nodes break is near
|
||||
x = -1, where the interpolation is fluctuating between
|
||||
large negative and large positive values. From n > 25,
|
||||
this starts to get visible.
|
||||
|
||||
The chebyshev nodes break near x = 1 when n > 30, where
|
||||
it interpolates the function to be negative.
|
||||
|
||||
Funnily enough, the equidistant nodes vary much more
|
||||
than the chebyshev nodes.
|
||||
|
||||
For the random nodes, you just have be lucky that not
|
||||
too many points are close together at the extremes of
|
||||
the interval.
|
||||
|
||||
[1] = https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.lagrange.html
|
||||
""")
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in a new issue