3.3.1. Polynominterpolation#
Bei der Interpolation wird eine Modellfunktion gesucht, welche die Messdaten exakt abbildet.
import numpy as np
np.set_printoptions(precision=2, linewidth=65)
import matplotlib.pyplot as plt
plt.rc('figure', dpi=150)
import seaborn as sns
sns.set()
sns.set_style('ticks')
sns.set_context("notebook", font_scale=1.2, rc={"lines.linewidth": 1.2})
Übersicht#
In vielen praktischen Anwendungen werden Polynome als Basisfunktionen der Modellfunktion angenommen. Vorteile von Polynomen:
Polynome sind leicht zu differenzieren und integrieren
Annäherung von beliebigen Funktionen durch Polynome möglich, siehe Taylor-Entwicklung
Auswertung ist sehr einfach und dadurch schnell, d.h. sie benötigt nur wenige schnelle arithmetische Operationen (Addition und Multiplikation)
Ein Beispiel für eine Basis aus Polynomen:
Polynome#
Polynome
Als Grad eines Polynoms wird der Term mit dem höchsten Exponenten und nichtverschwindenden Koeffizienten (der sogenannte Leitkoeffizient) bezeichnet.
Ein Polynom mit Grad
hat , teilweise komplexe, Nullstellen.
In Python, d.h. im numpy-Modul, werden Polynome durch ihre Koeffizienten representiert. Im Allgemeinen wird ein Polynom mit dem Grad
[an, ..., a2, a1, a0]
So z.B. für
P = np.array([1, 5, -2, 3])
print(P)
[ 1 5 -2 3]
Die Auswertung des Polynoms an einem Punkt oder einem Array erfolgt mit der np.polyval
-Funktion.
x = 1
y = np.polyval(P, x)
print(f"P(x={x}) = {y}")
P(x=1) = 7
x = np.array([-1, 0, 1])
y = np.polyval(P, x)
print(f"P(x={x}) = {y}")
P(x=[-1 0 1]) = [9 3 7]
Für die graphische Darstellung im Bereich
x = np.linspace(-6, 2, 50)
y = np.polyval(P, x)
plt.plot(x, y)
plt.xlabel('x')
plt.ylabel('y(x)')
plt.grid();

Um die Nullstellen eines Polynoms zu finden, kann die numpy-Funktion np.roots
genutzt werden. Für das obige Polynom können folgende Nullstellen bestimmt werden.
nstellen = np.roots(P)
# direkte Ausgabe des Arrays
print("Nullstellen: ")
print(nstellen)
Nullstellen:
[-5.47+0.j 0.23+0.7j 0.23-0.7j]
print("Nullstellen: ")
# schönere Ausgabe des Arrays
for i, z in enumerate(nstellen):
if z.imag == 0:
print(f" x_{i+1} = {z.real:.2}")
else:
print(f" x_{i+1} = {z.real:.2} {z.imag:+.2}i")
Nullstellen:
x_1 = -5.5
x_2 = 0.23 +0.7i
x_3 = 0.23 -0.7i
In diesem Beispiel sind zwei der Nullstellen komplex. Eine komplexe Zahl j
, die imaginäre Einheit, gekennzeichnet.
Die Nullstellen können auch zur alternativen Darstellung des Polynoms verwendet werden. Sind
Seien beispielsweise 1 und 2 die Nullstellen eines Polynoms, so lautet dieses:
Die numpy-Funktion np.poly
kann aus den Nullstellen die Polynomkoeffizienten bestimmen. Anhand des obigen Beispiels lautet der Funktionsaufruf:
nstellen = [1, 2]
koeffizienten = np.poly(nstellen)
print("Nullstellen:", nstellen)
print("Koeffizienten:", koeffizienten)
Nullstellen: [1, 2]
Koeffizienten: [ 1. -3. 2.]
Das Modul numpy stellt viele praktische Funktionen zum Umgang mit Polynomen zur Verfügung. So existieren Funktionen um Polynome auszuwerten, die Nullstellen zu finden, zu addieren, zu multiplizieren, abzuleiten oder zu integrieren. Eine Übersicht ist in der numpy-Dokumentation gegeben.
Interpolation#
Interpolation ist eine Methode, um Datenpunkte zwischen gegebenen Messpunkten zu konstruieren. Dazu wird eine Funktion gesucht, die alle Messpunkte exakt abbildet, was gleichbedeutend damit ist, dass die L2-Norm zwischen Funktion und Punkten Null ist.
Zwei Punkte können z.B. mit einer Geraden interpoliert werden. D.h. für zwei Messpunktpaare
verschwindet.
# Beispieldaten aus y(x) = -x + 2
N = 50
dx = 0.25
def fnk(x):
return -x + 2
x = np.array([1, 2])
y = fnk(x)
plt.scatter(x, y, color='C1', label="Messpunkte", zorder=3)
x_modell = np.linspace(np.min(x), np.max(x), N)
plt.plot(x_modell, fnk(x_modell), color='C0', label="Modellfunktion")
x_linie = np.linspace(np.min(x)-dx, np.max(x)+dx, N)
plt.plot(x_linie, fnk(x_linie), '--', alpha=0.3, color='C0')
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.grid();

