P4 - Testcase?

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

kurz nach der Nachricht von Stumpf.Alex kam ja auch ein update(die Angabe 10.1 ist falsch). Das Problem ist nur, dass dieser Testcase auch noch nicht fehlerfrei ist.

Stumpf.Alex
Nerd
Nerd
Beiträge: 645
Registriert: 1. Okt 2007 12:40
Wohnort: Darmstadt
Kontaktdaten:

Re: P4 - Testcase?

Beitrag von Stumpf.Alex »

Das "demnächst"-Update ist bereits am 19.01. vorgenommen worden. Entschuldigt bitte, dass sich dort ein kleiner Tippfehler, also Updatedatum auf 10.01. anstelle 19.01., eingeschlichen hat.
Der Testcase ist in dieser Fassung maßgeblich und zur Aufgabenstellung passend.

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

if ((size(P4b,'c') == 18) & (size(P4a,'r') == 6))

also das "P4a" ist schonmal sicherlich nicht richtig.

f_jakob
Mausschubser
Mausschubser
Beiträge: 50
Registriert: 27. Okt 2009 14:05

Re: P4 - Testcase?

Beitrag von f_jakob »

Ich beschäftige mich jetzt schon eine ganze Weile mit Aufgabenteil b), komme aber nicht auf die Werte, die im Testcase gefordert werden. Meine Hoffnung war die ganze Zeit, dass der Testcase noch fehlerhaft ist. Da er das ja scheinbar nicht ist, interpretiere ich wohl die Aufgabenstellung falsch...

Hier mal meine Interpretation für Aufgabe b):
Zuerst wenden wir das implizite Eulerverfahren an und approximieren uns ein \(c_{k+1}\).
Danach jagen wir dieses \(c_{k+1}\), das aktuelle \(h_k\) und das alte \(c\) durch \(K\).
Anhand von diesem \(K\) machen wir eine exklusive Fallunterscheidung, d.h. entweder der Teil mit \(K > \delta_2\) oder der Teil mit \(K < \delta_1\) oder \(\delta_1 \leq K \leq \delta_2\) wird ausgeführt.
Fall \(K > \delta_2\):
\(h_k\) wird halbiert. Mit diesem neuen \(h_k\) approximieren wir uns ein neues \(c_{k+1}\), aber noch vom alten \(c\) aus gehend. Jetzt berechnen wir uns wieder \(K\) und schauen nun, ob \(K \leq \delta_2\). Wenn nicht, dann wiederholen wir das solange, bis es passt. Die passenden Werte sind dann unsere endgültigen Werte für diesen Schritt. Wir fügen also \(c_{k+1}\) mit \(t = t + h_k\) zu unseren Werten hinzu.
Fall \(K < \delta_1\):
Wir behalten das \(c_{k+1}\) für \(t = t + h_k\), aber beim nächsten Durchlauf arbeiten wir mit \(2 \cdot h_k\).
Fall \(\delta_1 \leq K \leq \delta_2\):
Wir behalten auch \(c_{k+1}\) für \(t = t + h_k\) und ändern nichts an der Schrittweite.

Ist diese Interpretation korrekt? Falls nein, wo liegt der Fehler?

Nachtrag:
Wenn ich das implementiere hat meine Matrix im Testfall 1495 Spalten, also deutlich mehr als die geforderten 18. Meine zweite Spalte ist
0.0600000
0.0000003
3.061D-10
0.0300000
2.636D-08
0.0195313

Wenn ich die beiden \(\delta\)-Werte auf 10e-8 setze, hat die Matrix nur noch 5 Spalten, wobei die zweite Spalte folgenden Wert hat:
0.0600000
0.0000003
4.450D-11
0.0300000
2.542D-08
1.25

Also ein deutlicher Unterschied für eine Zehnerpotenz. Gibt es evt. große Genauigkeitsunterschiede bei den Werten die fsolve auf verschiedenen Architekturen / Versionen von Scilab liefert? Mein System: Linux 2.6.28-17-generic #58-Ubuntu SMP i686. Scilab Version ist 5.1 (6. März 2009)

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

Sieht gut aus, was du da geschrieben hast.
Das Problem liegt offensichtlich an fsolve(), wenn du den 1. Parameter anders bestimmst, wirst du etwas andere Lösungen bekommen.
Und das kann einen sehr großen einfluss auf die Dimension haben, (weil wenn sich das Ergebniss ändert, ändert sich K -> Schrittweite muss öffters halbiert werden -> Dimension wird größer)
Du solltest einen Wert der möglichst nahe an dem erwarteten Wert übergeben. Ich persönlich finde es aber deshalb auch nicht richtig nach der Dimension in der Aufgabe b) zu testen. Wir haben es mit zwei unterschiedlichen Methoden probiert um den Startwert von fsolve() zu berrchnen die beide, meiner Meinung nach, recht gut sind. Bei einem haben wir eine Dimension von 16 und beim anderen einen Wert euerer Größenordnung.

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

