1
0
Fork 0

Finished Exercise 3

This commit is contained in:
Eric Teunis de Boone 2020-02-12 12:30:56 +01:00
parent 759d19d456
commit bd7e39ca9c
1 changed files with 93 additions and 0 deletions

93
week1/ex3.py Executable file
View 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()