Für drei Messpunkte muss ein Polynom zweiten Grades verwendet werden, um die Punkte exakt zu erfassen.
# Beispieldaten aus y(x) = 3x^2 -4x - 1
N = 50
dx = 0.25
def fnk(x):
return 3*x**2-4*x - 1
x = np.array([-1, 2, 3])
y = fnk(x)
plt.scatter(x, y, color='C1', label="Messpunkte", zorder=3)
x_modell = np.linspace(np.min(x), np.max(x), N)
plt.plot(x_modell, fnk(x_modell), color='C0', label="Modellfunktion")
x_linie = np.linspace(np.min(x)-dx, np.max(x)+dx, N)
plt.plot(x_linie, fnk(x_linie), '--', alpha=0.3, color='C0')
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.grid();

Dies kann verallgemeinert werden:
Die Existenz und Eindeutigkeit eines solchen Polynoms kann gezeigt werden. Das gesuchte Polynom lautet:
Alternativ kann auch ein Gleichungssystem, welches durch die Polynomialbasis
Das allgemeine Geleichungssystem lautet
und mit der Polynomialbasis
Die Matrix
In Python kann das Interpolationsproblem mit der Funktion np.polyfit
gelöst werden. Das folgende Beispiel demonstriert deren Anwendung.
Die Messtellen folgen in dem Beispiel der Funktion
Zunächst werden die Messpunkte generiert.
def fnk(x):
return 0.5 + 1/(1+x**2)
xmin = -5
xmax = 5
x = np.linspace(xmin, xmax, 100)
y = fnk(x)
n = 5
xi = np.linspace(xmin, xmax, n)
yi = fnk(xi)
Nun folgt die Interpolation für 5 und 15 Messpunkte.
P = np.polyfit(xi, yi, n-1)
print("Interpolationskoeffizienten:")
print(P)
Interpolationskoeffizienten:
[ 5.31e-03 -1.25e-17 -1.71e-01 -3.60e-16 1.50e+00]
plt.plot(x, y, color='C0', alpha=0.5, label='generierende Funktion')
plt.plot(x, np.polyval(P, x), color='C2', label='Interpolation')
plt.scatter(xi, yi, color='C1', label='Messpunkte', zorder=3)
plt.legend()
plt.grid();

n = 15
xi = np.linspace(xmin, xmax, n)
yi = fnk(xi)
P = np.polyfit(xi, yi, n-1)
plt.plot(x, y, color='C0', alpha=0.5, label='generierende Funktion')
plt.plot(x, np.polyval(P, x), color='C2', label='Interpolation')
plt.scatter(xi, yi, color='C1', label='Messpunkte', zorder=3)
plt.legend()
plt.grid();

Die Interpolation erfüllt immer die geforderte Bedingung