Autor Beitrag
bad2play
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mi 11.05.05 19:02 
Hallo,

also ich hab mich im Forum umgeschaut und entsprechend gesucht, doch leider habe ich nichts zu meinem Thema gefunden :( deshalb hoffe ich mal das mir hier jemand helfen kann, auch wenn ich noch ein delphi greenhorn bin.

also mein problem ist, dass ich es nicht hinkriege z.b. das räuber-beute Modell in Delphi grafisch darzustellen.. ich krieg es nur hin ne Parabel oda ne lineare Gleichung in ein Koordinatensystem zu zeichnen, aber eben nicht die Funktionen die ich bräuchte um das Räuber - Beute Modell / Bevölkerungswachstum oda sonst etwas an Wachstumsfunktionen darzustellen...

also braucht ihr noch den quelltext von meinem Koordinatensystem? ich habs auch schon hingekriegt ganzrationale funktionen 4. Grades darzustellen... aba eben keine dynamischen Systeme.

z.b. Krankenstand einer Bevölkerung. Bsp: 1000 Menschen, davon sind 40 erkrankt, und alle die krank waren sind nun Immun dagegen. d.h. es handelt sich um logistisches wachstum oda so ( auf jeden fall begrenztes).

der verlauf hängt ja von der ansteckungsrate ab und von der Anzahl der Kranken u. bevölkerung. doch wie schreibe ich das in Delphi?

schon mal jetzt vielen dank fürs lesen !

Gruß
Felix

Moderiert von user profile iconTino: Überflüssige Zeilenumbrüche entfernt.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Mi 11.05.05 19:32 
dazu brauchst du wahrscheinlich eine rekursive funktion. das heist, eine funktion, die sich selbst aufruft! wie war das noch gleich...
ach kein plan, pass nur auf, dass du die funktion nicht sich für immer und ewig neu aufrufen lässt... aber ich glaube so geht das. kannst du mal die funktion für dein wachstum posten? ich hab leider vergessen, wie das noch gleich war, mit dem logistischen wachstum...

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Do 12.05.05 10:45 
Also hier ist der bisherige Quelltext ( also Koordinatensystem hab ich mal weggelasen jetzt, dass is ja net das prob...)


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure ....;
var
Infizierte, Geheilte, Gesunde, Kranke, Kontakthaeufigkeit,
Infektionsrate, Heilungsrate, Immune : Real;
begin

Gesunde:= 1000;
Kranke:=40;
Immune:= 0;
Kontakthaeufigkeit:=0.2;
Infektionsrate:=0.01;
Heilungsrate:=0.1;
x:=0;  // gibt die Tage an, vom 0 - Nullten TAag bis zum 60 Tag praktisch.
   REPEAT
   Infizierte := Gesunde*Kranke*Kontakthaeufigkeit*Infektionsrate;
   Geheilte := Kranke * Heilungsrate;
  // Gesunde.neu:= Gesunde.alt + dt*(-Infizierte)                           
  //Kranke.neu:= Kranke.alt + dt*(Infizierte-Geheilte)
  // Immune.neu:= Immune.alt + dt*(Geheilte)



  ^^ Das ist der Teil den ich nicht hinkriege?!

   //  y:=x;     <-- hier muss dann irgendwie die funktion zum Pixel 
                     übertragen werden. 
    xb:=round(x0+x*k);
    yb:=round(y0-y*k);    // hier Y- Wert ändern
    Bild.Canvas.Pixels[xb,yb]:=farbe;
    x:=x+0.001; // damit es ein Pixel weiter rückt
  UNTIL x > 60 // 60 Tage


end;




PS: ich weiss dass es besser ist kurze namen zu verwenden, doch hier hab ich se jetzt zu gunsten der übersicht erstmal ausgeschrieben!

Vielen Dank für eure hilfe!
ich glaub ich muss das irgendwie mit nem array machen, aber wie?
und kann man das alles auch mit LineTo und Moveto machen oder muss man das per Pixel machen?
^^
hierbei ist dann noch das problem, dass man das die steigung in jedem punkt nach dem Euler-Cauchy-Verfahren bestimmen muss, leider habe ich das u. Differenzialgleichungen ( was dem wohl zu grunde liegt) nie gemacht, daher hab ich absolut keinen plan

Moderiert von user profile iconraziel: Delphi- und Highlight-Tags hinzugefügt.
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 17.05.05 12:04 
weiss wirklich keiner weiter??

hier hab ich noch nen hinweis zu dynamischen systemen und dem rechenverfahren, falls dies einer versteht oda weiss wo es besser erklärt wird, plz melden

www.learn-line.nrw.d...ote/modell/medio.htm
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 17.05.05 15:15 
Hallo user profile iconbad2play.

Anstatt mit Worten versuchen zu erklären, was das Räuber-Beute Modell ist, könntest du entwas konkreter auf dein Problem eingehen?

So wie es klingt hast du die Koordinaten des Graphen gegeben und willst diese nun plotten? War das jetzt schon dein ganzes Problem, oder hast du noch Probleme damit, die Differentialgleichungen korrekt zu diskretisieren und diese numerisch zu lösen?

Falls Zweiteres gefragt ist, könntest du bitte die Differentialgleichung für das Räuber-Beute-Modell angeben, ich weiss sie zufälligerweise nicht mehr auswendig.

Je mehr Informationen du uns gibst, desto kleiner ist unser Aufwand, und desto grösser ist die Chance, dass dir jemand ne gescheite Antwort gibt.
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 17.05.05 16:00 
Hi Delfiphan,

vielen Dank für deine Antwort.

also anstelle des Räuber-Beute Modells habe ich hier ein Infektionsmodell genommen ( siehe Quellcode oben). also wenn ich mir das richtige unter plotten vorstelle, dann hab ich bei beidem Probleme..

zu 2. lässt sich sagen, dass ich soviel weiss:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Gesunde:= round(Gesunde.NEU - x*Infizierte);
Geheilte := round(Geheilte.NEU * Heilungsrate);
Kranke:= round(Kranke.NEU + x*(Infizierte-Geheilte));
Immune:= round(Immune.NEU + x*(Geheilte));
Infizierte := round(Gesunde.NEU*Kranke*Kontakthaeufigkeit*Infektionsrate);

Gesunde.NEU usw. müssten ableitungen der Gleichung sein... nur wie geht das?

nehmen wir nun mal an, ich will den Verlauf der Anzahl der Kranken grafisch darstellen in einem graphen, wie mache ich das? weil ich muss ja irgendwie die ableitung von der "kranken"- Funktion bilden, die wiederum von der Infizierten u. geheilten Funktion abhängig ist. also habe ich nicht nur ein problem beim programmieren, sondern schon bei der mathematik...? wenn ich die Differentialgleichung für das Räuber Beute Modell oda das Infektionsmodell hätte, dann hätte ich glaub ich schon net mehr ein so großes Problem.

also da ich langsam anfange dadurch zu steigen, bin ich jetzt auf folgende sites gestoßen: hier stehen alle möglichen Differentialgl. u.a. auch für das Räuber Beute Modell. ifgivor.uni-muenster...population_einf.html

jetzt müsst ich nur noch die Gleichungen verstehen....

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.
Moderiert von user profile iconTino: Überflüssige Zeilenumbrüche entfernt.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 17.05.05 16:47 
Das reicht noch nicht. Du hast bestimmt eine Differentialgleichung erhalten. Mit Parametern wie Todesrate, Infektionsrate, usw.. Wenn die nicht gegeben ist, kann ich dir leider auch nicht helfen.

//Edit: Das hier vielleicht: www.uni-graz.at/~propst/saII0203.pdf
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 17.05.05 17:01 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
Immune:= 0;
Kontakthaeufigkeit:=0.2;
Infektionsrate:=0.01;
Heilungsrate:=0.1;


weitere Startwerte s.o. ( sonst wird es unübersichtlich oder?)

das is ein Bsp. Modell von DynaSis.

also ich hab keine Differentialgleichung dazu bekommen, da ich mir ja beliebige dynamische systeme aussuchen darf. das is mein Abitursthema.

sterberate gibt es nicht, da es keine Infektion mit Tod ist, vielmehr können die auch wieda alle geheilt werden ... wie die heilungsrate vermuten lässt :)

