Klasyczne modele oparte na równaniach
różniczkowych zwyczajnych zakładają, że w danej chwili reakcja systemu (zmiana wartości) jest natychmiastowa i zależy od jej wartości w tym momencie (czyli, że
Pakiet OdePkg, rozszerzający możliwości Octave i dostępny w Octave-Forge [20], zawiera w sobie kilka solverów równań różniczkowych ze stałym opóźnieniem ode23d
, po metodę wysokiego rzędu ode78d
. Warto pamiętać, że w przypadku równań z opóźnieniem rozwiązania mogą nie być zbyt gładkie i wówczas korzystniej może być stosować schemat niższego rzędu.
Sposób wykorzystania pakietu jest bardzo dokładnie opisany w [25], na którym, jak się wydaje, opiera się zestaw solverów z OdePkg. My ograniczymy się do krótkiego omówienia sposobu rozwiązania jednego z najprostszych równań.
Rozważmy równanie postaci
(9.1) | ||||
(9.2) |
Jest to tzw.równanie logistyczne z opóźnieniem. Dodatni współczynnik
Zacznijmy od zapisania skryptu, rozwiązującego nasze równanie dla wartości
parametru
global a; lag = 1; T = 100; % parametry solvera opts = odeset ('Stats', 'on', ... 'RelTol', 1e-4, ... % tolerancja bledu wzglednego 'AbsTol', 1e-4, ... % tolerancja bledu bezwzglednego 'InitialStep', 1e-5, ... % poczatkowy krok schematu 'MaxStep', 1e-2); % przy okazji steruje liczba punktow probkowania rozwiazania filename = 'logdel'; for a = [0.1, pi/2 - 0.1, pi/2 + 0.1] sol = ode23d(@logdelf, [0,T], 0.2, lag, 0.2, opts); t = sol.x; Y = sol.y; sol.stats Ylag = interp1(t,Y,t-lag,'cubic'); % rozwiazanie opoznione Ydot = logdelf(t,Y,Ylag); % pochodna rozwiazania plot(t,Y); xlabel('t'); ylabel('y(t)'); title('Rozwiazanie y(t)'); print('-depsc', strcat(filename, '-a-', ... strrep(num2str(a,'%g'),'.','p'), '.eps') ) pause(1); plot(Y,Ydot); xlabel('y(t)'); ylabel('y''(t)'); title('Wykres fazowy'); print('-depsc', strcat(filename, '-a-', ... strrep(num2str(a,'%g'),'.','p'), '-phase.eps') ) pause(1); end
Kluczowa jest linijka
sol = ode23d(@logdelf, [0,T], 0.2, lag, 0.2, opts);
która w rzeczywistości rozwiązuje nasze równanie. Parametrami funkcji
ode23d
są kolejno:
funkcja określająca prawą stronę23Funkcja musi być przekazana jako wskaźnik, a nie jako nazwa! (u nas jest
to logdelf
), do której parametr a
przekazujemy z przyzwyczajenia za
pomocą zmiennej globalnej24W rzeczywistości funkcje z pakietu OdePkg umożliwiają wygodne przekazywanie listy dodatkowych parametrów do wnętrza funkcji prawej strony.),
przedział czasowy, na
którym wyznaczamy rozwiązanie, tutaj:
warunek początkowy,
wartości opóźnień (u nas jest tylko jedno, bo równanie jest skalarne) lag
= 1), no i ewentualnie
struktura, zmieniająca domyślne parametry pracy solvera.
function ydot = logdelf(t,y,ylag) global a; ydot = (a - ylag).*y; end
W odróżnieniu od lsode
, ode23d
zwraca wartości rozwiązania w
przez siebie wyznaczonych punktach przedziału
t = linspace(0,T,10*T);musimy interpolować wartości; warto także wcześniej zadać w opcjach maksymalną długość kroku, która zagwarantuje nam wystarczającą rozdzielczość próbkowania; dla danych opóźnionych, a następnie wyznacz
Ylag = interp1(t,Y,t-lag,'cubic'); % rozwiązanie opóźnione Ydot = logdelf(t,Y,Ylag); % pochodna rozwiązania
która zwraca nam wartości obliczonego przybliżenia rozwiązania (i jego
pochodnej!) w punktach
plot(t, Y); plot(Y, Ydot);
— najpierw rozwiązanie w zależności od czasu, potem — wykres fazowy.
Wyniki, które, przynajmniej w sposób jakościowy, zgadzają się z przewidywaniami teoretycznymi, przedstawiają poniższe wykresy.
Aby nabrać więcej przekonania do ilościowych wyników, zobaczymy, czy stukrotne zmniejszenie parametrów tolerancji błędu spowoduje wyraźną zmianę uzyskanych wartości rozwiązania. Sprawdzenie przeprowadzimy dla parametru
Najpierw wyznaczymy w standardowy sposób wartości rozwiązania w interesujących nas punktach:
a = pi/2 + 0.1; opts = odeset ('Stats', 'on', ... 'RelTol', 1e-4, ... % tolerancja błędu względnego 'AbsTol', 1e-4, ... % tolerancja błędu bezwzględnego 'InitialStep', 1e-5, ... % początkowy krok schematu 'MaxStep', 1e-2); % przy okazji steruje liczbą punktów próbkowania sol = ode23d(@logdelf, [0,T], 0.2, lag, 0.2, opts); t = sol.x; Y = sol.y; sol.statsa następnie powtórzymy obliczenia dla ostrzejszych kryteriów:
opts = odeset ('Stats', 'on', ... 'RelTol', 1e-6, ... % tolerancja błędu względnego 'AbsTol', 1e-6, ... % tolerancja błędu bezwzględnego 'InitialStep', 1e-7, ... % początkowy krok schematu 'MaxStep', 1e-2); % przy okazji steruje liczbą punktów próbkowania sol = ode23d(@logdelf, [0,T], 0.2, lag, 0.2, opts); tref = sol.x; Yref = sol.y; sol.statsJednak kłopot w tym, że — w przeciwieństwie do
lsode
— funkcja ode23d
zwraca rozwiązanie nie we wskazanych przez nas wartościach sol.x
.
Dlatego musimy napierw sprowadzić wyznaczone wartości do wspólnego zestawu chwil czasowych t
— wartości wyznaczone przy mniej restrykcyjnych parametrach pracy solvera. Następnie, musimy interpolować25To może wprowadzić dodatkowe zaburzenia w wynikach, więc musimy być czujni! wartości (tref
,Yref
) na t
, do czego idealnie nadaje się funkcja interp1
.
Yreft = interp1(tref, Yref, t);
Następnie sprawdzamy, jak bardzo różnią się rozwiązania Y
i Yref
:
octave:> norm(Yreft-Y, Inf) ans = 4.8362e-06 octave:> semilogy(abs(Yreft-Y));
A więc maksymalna różnica pomiędzy rozwiązaniami wynosi jedynie około
Potwierdź eksperymentalnie, że właśnie dla
Napisz funkcję, pozwalającą rozwiązać równanie logistyczne z opóźnieniem o zadanych parametrach i jednocześnie od razu zweryfikować w opisany powyżej sposób jakość rozwiązania. Zadbaj o komunikaty i wizualizacje dla niecierpliwego użytkownika. Następnie sprawdź pozostałe uzyskane powyżej wyniki.
Napisz skrypt Octave lub MATLABa, rozwiązujący inną wersję równania logistycznego z opóźnieniem, pochodzącą z pewnego modelu wzrostu nowotworu u myszy [4]:
Dodatnie współczynniki
Treść automatycznie generowana z plików źródłowych LaTeXa za pomocą oprogramowania wykorzystującego LaTeXML.
strona główna | webmaster | o portalu | pomoc
© Wydział Matematyki, Informatyki i Mechaniki UW, 2009-2010. Niniejsze materiały są udostępnione bezpłatnie na licencji Creative Commons Uznanie autorstwa-Użycie niekomercyjne-Bez utworów zależnych 3.0 Polska.
Projekt współfinansowany przez Unię Europejską w ramach Europejskiego Funduszu Społecznego.
Projekt współfinansowany przez Ministerstwo Nauki i Szkolnictwa Wyższego i przez Uniwersytet Warszawski.