|
Autor |
Baryzentrische Polynominterpolation |
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Themenstart: 2016-05-09
|
Guten Abend zusammen,
ich knobel schon ewig an folgender Aufgabe herum:
a) schreibe eine Fkt. lam = baryGew(x) zur Bestimmung der baryz. Gewichte lambda(i). x sei Vektor mit Stützstellen. Ausgabe liefert die Gewichte lambda(i).
=> das habe ich noch komplett hinbekommen.
b) schreibe Fkt. y = bary(X,x,f,lam). X sei Vektor, an dessen Stellen das Polynom ausgewertet wird, x sei Vektor der Stützstellen mit Wertevektor f, lam die Gewichte.
\sourceon Matlab
function y = bary(X,x,f,lam)
m=length(X);
y=zeros(m,1);
for i=1:m
ind=find(x(i)==X(i));
if isempty(ind)
v=lam./(X(i)-x(i));
y(i)=sum(f.*v)/sum(v);
else
y(i)=f(ind);
end
end
\sourceoff
=> soweit meckert Matlab nicht, allerdings bekomme ich bei nem Test mit "humanen" Eingaben ne Zahl "hoch 16" raus, was mich irritiert. Ist da evtl n Fehler, der den Algorithmus in eine falsche Richtung steuert?
c)Teste die obigen Algorithmen mit f(x)=sin(100x), x = [-1,1]
an den Stützstellen x(i) = 2i/n - 1 bzw. den Tschebyscheff-Knoten x(j) = cos((2j+1)*Pi/(2n+2))
Stelle die Ergebnisse für n=500, x=[0 0.5] graphisch dar. Verwende 400 Punkte für die Darstellung
\sourceon Matlab
f1 =@(x) sin(100*x);
n=500;
for i=1:500
x1(i)=(2*(i-1)/n)-1; %Stützst. (i)
end
for j=1:500
x2(j)=cos((2*(j-1)+1)*pi/(2*n+2)); %Tsch.-Knoten x(j)
end
xs=linspace(0,0.5,n);
Y1 = f1(x1);
Y2 = f1(x2);
lam1=baryGew(x1); %Gewichte zu x(i)
lam2=baryGew(x2); %Gewichte zu x(j)
figure;
hold on;
plot(x1,Y1,'r-'); PLOT1
plot(x1,bary(xs,x1,f1(x1),lam1),'ko');
axis equal;
hold on;
plot(x2,Y2,'b*'); PLOT2
plot(x2,bary(xs,x2,f1(x2),lam2),'ko');
axis equal;
\sourceoff
=> hier plottet Matlab die Plots mit der bary-Fkt. nicht, ich bekomme die 400 Punkte-Darstellung nicht hin und die Plots die ich mit PLOT1 und PLOT2 bezeichnet habe sind komplett identisch (kann das stimmen?).
Kann wer helfen?
Vielen Dank schonmal :)!
Gruß, nickel
|
Profil
|
Kitaktus
Senior  Dabei seit: 11.09.2008 Mitteilungen: 7234
Wohnort: Niedersachsen
 | Beitrag No.1, eingetragen 2016-05-10
|
Hallo nickel,
1) Wenn Du die Umgebung "Quelltextbereich" unterhalb des Editierfensters anklickst und nameDerSprache durch Matlab ersetzt, kannst Du Deinen Quellcode schöner darstellen.
2) Um einen Fehler nachzuvollziehen, ist es immer schön, wenn Du konkrete Werte für die Variablen angibst. Dann kann man sich den Code kopieren, mit den Werten laufen lassen und vergleichen, was passiert.
Es passiert immer wieder, dass sich vermeintliche Fehler nicht reproduzieren lassen. Zum Teil liegt es an Versionsunterschieden, zum Teil aber auch an versteckten Umdefinitionen von Konstanten und Funktionen oder auch daran, dass der gepostete Code nicht mit dem getesteten Code übereinstimmt.
3) Ohne tiefer in Dein Problem eingestiegen zu sein, fällt mir eine Zeile ins Auge: find(x(i)==X(i));
Ich bin mir ziemlich sicher, dass Du etwas anderes willst, entweder
find(x==X(i)); oder find(x(i)==X); Wahrscheinlich das erste.
Auch in der Zeile v=lam./(X(i)-x(i)); soll es wahrscheinlich v=lam./(X(i)-x); heißen.
Probiere das mal aus. Vielleicht erledigt sich dann auch die zweite Frage.
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.2, vom Themenstarter, eingetragen 2016-05-10
|
Vielen Dank für die Info. Ich habe es abgeändert, und jetzt kann ich das Programm für b) auch korrekt anwenden.
Bleiben noch die Plots:
\sourceon Matlab
f1 =@(x) sin(100*x);
n=500;
for i=1:500
x1(i)=(2*(i-1)/n)-1; %generiert Vektor mit geforderten Stützstellen x(i)
end
for j=1:500
x2(j)=cos((2*(j-1)+1)*pi/(2*n+2)); %generiert Vektor mit Tschebyscheff-Knoten x(j)
end
xs=linspace(0,0.5,n);
Y1 = f1(x1); %Stützstellen x(i) in f eingesetzt
Y2 = f1(x2); %Stützstellen x(j) (Tschebyscheff-Knoten) in f eingesetzt
lam1=baryGew(x1); %baryz. Gew. bzgl. Stützstellen x(j)
lam2=baryGew(x2); %baryz. Gew. bzgl. Stützstellen x(j)
figure;
hold on;
plot(x1,Y1,'r-') %Funktion geplottet
plot(x1,bary(xs,x1,f1(x1),lam1),'ko') %Polynom geplottet
axis equal;
hold on;
plot(x2,Y2,'b*')
plot(x2,bary(xs,x2,f1(x2),lam2),'ko')
axis equal;
\sourceoff
Matlab plottet mir eine rote Sinuskurve gemäß f und den Plot mit blauen Sternchen. Die Plots sind identisch wie es aussieht und die Plots mit der "bary"-Fkt. werden offenbar nicht mitgeplottet.
Sieht für mich nicht gerade richtig aus......
ich bin mir auch unsicher, ob ich den Vektor xs und x1 bzw. x2 richtig benutze im Plotbefehl.
Gemäß Aufgabenstellung c) fehlt da wohl noch einiges....
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11650
Wohnort: Wien
 | Beitrag No.3, eingetragen 2016-05-10