vielen Dank für den Link, denn werde ich mir jetzt erstmal anschaun, über weitere hilfe würde ich mich trotzdem sehr freuen :)

PS: wenn es daran scheitert, dass wir beide dazu keine Differentialgleichung kennen, dann nimm doch einfach bitte das Räuber Beute Modell, da is die Differentialgleichung...

Räuber-Beute-Modell
  • Die Räuberart ist in ihrer Ernährung vollständig von einer einzigen Beuteart abhängig.
  • Die Beuteart hat einen unbegrenzten Nahrungsvorrat.
  • Ausser dieser einen Räuberart hat die Beuteart keine weiteren Feinde.
  • ...
Unabhängig voneinander entwickelten Lotka und Volterra Mitte der zwanziger Jahre des 20. Jahrhunderts zwei gekoppelte Diffentialgleichungen, die eine solche Räuber-Beute-Interaktion idealisiert beschreiben. Die Gleichungen lauten für den zeit-kontinuierlichen Fall:

user defined image

Bedeutung der Terme:
x(t) Beute-Population
y(t) Räuber-Population
dx(t)/dt zeitliche Änderung der Beutepopulation
dy(t)/dt zeitliche Änderung der Räuberpopulation
a1 x(t) Vermehrung der Beutepopulation x(t)
b1 x(t)y(t) Gefressenwerden der Beutepopulation x(t)
b2 x(t)y(t) Vermehrung der Räuberpopulation y(t)
a2 y(t) Sterben der Räuberpopulation y(t)

