For a university assignment I had to plot different polynomial functions depending on one single parameter. That parameter gave the number of supporting points to interpolate a given function in the domain \$\lbrack -1.0, 1.0 \rbrack \$.
The supporting points were to be calculated in two different fashions. Either they were to be equidistant or be Chebyshev nodes. The given definitions were:
$$ x_i = \frac{2i}{n} - 1 , \quad x_i = \cos \frac{(2i + 1)\pi}{2(n + 1)} $$
The plots are to be handed in in a pdf. The polynomial functions I had to calculate were given as:
\$\Phi_n(x) = \underset{i \neq j}{\underset{i = 0}{\overset{n}{\Pi}}} (x - x_i) \$ and the slightly more complicated \$\lambda(x) = \underset{i = 0}{\overset{n}{\Sigma}} \lvert l_{i,n}(x) \rvert \$. Here \$l_{i,n}(x)\$ denotes a Lagrange polynomial. I'll just stop torturing you with math definitions, (because I'm reasonably sure I'm able to copy a formula from a script into code).
Note that \$\Phi_n\$ is called "Supporting point polynomial" and \$\lambda\$ is called "Lebesgue function" in the assignment.
So without further ado, here's my code.
Note that maintainabiltiy for future use is not a concern, so if you want you can mention docstrings and variable names, but those points don't really help me :)
import numpy as np
import matplotlib.pyplot as plt
def equidistant_points(count):
points = []
for i in np.arange(0, count):
points.append((2 * i / count) - 1)
return points
def tschebyscheff_points(count):
points = []
for i in np.arange(0, count):
points.append(np.cos(((2 * i + 1) * np.pi) / (2 * (count + 1))))
return points
def as_supporting_point_poly(points, x):
poly = 1
for point in points:
poly = poly * (x - point)
return poly
def lagrange_poly(points, j, x):
poly = 1
for i in range(0, len(points)):
if (i != j):
poly = poly * ((x - points[i]) / (points[j] - points[i]))
return poly
def lebesgue_function(points, x):
leb = 0
for i in range(0, len(points)):
leb = leb + np.fabs(lagrange_poly(points, i, x))
return leb
def plot_and_save(n, x, poly_calc, name):
equi = plt.plot(x, poly_calc(equidistant_points(n), x), 'r-', label='Äquidistante Stützstellen')
tsch = plt.plot(x, poly_calc(tschebyscheff_points(n), x), 'g-', label='Tschebyscheff-Stützstellen')
plt.xlabel("x")
plt.ylabel("y")
plt.title(name + " mit n = " + str(n))
plt.grid(True)
plt.legend(loc='upper right', shadow=False)
plt.savefig("Aufg1"+ poly_calc.__name__ + str(n) + ".png")
plt.show()
if __name__== '__main__':
domain = np.arange(-1.0, 1.0001, 0.0001)
plot_and_save(8, domain, as_supporting_point_poly, "Stützstellenpolynome")
plot_and_save(20, domain, as_supporting_point_poly, "Stützstellenpolynome")
plot_and_save(8, domain, lebesgue_function, "Lebesgue-Funktion")
plot_and_save(20, domain, lebesgue_function, "Lebesgue-Funktion")
I'm especially interested in ways to make the calculation of the supporting points in equidistant_points
and tschebyscheff_points
cleaner.