|
Hallo nickel,
es ist natürlich auch der Verlauf der Interpolationspolynome zwischen den Stützpunkten interessant. Verwende n Stützstellen (für den Anfang würde ich es mit viel kleineren Werten, etwa n=10 versuchen) und m=400 Punkte, die gleichmäßig auf das Intervall [0,0.5] aufgeteilt werden (dazu hast Du ja schon den Vektor xs berechnet).
Für das Plotten der Polynome musst Du dann xs für die x-Werte und die an diesen Stellen ausgewerteten Polynome als y-Werte verwenden.
Ich hoffe, das hilft Dir,
Roland
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.4, vom Themenstarter, eingetragen 2016-05-11
|
Nun habe ich
\sourceon Matlab
f1 =@(x) sin(100*x);
n=10;
for i=1:n
x1(i)=(2*(i-1)/n)-1; %generiert Vektor mit geforderten Stützstellen x(i)
end
for j=1:n
x2(j)=cos((2*(j-1)+1)*pi/(2*n+2)); %generiert Vektor mit Tschebyscheff-Knoten x(j)
end
xs=linspace(0,0.5,n);
Y1 = f1(x1); %Stützstellen x(i) in f eingesetzt
Y2 = f1(x2); %Stützstellen x(j) (Tschebyscheff-Knoten) in f eingesetzt
lam1=baryGew(x1); %baryz. Gew. bzgl. Stützstellen x(j)
lam2=baryGew(x2); %baryz. Gew. bzgl. Stützstellen x(j)
figure;
hold on;
plot(x1,Y1,'r-') %Funktion geplottet
plot(x1,bary(xs,x1,f1(x1),lam1),'k-') %Polynom geplottet
axis equal;
hold on;
plot(x2,Y2,'b--')
plot(x2,bary(xs,x2,f1(x2),lam2),'g--')
axis equal;
\sourceoff
Das liefert den folgenden Graphen (n=10):
http://www.matheplanet.com/matheplanet/nuke/html/uploads/a/22808_Plot1.jpg
wenn ich das n z.B. (wie verlangt) auf 400 setze kommen identische Sinuskurven heraus:
http://www.matheplanet.com/matheplanet/nuke/html/uploads/a/22808_Plot2.jpg
und für n=50 kommt nur ein roter, völlig deformierter Graph heraus.
Und wenn ich die Stützstellen weniger zahlreich bilde (etwa x=1:10), dann aber wie gefordert xs mit 400 Punkten darstelle bekomme ich Probleme weil die Vektoren zum Ploten nicht die gleiche Länge haben.
Leider bekommen wir für die Aufgabe nur einen Punkt wenns perfekt läuft :/
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11650
Wohnort: Wien
 | Beitrag No.5, eingetragen 2016-05-11