Anstelle der aufwändigen Suche nach einer analytischen Lösung dieses Systems von Differentialgleichungen soll hier eine diskrete Lösung nach der Runge-Kutta-Methode gesucht werden: Zunächst wird dazu die Lösung in der Mitte des zu berechnenden Zeitintervalls geschätzt (die geschätzten Größen sind hier mit einem ' gekennzeichnet):

user defined image

Dann werden die Werte xn+1 und yn+1 unter Verwendung dieser Schätzung bestimmt:

user defined image

verstehst du das?

Moderiert von user profile iconTino: Überflüssige Zeilenumbrüche entfernt.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 17.05.05 18:42 
Gut okay. Wenn die Differentialgleichung nicht vorgegeben ist, musst du sie zuerst aufstellen. Die numerisch zu lösen ist dann eine Standardaufgabe (analog zu dem, was du gepostet hast). Ich schlage vor, du löst es mit Runge-Kutta, jedoch mit der Formel 4. Ordnung. Das ist neben der einfachen Euler-Formel eines der meistgebrauchten Formeln.

Weiss jetzt nich so genau, wo dein Problem liegt :?:

Ich zeig's dir einfach mal anhand des SIR-Modells. Die Differentialgleichung siehst du ja im PDF (siehe Link oben):
                     | Aktion:    Tod    Infektion      Heilung
Gruppe: -------------+------------------------------------------
Empfängliche         | S' = beta -mu*S  -lambda*S*I
Infizierte           | I' =      -mu*I  +lambda*S*I    -gamma*I
Resistente (geheilte)| R' =      -mu*R                 +gamma*I
(' bedeutet partielle Zeitableitung)

Die gewöhnliche Differentialgleichung ist von der Form:
u' = f(u)

Wobei u ein Vektor ist und f eine Vektorfunktion.
Runge-Kutta 4. Ordnung geht dann so:
(rkm4.gif)
Du definierst dir also einen Zeitschritt dt und Anfangswerte. Zum Lösen musst du eigentlich nur noch die Zahlen in die Formel einsetzen.

Das kann dann z.B. so aussehen
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
type
 TData = record
  S, I, R: Extended;
 end;

function f(u: TData): TData;
const
 beta = ...
 mu = ...
 lambda = ...
 gamma = ...
begin
 with u do
 begin
  Result.S := beta -mu*S -lambda*S*I;           // susceptible
  Result.I :=      -mu*I +lambda*S*I -gamma*I;  // infected
  Result.R :=      -mu*R             +gamma*I;  // resistant
 end;
end;

function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.S := S*factor;
  Result.I := I*factor;
  Result.R := R*factor;
 end;
end;

function Add(u, v: TData): TData;
begin
 Result.S := u.S+v.S;
 Result.I := u.I+v.I;
 Result.R := u.R+v.R;
end;

function RKM4(u: TData; dt: Extended): TData;
var
 v, du: TData;
begin
 du := f(u);
 Result := du;
 v := Add(u, Mult(du, dt/2));
 du := f(v);
 Result := Add(Result, Mult(du, 2));
 v := Add(u, Mult(du, dt/2));
 du := f(v);
 Result := Add(Result, Mult(du, 2));
 v := Add(u, Mult(du, dt));
 du := f(v);
 Result := Add(Result, du);
 Result := Add(u, Mult(Result, dt/6));
end;

procedure TForm1.Button1Click(Sender: TObject);
const
 dt = 0.01; // Zeitschritt
var
 t: Extended;
 u: TData;
begin
 // Anfangswerte
 t := 0;
 u.S := ...
 u.I := ...
 u.R := ...
 while t < 200 do
 begin
  u := RKM(u, dt);
  with Image1.Canvas do
  begin
   Pixels[Round(t), Round(u.S)+100] := clBlack;
   Pixels[Round(t), Round(u.I)+101] := clRed;
   Pixels[Round(t), Round(u.R)+100] := clBlue;
  end;
  t := t + dt;
 end;
end;


Ungetestet (bzw. Richtigkeit nicht verifiziert); hoffe ich hab die Formeln einigermassen richtig.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von delfiphan am Do 19.05.05 18:31, insgesamt 3-mal bearbeitet
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Di 17.05.05 19:21 
Heyho,
also zunächst einmal BIG thx,

ich werd jetzt mal versuchen das zu verstehen und umzusetzen und dann mein feedback hier posten bzw. ein faq zu dem thema erstellen, so dass auch den anderen in Zukunft geholfen sein wird.

ich soll das eigentlich mit dem euler verfahren machen, obwohl das ungenauer ist etc.,
nur leider ist mir der unterschied bzw. wie dieses und das runde-kutta verfahren funktionieren noch nicht so klar.


user defined image

also hieran verstehe ich fast nix...?
bzw. wie kommt diese gleichung zu stande?


oh man ich hab das gefühl ich leide an dummheit.
ich hoffe du verlierst net die geduld mit mir.

also ich werd mal probieren etwas zu programieren, bei erfolg meld ich mich hier.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Di 17.05.05 20:47 
Naja. Euler ist im Prinzip auch ein Runge-Kutta Verfahren. Runge Kutta ist ein Oberbegriff für so explizite Formeln zur Lösung von gewöhnlichen Differentialgleichungen vom Typ u'=f(u). Die Herleitung für RKM4 ist nicht ganz ohne. Per Taylorentwicklung kann man zeigen, dass sie die DGL bis zur 4. Ordnung approximiert. Die Formel versucht, möglichst genau die "durchschnittliche" Steigung zwischen zwei Zeitpunkten (1 Zeitschritt) zu berechnen.

Die Euler-Formel geht so:
(Euler.gif)

Die Interpretation ist hier etwas einfacher. Die Euler-Formel nimmt als "durchschnittliche" Steigung einfach die Steigung der Tangente am jeweiligen Zeitpunkt. Das ist natürlich etwas ungenau. Deswegen muss man den Zeitschritt dementsprechend klein wählen (z.B. dt = 0.001).
Hier die zugehörige Skizze:
(Euler2.gif)

Die orangen Kurven sind verschiedene Lösungen der Differentialgleichung zu verschiedenen Anfangswerten. Die rote Kurve approximiert die orange Kurve, indem sie an den jeweiligen Zeitpunkten einfach die Tangente nimmt und der folgt. Wie man auch sieht ist dies halt nicht sooo genau und es gibt bald Abweichungen.

Die Skizze ist jetzt natürlich in 1D. In deinem Fall sind es ja 4 Gleichungen, also 4D. Jedoch geht das alles ganz analog. Man kann dort zwar keine Skizzen mehr zeichnen, die Formeln lauten aber alle gleich, einfach überall (wo u steht) ein Vektorpfeilchen.

Der zugehörige Codeschnispel sieht dann etwa so aus (der Rest bleibt gleich):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function RKM1(u: TData; dt: Extended): TData;  
var du: TData;
begin  
 du := Mult(f(u), dt);  
 Result := Add(u, du);  
end;


PS: Die Bilder werde ich irgendwann vom Server löschen und diese als Post-Anhänge speichern. Du solltest sie also nicht verlinken. Ich lass es erst mal so sein, damit's übersichtlicher ist.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von delfiphan am Do 19.05.05 18:29, insgesamt 1-mal bearbeitet
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mi 18.05.05 11:40 
mmh wieso ist das ganze 4D wenn ich 4 gleichungen habe?

ich dachte das könnt ich imma noch 2D,
also auch in so graphen darstellen?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 18.05.05 14:22 
Ja klar, das kannst du. Sorry das war etwas unpräzise von mir. Rein formal ist es eine Lösungskurve durch den 4D-Raum.
Aber zum Visualisieren, klar, da zeichnet man jede Dimension für sich separat in einen Graphen. Gibt dann halt 4 gewöhnliche Graphen. Schliesslich hat auch jede Dimension eine Interpretation: Anzahl der Immunen, Anzahl der Kranken, etc.
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mi 18.05.05 14:33 
ah ich liebe es.
also ich weiss warum ich es net verstehe,
denn diese schreibweise usw. kenne ich gar nicht.
user defined image

^^
f( u^n, t) <-
hier stellt f wohl die Änderungsrate, welche abhängig von Zeit / Bestand ist dar. oder irre ich mich?


ah ich weiss, dass ich nichts weiss...

EDIT:
also ich habe deinen Quellcode mal ausprobiert und es scheint zu gehen,
jetzt versuche ich es mal durch rumprobieren dahinter zu kommen und dies auf die oben genannte Infektion abzuändern, geht das?

aba auf jeden fall vielen dank schon mal, weil das hätte ich ja bisher noch net mal hinbekommen!!!






edit2: jetzt habe ich auch noch ne frage wegen dem maßstab, wie mache ich das am besten?
da muss ich mit line to u. move to arbeiten damit das geht..oda?
und noch ne frage... warum + 100????
Pixels[Round(t), Round(u.S)+100] := clBlack;

bis jetzt ist der graph ja nur teilweise drauf.


Zuletzt bearbeitet von bad2play am Mi 18.05.05 15:23, insgesamt 1-mal bearbeitet
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mi 18.05.05 14:58 
Genau, f(u)=u'. f beschreibt die Änderung von u am Punkt u. f(S,I,R) = Änderung von (S,I,R). Weiss nicht genau, wie ich das erklären soll. Vielleicht hilft dir das: Hab das Programm von oben mit deinem Infektionsmodell gefüttert (Kontakthäufigkeit, etc.). Es ist nichts anderes als eine Vereinfachung des SIR-Modells.

Ergibt dieses Bild:
(Infektion.gif)

(Infektionsrate, Anfangswerte aus: www.hupfeld-software...Dynasys-Handbuch.pdf, Seite 14)

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
type
 TData = record
  S, I, R: Extended;
 end;

function f(u: TData): TData;
const
 beta = 0; // Zuwachs
 mu = 0; // Todesrate
 lambda = 0.0004; // = Kontakthäufigkeit*Infektion_Pro_Kontakt
 gamma = 0.1; // = Heilungsrate
begin
 with u do
 begin
  Result.S := beta -mu*S -lambda*S*I;           // susceptible
  Result.I :=      -mu*I +lambda*S*I -gamma*I;  // infected
  Result.R :=      -mu*R             +gamma*I;  // resistant
 end;
end;

function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.S := S*factor;
  Result.I := I*factor;
  Result.R := R*factor;
 end;
end;

function Add(u, v: TData): TData;
begin
 Result.S := u.S+v.S;
 Result.I := u.I+v.I;
 Result.R := u.R+v.R;
end;

function RKM1(u: TData; dt: Extended): TData;
var du: TData;
begin
 du := Mult(f(u), dt);
 Result := Add(u, du);
end;

function RKM4(u: TData; dt: Extended): TData;
var
 v, du: TData;
begin
 du := f(u);
 Result := du;
 v := Add(u, Mult(du, dt/2));
 du := f(v);
 Result := Add(Result, Mult(du, 2));
 v := Add(u, Mult(du, dt/2));
 du := f(v);
 Result := Add(Result, Mult(du, 2));
 v := Add(u, Mult(du, dt));
 du := f(v);
 Result := Add(Result, du);
 Result := Add(u, Mult(Result, dt/6));
end;

procedure TForm1.Button1Click(Sender: TObject);
const
 ScaleT = 5;
 dt = 0.2;
var
 t: Extended;
 u: TData;
begin
 // Anfangswerte
 t := 0;
 u.S := 1000;
 u.I := 40;
 u.R := 0;
 while t < 70 do
 begin
  u := RKM4(u, dt);
  with Image1,Image1.Canvas do
  begin
   Pixels[Round(ScaleT*t), Height-1-Round(u.S/10)] := clBlack;
   Pixels[Round(ScaleT*t), Height-1-Round(u.I/10)] := clRed;
   Pixels[Round(ScaleT*t), Height-1-Round(u.R/10)] := clBlue;
  end;
  t := t + dt;
 end;
end;
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von delfiphan am Do 19.05.05 18:28, insgesamt 1-mal bearbeitet
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mi 18.05.05 15:38 
Hey,
ein großes Lob an dich :)
ich hab es auch schon hingekriegt gehabt das Modell auf das von Dynasis zu vereinfachen :)
aba mit der skalierung hatte ich meine probs die jetzt auch beseitigt sind,
vielen Dank!!
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Mi 18.05.05 17:47 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.S := S*factor;
  Result.I := I*factor;
  Result.R := R*factor;
 end;
