Skip to content

Kapitel 2

Wir wollen Polynome aus einer Folge von Punkten (xi,yi)(x_i,y_i) interpolieren. Dazu suchen wir eine Basis b(x)jb(x)_j und Koeffizienten αj\alpha_j und schreiben 1nαjb(x)j\sum_1^n \alpha_j b(x)_j.

Um ein Polynom schnell auszuwerten, verwenden wir das Horner Schema. Sei p(x)=anxn++a0p(x) = a_nx^n + \dots + a_0:

R=anR = a_n
for ii from n1n-1 to 00:
R=Rx+aiR = Rx + a_i

Es ist numerisch stabil und läuft in O(n)O(n).

Naive Methode

Ein Polynom von Grad kk ist durch k+1k+1 Punkte (Stützstellen) eindeutig bestimmt. Also können wir für die Punkte ein lineares Gleichungssystem aufstellen und lösen. Diese Methode gibt aber die Vandermode Matrix (mit Einsen in der linken Spalte), welche schlecht konditioniert ist (die Lösung wird stark von numerischen Fehlern beeinflusst).

Da das Polynom durch die Punkte eindeutig ist, geben die anderen Methoden dasselbe Polynom (bei denselben Punkten).

Laufzeit: O(n2)O(n^2) für das lösen des Systems und O(n)O(n) für die Auswertung.

Newton Basis und dividierte Differenzen

Wir wollen nun leicht neue Punkte zum Polynom hinzufügen. Dazu fügen wir zu einem alten Interpolationspolynom einen neuen Term hinzu, welcher 0 ist bei den alten Punkten und bei dem neuen Punkt zum richtigen Wert ausgleicht.

Die Newton-Basis ist Nn(x)=i=0n1(xxi)N_n(x) = \prod_{i=0}^{n-1}(x-x_i). Also z.B.

N0(x)=1,  N1(x)=(xx0),  N2(x)=(xx0)(xx1) N_0(x) = 1, \; N_1(x) = (x-x_0), \; N_2(x) = (x-x_0)(x-x_1)

Wir erhalten so n Basispolynome und die Koeffizienten könnten wir durch ein lineares Gleichungssystem bestimmen.

Besser geht es mit den dividierten Differenzen. Wir schreiben hier für die Interpolationspunkte (xi,yi)(x_i,y_i)

y[a,a]=ya  und  y[a,b]=y[a+1,b]y[a,b1]xbxa y[a,a] = y_a \; \text{und} \; y[a,b] = \frac{y[a+1,b] - y[a,b-1]}{x_b - x_a}

Aus den y mit “Länge” 1 können wir also die y mit “Länge” 2 berechnen und so weiter. Wir machen also DP. Die Koeffizienten sind βj=y[0,j]\beta_j = y[0,j] und ergeben das Polynom

j=0nβjNj(x)=y[0,0]+y[0,1](xx0)+ \sum_{j=0}^n \beta_j N_j(x) = y[0,0] + y[0,1](x-x_0) + \dots

Wenn wir nur O(n)O(n) Speicher verwenden wollen, können wir nur ein Array nehmen und im Durchgang i nur die Elemente ab i ausrechnen und die schon berechneten β\beta stehen lassen (siehe CE 2.1.d):

NewtonCoeffs(x, y):
    n = len(x)
    for j in range(1,n):
        y[j:n] = (y[j:n] - y[j-1:n-1]) /  (x[j:n] - x[:n-j])
    return y

Wir können das Polynom wieder mit einer Idee wie dem Horner-Schema auswerten.

Laufzeit: O(n2)O(n^2) für dividierte Differenzen und O(n)O(n) für die Auswertung und O(1)O(1) für das Hinzufügen neuer Punkte.

Der Fehler ist für n Stützstellen in [a,b] maximal

(ba)n+1f(n+1)(n+1)! (b-a)^{n+1} \frac{\| f^{(n+1)} \|_\infty}{(n+1)!}

