Interpolation & Fitten

Interpolieren

Wir bleiben bei den Wasserständen des letzten Blocks. Nehmen wir an, du bekommst folgende Werte für den Tagesverlauf der Wassertiefe im Eingang eines idyllischen, norwegischen Fjords.

minuten = [0 180 500 900 1200 ] tiefe = [6.00 7.50 4.59 7.50 4.70]

Nun möchtest du berechnen, wie tief das Wasser bei 650 Minuten ist. Zum Beispiel um zu wissen, ob du um diese Zeit mit deinem Boot da durchfahren kannst.

Eine Möglichkeit diese Frage zu beantworten ist es, die Werte zu interpolieren. Dafür verwendest du die Befehle interp1 und spline. Beide Befehle haben die gleiche Grundstruktur

yi = interp1(minuten, tiefe, xi)

xi ist ein Vektor mit den Stützstellen, für die du y-Werte berechnet haben möchtest. Du kannst das Resultat also anschliessend mit plot(xi, yi) darstellen. Bei interp1 kannst du zudem mit einem vierten Argument zwischen verschiedenen Methoden wählen. Die Methoden sind alle in der Hilfe kurz beschrieben.

Aufgabe 1

Schreibe ein Skript, das in einer Grafik folgende Dinge darstellt.

Welche Methode gibt die beste Näherung? Was ist damit die Antwort auf unsere Ausgangsfrage?

Lösung Anzeigen

minuten = [0 180 500 900 1200 ]; tiefe = [6.00 7.50 4.59 7.50 4.70] %tiefe = [6.00 7.06 7.39 5.14 4.70] ; xi = 0:50:1200; nearest = interp1(minuten, tiefe, xi, 'nearest'); linear = interp1(minuten, tiefe, xi, 'linear'); pchip = interp1(minuten, tiefe, xi, 'pchip'); spline = interp1(minuten, tiefe, xi, 'spline'); plot(xi, nearest, 'b-') hold on plot(xi, linear, 'g-') plot(xi, pchip, 'c-') plot(xi, spline, 'm-') plot(minuten, tiefe,'rx'); legend('nearest', 'linear', 'pchip', 'spline',... 'data', 'location', 'southwest') xlabel('Zeit /minuten'); ylabel('Tiefe /m'); hold off

Aufgabe 2

Fürs berechnen der Werte wurde ein Sinus mit folgenden Paramtern verwendet. (Das beschreibt Gezeiten natürlich nicht korrekt, reicht aber für unsere Zwecke.)

Zeichne auch diese Funktion ein. Berechne schliesslich die korrekte Antwort und den Fehler der verschiedenen Methoden.

Lösung Anzeigen

% Ergänzung zu Lösung 1 frequenz = 1/(12*60); korrekt = 1.5*sin(2*pi*frequenz*xi)+6; hold on plot(xi, korrekt, 'r+') hold off disp('Abweichungen') zeit = 650 resKorr = 1.5*sin(2*pi*frequenz*zeit)+6; resNear = interp1(minuten, tiefe, zeit, 'nearest'); resLine = interp1(minuten, tiefe, zeit, 'linear'); resPchi = interp1(minuten, tiefe, zeit, 'pchip'); resSpli = interp1(minuten, tiefe, zeit, 'spline'); printf('nearest: %f\n', resNear - resKorr) printf('linear: %f\n', resLine - resKorr) printf('pchip: %f\n', resPchi - resKorr) printf('spline: %f\n', resSpli - resKorr)

Aufgabe 3

Auch für 3 Dimensionen stehen Interpolationsmethoden zur Verfügung. Die folgenden drei Vektoren enthalten Punkte einer Funktion z = f(x,y). Stelle diese Funktion mit Hilfe von mesh, surf und contour da. Verwende dafür je einen eigenen Subplot.

x=[-4:2:4]; y=x; Z = [ 0.4272 0.2720 -0.6536 0.2720 0.4272;... 0.2720 0.1732 -0.4161 0.1732 0.2720;... -0.6536 -0.4161 1.0000 -0.4161 -0.6536;... 0.2720 0.1732 -0.4161 0.1732 0.2720;... 0.4272 0.2720 -0.6536 0.2720 0.4272];

Verwende anschliessend interp2 und griddata um die Funktion zu interpolieren. Zeichne diese Resultate jeweils in einen zusätzlichen Subplot neben/unterhalb des ursprünglichen.

Lösung Anzeigen

x=[-4:2:4]; y=x; Z = [ 0.4272 0.2720 -0.6536 0.2720 0.4272;... 0.2720 0.1732 -0.4161 0.1732 0.2720;... -0.6536 -0.4161 1.0000 -0.4161 -0.6536;... 0.2720 0.1732 -0.4161 0.1732 0.2720;... 0.4272 0.2720 -0.6536 0.2720 0.4272]; [X, Y] = meshgrid(x,y); row = 2; col = 3; plot = 1; subplot(row, col, plot); mesh(X,Y,Z) plot += 1; subplot(row, col, plot); surf(X,Y,Z) plot += 1; subplot(row, col, plot); contour(X,Y,Z) xi=[-4:.5:4]; yi=xi; [Xi, Yi] = meshgrid(xi,yi); plot += 1; subplot(row, col, plot); mesh(Xi, Yi, interp2(x,y,Z,Xi,Yi)) plot += 1; subplot(row, col, plot); surf(Xi,Yi,interp2(x,y,Z,Xi,Yi,'spline')) plot += 1; subplot(row, col, plot); contour(Xi,Yi,griddata(X,Y,Z,Xi,Yi))

Fitten

Eine alternative Möglichkeit um Werte zwischen den gemessenen zu bestimmen, ist es eine Funktoin an die Messwerte zu fitten. Das ist insbesondere dann sinnvoll, wenn du weisst, zu welcher Funktion die Messwerte gehören. Octave kann das leider nur für Polynome, in Matlab kannst du auch selbst definierte Funktionen fitten.

Mit K = polyfit(X,Z,N) kannst du ein Polynom N-ten Grades an die Punkte in X und Y fitten. Der Rückgabewert K ist ein Vektor mit den Koeffizienten des Polynoms. Du kannst das Polynom also anschliessend mit polyval(K,xi) auswerten.

Aufgabe 4

Definiere folgende Vektoren

x= [-5 -4 -1 1 2 3 5]; y= [-5 4 -3 2 -1 0 -3];

Zeichne diese Punkte in ein Koordinatensystem mit x und y zwischen -5.1 und 5.1 und aktiviere die Gitternetzlinien. Fitte anschliessend Polynome mit verschiedenen Graden an diese Punkte. Welche Polynome machen Sinn? Zeichne die Polynome mit verschiedenen Farben in den Plot.

Lösung Anzeigen

x = [-5 -4 -1 1 2 3 5]; y = [-5 4 -3 2 -1 0 -3]; plot(x, y,'rx') grid on hold on degrees = [5 7 9]; xi = -5.1:0.1:5.1; colors = ['g' 'b' 'm' 'c']; col = 1; for deg = degrees coeff = polyfit(x,y,deg); yi = polyval(coeff, xi); plot(xi, yi, colors(col)) col = mod(col,4)+1; end hold off