end;

function Add(u, v: TData): TData;
begin
 Result.S := u.S+v.S;
 Result.I := u.I+v.I;
 Result.R := u.R+v.R;
end;

function RKM1(u: TData; dt: Extended): TData;
var du: TData;
begin
 du := Mult(f(u), dt);
 Result := Add(u, du);
end;



jetzt muss ich nur noch diese functions hier verstehen ;)


letztlich hab ich nur noch eine frage, ... ich weiss ich bin penetrant, sry

ich will nämlich jetzt auch noch die werte alle in ner Tabelle anzeigen lassen
für 70 Tage,
das prob ist, dass ich das dann mit dt net gescheit hinkriege?
und wenn ich ne neue variable für die zeit, nämlich X nehme, dann stimmt das ja mit der zeit net mehr überein.

also hier mein quellcode


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm2.FormActivate(Sender: TObject);
VAR dt,x :real;
    sp  : byte;
     t: Extended;
     u: TData;
begin
Tab.Cells[0,0]:='Tage';
Tab.Cells[1,0]:='Infizierte';

// Anfangswerte
 x:=1;
 sp:=1;
 dt := 0.2;
 t := 0;
 u.S := 1000;
 u.I := 40;
 u.R := 0;
 while x < 70 do
 begin
  u := RKM1(u, dt);
 Tab.Cells[0,sp]:=FloatToStrF(x,fffixed,10,1);
 [b]Tab.Cells[1,sp]:=FloatToStrF(Round(u.I),fffixed,10,1);[/b]
 t:=t+0.2;
 x:= x +1;
 sp:=sp+1;

  end;