Was noch interessant ist: Wir haben es auch mal mit folgender Methode probiert: Wir haben
solange einen zufälligen Wert in fsolve eingegeben bis der Termination indicator 1 wurde, also
eine hinnreichen genaue Lösung herauskam, und den Wert für unsere Berrechnung genommen
Jedesmal kam ein anderes Ergebnis raus. Das gibt mir zu denken.

f_jakob
Mausschubser
Mausschubser
Beiträge: 50
Registriert: 27. Okt 2009 14:05

Re: P4 - Testcase?

Beitrag von f_jakob »

m_stoica hat geschrieben:Du solltest einen Wert der möglichst nahe an dem erwarteten Wert übergeben.
Wusste ich eigentlich vorher schon, hab mich in meiner Implementierung aber nicht dran gehalten. :oops:
Danke für das Mit-der-Nase-draufstoßen. \(c_{k+1}\) Ist dann doch näher dran als das alte \(c\)... Jetzt ist der Testfall auch positiv.

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

Das klingt doch gut.
Wie meinst du das mit ck+1. Das willst du doch erst berrechnen. Und hast es noch nicht im Vorraus

Könntest du übrigens deine Werte, die du auf diese Weise erhälst mal posten? Wäre nett.
wir hatten uns das so überlegt und damit laufen die Tests auch:
es gilt ja 0=(ck+1)-c-h*f(t,ck+1) <=> ck+1=c+h*f(t,ck+1) das ist ungefähr c+h*f(t,c)

tzeenie
Mausschubser
Mausschubser
Beiträge: 80
Registriert: 14. Okt 2008 20:04

Re: P4 - Testcase?

Beitrag von tzeenie »

Also, langsam verzweifel ich echt. :( Wie ich's auch dreh und wende - ich komme entweder auf 18 Spalten, oder auf die richtigen Werte von t. Ich hab's eig genau so implementiert wie ihr, aber die Werte passen einfach ned (\(t = t_k, tn = t_{k+1}, cprev = c_k, cn = c_{k+1}\)):

Code: Alles auswählen

     while K>delta2 do
       h = h/2; 
       tn = t + h;
       [cn,v,info] = fsolve(cprev + h*f(t,cprev), euler);
       printf("t=%3.6f: tn=%3.6f h=%3.8f info=%d\n", t, tn, h, info);
       K = h*abs(xprev - f(tn,cn));
     end;
Ich hab jetzt bald alle Kombinationen durch, was ist denn daran falsch, ich kapiers einfach ned? info meldet übrigens regelmäßig '4', also 'iteration is not making good progress', nehmt ihr cn als neuen Startwert?
// EDIT: Oder habt ihr bei fsolve die Jacobi-Matrix mit angegeben?

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

du hast es nicht wie wir implementiert ;)...

du inkrementierst jedesmal das t in der while-schleife. Das stimmt doch nicht. Du darfst nur einmal um den h-Wert inkrementieren, den du am Ende auch nimmst

tzeenie
Mausschubser
Mausschubser
Beiträge: 80
Registriert: 14. Okt 2008 20:04

Re: P4 - Testcase?

Beitrag von tzeenie »

Nein - ich korrigiere bloß das aktuelle \(t_{k+1}\), das ja um h größer ist als \(t_k\). Wenn ich also h ändere, muss ich das doch auch anpassen, oder ned?

f_jakob
Mausschubser
Mausschubser
Beiträge: 50
Registriert: 27. Okt 2009 14:05

Re: P4 - Testcase?

Beitrag von f_jakob »

m_stoica hat geschrieben:Wie meinst du das mit ck+1. Das willst du doch erst berrechnen. Und hast es noch nicht im Vorraus
Beim ersten Aufruf von fsolve nicht, da nehme ich \(c\), habe mir damit aber ein \(c_{k+1}\) approximiert. Wenn ich mir dann im Fall \(K > \delta_2\) das neue \(c_{k+1}\) approximiere, nutze ich hier das \(c_{k+1}\) als Startwert für fsolve, das gerade verworfen wird.
m_stoica hat geschrieben:Könntest du übrigens deine Werte, die du auf diese Weise erhälst mal posten? Wäre nett.