Wobei x\|x\|_\infty die maximale Komponente von x ist. (In dem Fall der maximale Funktionswert.) Das folgt aus einer genaueren Schätzung in Theorem 2.2.12 im Skript.

Lagrange und baryzentrische Interpolation

Wir definieren die Lagrange-Polynome

li(x)=j=0,jinxxjxixj l_i(x) = \prod_{j=0, j \neq i}^n \frac{x-x_j}{x_i-x_j}

Diese Polynome haben praktische Eigenschaften:

  • li(xj)=0xjl_i(x_j) = 0 \quad \forall x \neq j
  • li(xi)=1l_i(x_i) = 1
  • deg(li)=ndeg(l_i) = n
  • k=0nlk(m)(x)=1/0\sum_{k=0}^n l_k^{(m)}(x) = 1 / 0 für m=0/m>0m=0/m>0

Wir können dann interpolieren mit

p(x)=j=0nyili(x) p(x) = \sum_{j=0}^n y_il_i(x)

Um zur baryzentrischen Formel zu kommen, schreiben wir

λk=jk1xkxj \lambda_k = \prod_{j \neq k} \frac{1}{x_k - x_j}

und dann

p(x)=k=0nλkxxkykk=0nλkxxk p(x) = \frac{\sum_{k=0}^n \frac{\lambda_k}{x-x_k} y_k}{\sum_{k=0}^n \frac{\lambda_k}{x-x_k}}

Laufzeit: O(n2)O(n^2) für das Berechnen der λk\lambda_k und dann O(n)O(n) für eine Auswertung. Ein paar neue Punkte lassen sich in O(n)O(n) hinzufügen.

Für den Fehler definieren wir die Lebesgue-Konstante Λn\Lambda_n. Mit ihr schätzen wir die Auswirkung von Messfehlern ab. Bei der Runge-Funktion f(x)=1/(x2+1)f(x) = 1/(x^2+1) treten starke Fehler and den Rändern des Intervalls auf bei äquidistanten Stützstellen. Wir sollten diese also niemals für Polynome hohen Grades verwenden. Die Wahl der Stützstellen beeinflusst den Fehler.

Chebyshev Interpolation

Wir wollen nun bessere Stützstellen als äquidistante Punkte finden. Wir definieren die Chebyshev-Polynome Tn(x)T_n(x) und Un(x)U_n(x). Dann sind die n+1 Chebyshev-Knoten auf [a,b] für k=0,,nk = 0, \dots, n

xk=a+12(ba)(cos(2k+12(n+1)π)+1) x_k = a + \frac{1}{2} (b-a) (\cos \left( \frac{2k+1}{2(n+1)} \pi \right) + 1)

Die Chebyshev-Abszissen sind

xk=a+12(ba)(cos(knπ)+1) x_k = a + \frac{1}{2} (b-a) (\cos \left( \frac{k}{n} \pi \right) + 1)

Wenn wir bei den Abszissen die Endpunkte auslassen wollen, gehen wir nur über k=1,,n1k = 1,\dots,n-1

Die Wahl der Chebyshev-Knoten minimiert den Fehler. Die Chebyshev-Abszissen beinhalten die Chebyshev-Knoten (sehr vereinfacht) und werden deshalb in der Praxis verwendet.

Das Chebyshev-Interpolationspolynom ist dann

p(x)=c0+c1T1(x)++cnTn(x) p(x) = c_0 + c_1T_1(x) + \dots + c_nT_n(x)

Die ckc_k können wir mit der Formel im Skript berechnen. Wenn wir die Koeffizienten haben, können wir p(x)p(x) sehr stabil mit dem Clenshaw-Algorithmus berechnen. Wir setzen dn+2=dn+1=0d_{n+2} = d_{n+1} = 0 und die Rekursion

dk=ck+(2x)dk+1dk+2 d_k = c_k + (2x)d_{k+1} - d_{k+2}

und erhalten p(x)=d0xd1=12(d0d2)p(x) = d_0 - xd_1 = \frac{1}{2} (d_0 - d_2).