end;



oda sollte ich es lieba so machen???
nur da is auch etw. falsch, aba was?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
 while t < 70 do
 begin
  u := RKM1(u, dt);
 Tab.Cells[0,sp]:=FloatToStrF(t*5,fffixed,10,1);
 Tab.Cells[1,sp]:=FloatToStrF(Round(u.I/10),fffixed,10,1);
 t:=t+0.2;

 sp:=sp+1;

  end;
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 19.05.05 09:12 
user profile iconbad2play hat folgendes geschrieben:
und wenn ich ne neue variable für die zeit, nämlich X nehme, dann stimmt das ja mit der zeit net mehr überein.
Wenn dt = 1/10 ist rechnest du eben immer 10 Schritte und trägst nur jeden 10. Schritt in die Tabelle ein.

user profile iconbad2play hat folgendes geschrieben:
jetzt muss ich nur noch diese functions hier verstehen ;)
Die Funktionen Mult und Add sind doch eigentlich selbsterklärend, nicht? Die implementieren einfach Vektor + Vektor, und Vektor * Zahl. Und RKM1 ist das Euler-Verfahren, das kennst du ja schon. Was ist dir genau unklar?

Jetzt hab ich aber mehr oder weniger deine ganze Arbeit gemacht, nicht? ;) Es ist wichtig, dass du dein Programm selbst schreibst, und nicht einfach meine Prozeduren in dein Projekt übernimmst. Das wird nämlich dein Lehrer merken und wenn du nicht jeden Schritt verstanden hast, ist es natürlich unsinnig, wenn ich dir auf diese Weise versuche zu helfen ;)