Code: Alles auswählen

         column 1 to 6
 
    0.06         0.0600000    0.0600000    0.0600000    0.0600000    0.0600000  
    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003  
    5.010D-11    6.594D-11    4.512D-11  - 2.144D-12  - 2.682D-11  - 5.660D-11  
    0.03         0.0300000    0.0300000    0.0300000    0.0300000    0.0300000  
    2.400D-08    2.229D-08    2.057D-08    1.608D-08    8.717D-09  - 2.287D-09  
    0.           0.625        0.78125      0.9375       1.25         1.5625     
 
         column  7 to 12
 
    0.0600000    0.0600000    0.0600000    0.0600000    0.0600000    0.0600001  
    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003  
  - 8.571D-11  - 1.085D-10  - 1.325D-10  - 1.586D-10  - 1.849D-10  - 2.067D-10  
    0.0300000    0.0300000    0.0300000    0.0300000    0.0300000    0.0299999  
  - 1.384D-08  - 2.512D-08  - 3.626D-08  - 4.747D-08  - 5.881D-08  - 6.970D-08  
    1.875        2.1875       2.5          2.8125       3.125        3.4375     
 
         column 13 to 18
 
    0.0600001    0.0600001    0.0600002    0.0600002    0.0600002    0.0600003  
    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003  
  - 2.313D-10  - 2.555D-10  - 2.807D-10  - 3.027D-10  - 3.173D-10  - 2.783D-10  
    0.0299999    0.0299999    0.0299998    0.0299998    0.0299998    0.0299997  
  - 8.056D-08  - 9.131D-08  - 0.0000001  - 0.0000001  - 0.0000001  - 0.0000001  
    3.75         4.0625       4.375        4.6875       4.84375      5.         

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

wenn du damit fertig bist, dass h zu halbieren, kannst du das t inkrementieren. Aber nicht solange K>delta2 ist.
das könnte z.B so aussehen (vielleicht passt es aber auch nicht zum restlichen Code, das weiß ich nicht)

Code: Alles auswählen

while K>delta2 do

       h = h/2;
       tn = t + h;
       [cn,v,info] = fsolve(cprev + h*f(t,cprev), euler);
       printf("t=%3.6f: tn=%3.6f h=%3.8f info=%d\n", t, tn, h, info);
       K = h*norm(xprev - f(tn,cn)); //norm ist nicht das gleiche wie abs! abs bestimmt den Betrag nur komponenten-weise
       if(K>delta2 )tn=t-h; //zurückstellen von tn wenn das h nicht richtig war
     end;

Benutzeravatar
m_stoica
Kernelcompilierer
Kernelcompilierer
Beiträge: 473
Registriert: 5. Dez 2008 20:19
Wohnort: Zuhause

Re: P4 - Testcase?

Beitrag von m_stoica »

das sieht unseren Werten sehr ähnlich. Die t-Werte sind (wie zu erwarten) identisch.

Code: Alles auswählen

   column 1 to 7

    0.06         0.0600000    0.0600000    0.0600000    0.0600000    0.0600000    0.0600000
    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003
    5.010D-11    6.518D-11    4.691D-11  - 7.727D-14  - 3.674D-11  - 6.826D-11  - 9.282D-11
    0.03         0.0300000    0.0300000    0.0300000    0.0300000    0.0300000    0.0300000
    2.400D-08    2.212D-08    2.051D-08    1.615D-08    5.449D-09  - 6.124D-09  - 1.757D-08
    0.           0.625        0.78125      0.9375       1.25         1.5625       1.875

         column  8 to 14

    0.0600000    0.0600000    0.0600000    0.0600001    0.0600001    0.0600001    0.0600001
    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003    0.0000003
  - 1.172D-10  - 1.421D-10  - 1.674D-10  - 1.919D-10  - 2.159D-10  - 2.405D-10  - 2.646D-10
    0.0300000    0.0300000    0.0300000    0.0299999    0.0299999    0.0299999    0.0299999
  - 2.890D-08  - 4.015D-08  - 5.139D-08  - 6.252D-08  - 7.351D-08  - 8.441D-08  - 9.520D-08
    2.1875       2.5          2.8125       3.125        3.4375       3.75         4.0625

         column 15 to 18

    0.0600002    0.0600002    0.0600002    0.0600003
    0.0000003    0.0000003    0.0000003    0.0000002
  - 2.872D-10  - 3.112D-10  - 2.859D-10  - 2.405D-10
    0.0299998    0.0299998    0.0299998    0.0299997
  - 0.0000001  - 0.0000001  - 0.0000001  - 0.0000001
    4.375        4.6875       4.84375      5. 

tzeenie
Mausschubser
Mausschubser
Beiträge: 80
Registriert: 14. Okt 2008 20:04

Re: P4 - Testcase?

Beitrag von tzeenie »

m_stoica hat geschrieben:wenn du damit fertig bist, dass h zu halbieren, kannst du das t inkrementieren. Aber nicht solange K>delta2 ist.
Versteh ich nicht - ich setze in jedem Durchlauf lediglich \(t_{k+1} = t_{k} + h\), ich inkrementiere nicht in dem Sinne dass im 2. Durchlauf \(t_{k+1} = t_k + h/2 + h/4\) wäre. Hast Du evtl. tn = tn + h gelesen statt tn = t + h? t ändert sich bei mir erst am Ende des kompletten Durchlaufs.
// EDIT: Aber danke für den Hinweis mit norm, hab ich komplett übersehen! :oops:
// EDIT2: Mannmann, hab das Problem gefunden: Meine euler war falsch, hat sich ein Tippfehler eingeschlichen. :oops: :oops: :oops: Danke für die Hilfe! :lol:

Antworten

Zurück zu „Archiv“