|
Hallo nickel,
Du solltest zwischen der Anzahl n der Stützstellen und der Anzahl m der gezeichneten Punkte unterscheiden. Ich habe leider übersehen, dass die Funktion f1 so schnell schwankt, dass mit n < 200 keine brauchbaren Interpolationspolynome zu erwarten sind.
Mit
\sourceon Matlab
m=400;
xs=linspace(0,0.5,m);
% ...
plot(xs,bary(xs,x1,f1(x1),lam1),'k-') %Polynom geplottet
% ...
plot(xs,bary(xs,x2,f1(x2),lam2),'g--')
\sourceoff
solltest Du die gewünschten Plots erhalten.
Ich hoffe, das hilft Dir,
Roland
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.6, vom Themenstarter, eingetragen 2016-05-11
|
Ahh das klappt schon besser, danke :)
http://www.matheplanet.com/matheplanet/nuke/html/uploads/a/22808_Plot4.jpg
hier sieht man im Intervall [0, 0.5] ja schön, wie die bary-Prozedur (gestrichelte Graphen) die Funktion interpoliert und somit annähert.
Ich hoffe, dass das die Aufgabenstellung jetzt erfüllt??!
Mich irritiert nur noch sehr, dass man laut Aufgabenstellung die Ergebnisse für n=500 darstellen soll, obwohl ich dann ja Sinuskurven mit extrem kurzer Periodenlänge bekomme (wegen sin(100x)) und ich hier in der Graphik garkeinen Unterschied mehr erkennen kann zwischen den Funktions- und Polynomgraphen (s. unterer Plot in meinem letzten Beitrag).
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11650
Wohnort: Wien
 | Beitrag No.7, eingetragen 2016-05-11
|
Hallo nickel,
ich würde die Verbindungslinien zwischen den Stützpunkten weglassen, also
\sourceon Matlab
plot(x1,Y1,'r.')
% ..
plot(x2,Y2,'b.')
\sourceoff
verwenden.
Kann es sein, dass ein kleinerer Ausschnitt dargestellt werden sollte, etwa so?
\quoteon
Stelle die Ergebnisse für n=500, x=[0 0.05] graphisch dar. Verwende 400 Punkte für die Darstellung.
\quoteoff
Servus,
Roland
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.8, vom Themenstarter, eingetragen 2016-05-11
|
Nein, es heißt wörtlich "stellen Sie die Ergebnisse für n=500, x Elem. [0, 0.5] graphisch dar. Verwenden Sie 400 Punkte für die Darstellung."
Betrachtet werden soll die Funktion f(x) = sin(100x), x Elem. [-1, 1].
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11650
Wohnort: Wien
 | Beitrag No.9, eingetragen 2016-05-11
|
Hallo nickel,
die Funktion f hat die Periode $P=\frac{2\pi}{100}\approx 0.0628$, im Intervall $0
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.10, vom Themenstarter, eingetragen 2016-05-11
|
Differenzen plotten macht Matlab nicht weil die Matrixdimensionen nicht übereinstimmen.....
Durch die axis-Änderungen erhalte ich nun für n=500 immerhin einen anschaulicheren Plot:
http://www.matheplanet.com/matheplanet/nuke/html/uploads/a/22808_Plot5.jpg
Hab das jetzt mal als Alternativlösung in einer anderen Datei gespeichert und schicke im Zweifel einfach beide Mögl. ein.
Man sieht ja in den Extremstellen Abweichungen immerhin.
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.11, vom Themenstarter, eingetragen 2016-05-11
|
Einer der Tutoren hat mir gerade übrigens geschrieben, dass meine Funktion für die Gewichte falsch wäre.
Habe eine händisch errechnete Aufgabe getestet und ich bekomme dasselbe raus.
Jetzt bin ich erst recht verwirrt... dachte dass wenigstens das korrekt wäre.
\sourceon Matlab
function lam = baryGew(x)
n=length(x);
lambda=zeros(1,n);
lambda(1)=1;
for k=2:n
for i=1:k-1
lambda(i)=lambda(i)/(x(i)-x(k));
lambda(k)=lambda(k)-lambda(i);
end
end
lam=lambda;
\sourceoff
|
Profil
|
Kitaktus
Senior  Dabei seit: 11.09.2008 Mitteilungen: 7234
Wohnort: Niedersachsen
 | Beitrag No.12, eingetragen 2016-05-12
|
Der Code sieht sehr verdächtig aus. Kannst Du mal verbal oder in Formeln aufschreiben, wie die Gewichte berechnet werden.
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.13, vom Themenstarter, eingetragen 2016-05-12
|
Offenbar sollen wir die Gewichte nach der Formel
lam(j) = 1/[(x(j)-x(1))*(x(j)-x(2))*....*(x(j)-x(n))]
implementieren. Sozusagen der Kehrwert einer Produktkette aus den Differenzen der Stützstellen.
Habe ich heute dank einem Kommilitonen auch endlich
hinbekommen.
Die andere Formel liefert zwar dieselben Werte, sollten wir aber nicht
verwenden da wir ja die baryzentrische Darstellung nutzen sollten.
|
Profil
|
nickel
Ehemals Aktiv  Dabei seit: 21.05.2008 Mitteilungen: 27
 | Beitrag No.14, vom Themenstarter, eingetragen 2016-05-13
|
Ich habe die Aufgabe jetzt eingereicht und bedanke mich für eure schnelle Hilfe!
|
Profil
|
nickel hat die Antworten auf ihre/seine Frage gesehen. nickel hat selbst das Ok-Häkchen gesetzt. | nickel wird per Mail über neue Antworten informiert. |
|
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2023 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen. Lesen Sie die
Nutzungsbedingungen,
die Distanzierung,
die Datenschutzerklärung und das Impressum.
[Seitenanfang]
|