Wenn du eine Frage hast, frag ruhig. Es geht hier ja um dich und dass du es verstehst :D Ich denke mal das wichtigste ist, dass du das Differentialgleichungssystem des SIR verstanden hast (was die linke und rechte Seite, und die einzelnen Terme bedeuten).
bad2play Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21



BeitragVerfasst: Do 19.05.05 12:25 
ahjo, dass muss ich halt noch irgendwie hinkriegen, dass es nur jeden 10 wert ausgibt.


ich sehe es auch so dass ich es machen muss, deshalb nehme ich dieses Modell ja auch nicht in meine Arbeit auf,
es sollte jediglich ein Bsp dafür sein, anhand dessen ich mir dann z.b. das Räuber Beute Modell erklären kann.

leider funktioniert das noch nicht so ganz. also hier sind meine fragen.

1.wo kommt der Wert für factor her???
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.S := S*factor;
  Result.I := I*factor;
  Result.R := R*factor;
 end;
end;


ich sehe nirgends wo der gegeben wird.

2. kann ich mit diesen 3 funktionen alle dynamischen system beschreiben, wenn ich oben entsprechend die Zustandsgleichungen ändere?
beim räuber beute system müsste das dann so etw. hier sein.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
function f(u: TData): TData;
const

a = 0.08; //Nettozuwachsrate Hasen
b = 0.2; //Gewichtsverlust der Füchse/Woche
c = 0.002; // Wahrscheinlichkeit, bei Treffen gefressen zu werden
d = 0.0004; // Beutewahrscheinlichkeit der Füchse
wp = 2000;

begin
 with u do
 begin
Result.H:= a*H*w*0.001 - c*H*F;  {w*0.001}                // Population Hasen
Result.F:= -b*F + d*H*F;                  // " Füchse
Result.w:= Wp-H;                          // Weidekapazität


 end;
end;

function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.H := H*factor;
  Result.F := F*factor;
 Result.w := w*factor;
 end;
end;

function Add(u, v: TData): TData;
begin
 Result.H := u.H+v.H;
 Result.F := u.F+v.F;
 Result.w := u.w+v.w;
end;


^^
also ohne der Berücksichtung der Weidekapazität würde ich meinen funktioniert es, aba mit der weidekapazität nicht? wieso nicht?

hier ein screenshot wie es bisher ist.
[img]fapomatic.com/9/screen.bmp[/img]

wie man hier sieht hab ich da auch noch nen bissi probs mit der skalierung, mal sehn.




Zitat:
Vektor + Vektor, und Vektor * Zahl


^^ mir is schon klar, was da die rechenoperationen sind, doch verstehe ich nicht für was?

bisher weiss ich nur, dass sie dafür stehen, die differentialgleichung auf nummerische weise zu lösen,
wie genau es das macht, dass weiss ich leider nicht.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Do 19.05.05 17:55 
user profile iconbad2play hat folgendes geschrieben:
ahjo, dass muss ich halt noch irgendwie hinkriegen, dass es nur jeden 10 wert ausgibt.

Das könnte z.B. so aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
const
 N = 10; // 10 Zwischenschritte
 dt = 1/N;
begin
 ...
 while t < 70 do  
 begin  
  for J := 1 to N do
  begin
   t := t + dt;  
   u := RKM4(u, dt);
  end;
  // Hier t und u tabellieren
 end;


user profile iconbad2play hat folgendes geschrieben:
1.wo kommt der Wert für factor her???
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.S := S*factor;
  Result.I := I*factor;
  Result.R := R*factor;
 end;
end;


ich sehe nirgends wo der gegeben wird.
Was meinst du, du weisst nicht, wo er gegeben wird? Er wird beim Aufruf der Funktion übergeben (in der Funktion RKM1).

user profile iconbad2play hat folgendes geschrieben:
2. kann ich mit diesen 3 funktionen alle dynamischen system beschreiben, wenn ich oben entsprechend die Zustandsgleichungen ändere?
Alle, die auf die Form u'=f(u) gebracht werden können. Das sind so ziemlich viele. Dabei kann man auch Gleichungen mit höheren Ableitungen umformen zu Systemen von Gleichung mit nur ersten Ableitungen. Siehe auch z.B. das Doppelpendel. Das ist ein System (2 Gleichungen) mit zweiten Ableitungen. Das kann man dann umformen zu 4 Gleichungen mit nur ersten Ableitungen. Das Programm benützt aber genau das gleiche Gerüst mit RKM, f(), Add, usw..

user profile iconbad2play hat folgendes geschrieben:
beim räuber beute system müsste das dann so etw. hier sein.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
function f(u: TData): TData;
const

a = 0.08; //Nettozuwachsrate Hasen
b = 0.2; //Gewichtsverlust der Füchse/Woche
c = 0.002; // Wahrscheinlichkeit, bei Treffen gefressen zu werden
d = 0.0004; // Beutewahrscheinlichkeit der Füchse
wp = 2000;

begin
 with u do
 begin
Result.H:= a*H*w*0.001 - c*H*F;  {w*0.001}                // Population Hasen
Result.F:= -b*F + d*H*F;                  // " Füchse
Result.w:= Wp-H;                          // Weidekapazität


 end;
end;

function Mult(u: TData; factor: Extended): TData;
begin
 with u do
 begin
  Result.H := H*factor;
  Result.F := F*factor;
 Result.w := w*factor;
 end;
end;

function Add(u, v: TData): TData;
begin
 Result.H := u.H+v.H;
 Result.F := u.F+v.F;
 Result.w := u.w+v.w;
end;
Ja, wenn deine Gleichung in f() stimmt, müsste es funktionieren.

user profile iconbad2play hat folgendes geschrieben:
^^
also ohne der Berücksichtung der Weidekapazität würde ich meinen funktioniert es, aba mit der weidekapazität nicht? wieso nicht?
Weiss leider nicht, was die Weidekapazität genau ist, aber ich denke grundsätzlich müsste es kein Problem sein, diesen noch einzubauen.

user profile iconbad2play hat folgendes geschrieben:
hier ein screenshot wie es bisher ist.
[img]fapomatic.com/9/screen.bmp[/img]
404 Not Found

user profile iconbad2play hat folgendes geschrieben:
Zitat:
Vektor + Vektor, und Vektor * Zahl


^^ mir is schon klar, was da die rechenoperationen sind, doch verstehe ich nicht für was?
Für was? Die Funktionen werden in der Funktion RKM gebraucht. Anstatt folgendes:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
v[0] := u[0] + du[0]*dt/2;
v[1] := u[1] + du[1]*dt/2;
v[2] := u[2] + du[2]*dt/2;
v[3] := u[3] + du[3]*dt/2;
kann man dann ganz einfach das hier schreiben:
v := Add(u, Mult(du, dt/2));Ist doch irgendwie übersichtlicher. Du kannst aber auch alles ausschreiben, dann wäre dein Code sogar noch ein bisschen schneller. Aber du verlierst vielleicht bald die Übersicht... Das ist wohl Geschmackssache.

user profile iconbad2play hat folgendes geschrieben:
bisher weiss ich nur, dass sie dafür stehen, die differentialgleichung auf nummerische weise zu lösen,
wie genau es das macht, dass weiss ich leider nicht.
Die Funktion f gibt ja an, wie stark sich u verändert, wenn der Zustand u und die Zeit t gegeben ist.
Die Gleichungen hier:
 S' := beta -mu*S -lambda*S*I;
 I' :=      -mu*I +lambda*S*I -gamma*I;
 R' :=      -mu*R             +gamma*I;
sind von der Form ( ' bedeutet immer "Änderung pro Zeiteinheit" (Tag)):
 u' := f(u)          (mit u = (S,I,R))

Betrachten wir mal die erste Gleichung genauer:
 S' := beta -mu*S -lambda*S*I

Die Gleichung sagt folgendes aus:
Die Änderung (pro Tag) der Anzahl der empfänglichen Personen (S) soll gleich sein wie:
Ein Zuwachs beta Personen pro Tag
Eine Abnahme mu*S Personen pro Tag (wegen Todes)
Eine Abnahme lambda*S*I Personen pro Tag (wegen Infizierung)

Die Funktion gibt also zum gegebenen Zustand (d.h. S empfängliche Personen, I infizierte Personen, R resistente Personen) an, wie stark sich eben dieser Zustand ändert (wenn es viele empfängliche Personen gibt, dann nimmt die Anzahl der infizierten Personen stark zu, usw.). Als erste Näherung kann man dann schreiben:
 S.Morgen := S.Heute + (Anzahl Tage)*(Änderung von S.Heute pro Tag)
Oder etwas mathematischer ausgedrückt:
 S(t+dt) := S(t) + dt*S'(t)       (mit dt = 1 Tag)
 S(t+dt) := S(t) + dt*f(S(t))     da ja per Definition von f gilt: f(S(t)) = S'(t) ist
Das ist jetzt genau die Euler-Formel. Statt dt = 1 Tag nimmt man aber viel kleinere Werte. Z.B. dt = 1 Stunde = 1/24 Tag. Das muss man machen, da sich der Zustand des Systems nicht wie vorhin täglich ändert, sondern in der Wirklichkeit ständig ändert. Je kleiner man dt wählt, desto näher kommt man an die Realität heran. Natürlich nimmt der Rechenaufwand ständig zu, wenn man dt kleiner macht, denn es sind immer mehr kleine Schritte nötig, um einen Tag zu berechnen.

Aber hattet ihr das nicht in der Schule? Kann mir fast nicht vorstellen, dass du etwas programmieren sollst/musst, was in der Schule überhaupt nicht behandelt wurde.

//Edit: Korrekturen im Text


Zuletzt bearbeitet von delfiphan am Fr 20.05.05 13:38, insgesamt 1-mal bearbeitet