6. Diferenciální rovnice 3#
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.integrate import solve_ivp
6.1. Lov v logistické rovnici#
6.1.1. Konstantní užitek#
V logistické rovnici nakreslíme pro tři různé intenzity lovu průběh řešení. Prorovnejte následující kód s kódem pro kreslení řešení jedné sady pro jednu intenzitu lovu.
Zpravidla netriviální kód nenapíšeme napoprvé, ale musíme příkazy ladit. V následujícím jsou rozděleny fáze řešení rovnice a vykreslení řešení. Pro potřeby spouštění je po odladění vhodné buňky sloučit.
Zkuste si v následující buňce rozdělit kód do dvou různých buněk. Tedy přepnete se do editace, najdete vhodný řádek a v menu vyberete „Edit“ a „Split Cell“.
Poté zkuste buňky co se mají spouštět společně spojit. V příkazovém modu buňky označte (například shift + šipka nahoru nebo dolů) a stisknout velké M, tj. Shift + M. Pozor, pokud byste stiskli malé „m“, buňka by se změnila na Markdown buňku s textem. Zpět na buňku s kódem je klávesa „y“.
pocatecni_podminka = np.linspace(0.1,1.2,50)
meze = [0,10]
t = np.linspace(*meze,100)
def destrukce_populace(t,x): # Pokud x klesne na nulu, zastavíme výpočet
return x
destrukce_populace.terminal = True
def rovnice(t, x, r=1, K=1, h=0.15):
return r*x*(1-x/K)-h
lovy = [0.1,0.2,0.3]
# Pro různé počáteční podmínky se bude lišit interval,
# na kterém algoritmus najde řešení. Proto nemůžeme data
# shrnout do jedné tabulky. Alternativou je tabulka s
# nedefinovanými hodnotami, viz
# https://robert-marik.github.io/dmp/snippety/tabulky_none.html
# a https://robert-marik.github.io/dmp/snippety/multiindex.html
reseni = [
[ solve_ivp(
lambda t,x:rovnice(t,x,h=h),
meze,
[pp],
t_eval=t,
events=destrukce_populace, # zastavení výpočtu při poklesu populace na nulu
)
for pp in pocatecni_podminka]
for h in lovy]
# GRAFICKA PREZENTACE VYSLEDKU
fig,ax = plt.subplots()
for i,r in enumerate(reseni):
for res in r:
ax.plot(res.t,res.y[0], color=f"C{i}", alpha=0.5, label=f"lov {lovy[i]}", lw=0.5)
ax.set(
title="Logistická rovnice s konstantním lovem",
xlabel="bezrozměrný čas",
ylabel="bezrozměrná velikost populace"
);
# Návod jak seskupit položky legendy je na https://stackoverflow.com/questions/26337493/pyplot-combine-multiple-line-labels-in-legend
handles, labels = ax.get_legend_handles_labels()
labels, ids = np.unique(labels, return_index=True)
handles = [handles[i] for i in ids]
plt.legend(handles, labels);
fig,ax = plt.subplots()
x = np.linspace(0,1)
plt.plot(x,rovnice(0, x,h=0),label="růst bez lovu",color='r')
for h in lovy:
plt.plot(x,h+0*x,label=f"lov {h}")
ax.set(
xlabel="velikost populace",
ylabel="rychlost růstu a lovu",
title="Srovnání dynamiky růstu a lovu"
)
plt.legend()
<matplotlib.legend.Legend at 0x7f30dd93a8d0>
6.1.2. Konstantní úsilí#
Modifikujte předchozí kód s vykreslením časového vývoje populace vystavené lovu. Lov konstantní intenzitou nahraďte lovem s konstantním úsilím. Zkuste nejprve minimální úprava kódu. Bez ohledu na efektivitu, vyjděte z předchozího a snažte se co nejméně modifikovat výchozí kód. Poté si prostudujte elegantnější přístup využívající toho, že žádné řešení neskončí v konečném čase.
# sem napiste reseni
U konstantního úsilí není problém s tím, že by některá řešení končila dříve. Proto může být programový kód kratší a čistý. Například nemusíme pracovat s vnořenými cykly a můžeme příkazu solve_ivp
poslat současně všechny počáteční podmínky. Pokusme se o to.
pocatecni_podminka = np.linspace(0.1,1.2,51).round(3)
meze = [0,10]
t = np.linspace(*meze,100)
def rovnice(t, x, r=1, K=1, h=0.15):
return r*x*(1-x/K)-h*x
lovy = [0.1,0.3,0.6]
### Definice tabulky s víceúrovňovými nadpisy sloupců, MultiIndex
### https://pandas.pydata.org/docs/user_guide/advanced.html
iterables = [lovy,pocatecni_podminka]
my_index = pd.MultiIndex.from_product(iterables, names=['lov', 'poč.podm.'])
df = pd.DataFrame(columns=my_index)
df["čas"] = t
for h in lovy:
r = solve_ivp(
lambda t,x:rovnice(t,x,h=h),
meze,
pocatecni_podminka,
t_eval=t,
).y.T
df[[(h,i) for i in pocatecni_podminka]]=pd.DataFrame(r)
df.set_index("čas", inplace=True)
df.T
čas | 0.000000 | 0.101010 | 0.202020 | 0.303030 | 0.404040 | 0.505051 | 0.606061 | 0.707071 | 0.808081 | 0.909091 | ... | 9.090909 | 9.191919 | 9.292929 | 9.393939 | 9.494949 | 9.595960 | 9.696970 | 9.797980 | 9.898990 | 10.000000 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
lov | poč.podm. | |||||||||||||||||||||
0.1 | 0.1 | 0.100 | 0.108371 | 0.117336 | 0.126920 | 0.137151 | 0.148054 | 0.159650 | 0.171950 | 0.184964 | 0.198694 | ... | 0.898016 | 0.898182 | 0.898329 | 0.898459 | 0.898573 | 0.898675 | 0.898768 | 0.898856 | 0.898940 | 0.899027 |
0.122 | 0.122 | 0.131909 | 0.142472 | 0.153707 | 0.165637 | 0.178276 | 0.191634 | 0.205712 | 0.220505 | 0.236000 | ... | 0.898404 | 0.898538 | 0.898656 | 0.898760 | 0.898852 | 0.898934 | 0.899008 | 0.899078 | 0.899147 | 0.899216 | |
0.144 | 0.144 | 0.155339 | 0.167371 | 0.180106 | 0.193555 | 0.207723 | 0.222605 | 0.238190 | 0.254458 | 0.271383 | ... | 0.898676 | 0.898787 | 0.898885 | 0.898971 | 0.899047 | 0.899115 | 0.899177 | 0.899235 | 0.899291 | 0.899349 | |
0.166 | 0.166 | 0.178662 | 0.192036 | 0.206123 | 0.220922 | 0.236423 | 0.252609 | 0.269455 | 0.286929 | 0.304989 | ... | 0.898878 | 0.898972 | 0.899055 | 0.899128 | 0.899192 | 0.899250 | 0.899302 | 0.899351 | 0.899399 | 0.899448 | |
0.188 | 0.188 | 0.201879 | 0.216470 | 0.231766 | 0.247752 | 0.264403 | 0.281690 | 0.299574 | 0.318011 | 0.336948 | ... | 0.899034 | 0.899115 | 0.899186 | 0.899249 | 0.899304 | 0.899354 | 0.899399 | 0.899441 | 0.899482 | 0.899524 | |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
0.6 | 1.112 | 1.112 | 1.038781 | 0.976482 | 0.922880 | 0.877138 | 0.838270 | 0.805131 | 0.776418 | 0.750671 | 0.726294 | ... | 0.407163 | 0.406875 | 0.406598 | 0.406333 | 0.406079 | 0.405835 | 0.405601 | 0.405376 | 0.405161 | 0.404954 |
1.134 | 1.134 | 1.057181 | 0.991996 | 0.936033 | 0.888480 | 0.848319 | 0.814316 | 0.785022 | 0.758774 | 0.733722 | ... | 0.407263 | 0.406970 | 0.406690 | 0.406421 | 0.406163 | 0.405915 | 0.405678 | 0.405450 | 0.405232 | 0.405022 | |
1.156 | 1.156 | 1.075507 | 1.007379 | 0.949009 | 0.899631 | 0.858199 | 0.823389 | 0.793589 | 0.766905 | 0.741191 | ... | 0.407361 | 0.407065 | 0.406780 | 0.406508 | 0.406246 | 0.405995 | 0.405755 | 0.405524 | 0.405303 | 0.405090 | |
1.178 | 1.178 | 1.093759 | 1.022631 | 0.961806 | 0.910585 | 0.867910 | 0.832358 | 0.802137 | 0.775090 | 0.748730 | ... | 0.407459 | 0.407159 | 0.406871 | 0.406594 | 0.406329 | 0.406075 | 0.405831 | 0.405597 | 0.405373 | 0.405157 | |
1.2 | 1.200 | 1.111938 | 1.037750 | 0.974419 | 0.921339 | 0.877452 | 0.841232 | 0.810687 | 0.783359 | 0.756369 | ... | 0.407558 | 0.407253 | 0.406961 | 0.406681 | 0.406412 | 0.406155 | 0.405908 | 0.405671 | 0.405443 | 0.405225 |
153 rows × 100 columns
fig,ax = plt.subplots()
for i in range(len(lovy)): # tři čáry mimo obrázek kvůli legendě
ax.plot([0,1],[-1,-1],label=f"none")
for i,h in enumerate(lovy):
ax.plot(df.index,df[h], color=f"C{i}", alpha=0.5)
ax.set(
title="Logistická rovnice s lovem s konstantním úsilím",
xlabel="bezrozměrný čas",
ylabel="bezrozměrná velikost populace",
ylim=[0,None]
)
plt.legend([f"lov {lov}" for lov in lovy]);
fig,ax = plt.subplots()
x = np.linspace(0,1)
plt.plot(x,rovnice(0, x,h=0),label="růst bez lovu")
for a in lovy:
plt.plot(x,a*x,label=f"lov {a}")
ax.set(
xlabel="velikost populace",
ylabel="rychlost růstu a lovu",
title="Srovnání dynamiky růstu a lovu",
ylim=(0,0.3)
)
plt.legend()
<matplotlib.legend.Legend at 0x7f30d440c440>
6.2. Alleeho efekt#
Nakreslete model řešení rovnice modelující lov konstantním úsilím v populaci s Alleeho efektem. Můžete uvažovat slabý Aleeho efekt (pro malé velikosti populace se dynamika růstu výrazně zpomalí) nebo silný Alleeho efekt (pro malé velikosti populace vymírá). Můžete použít například rovnici
# sem napiste kod pro vykreslení krivek rustu a lovu
# sem napiste kod pro vykreslení reseni diferenciální rovnice
6.3. Populace pod predačním tlakem#
Vykreslete model pro populaci pro predačním tlakem https://robert-marik.github.io/dmp/prednaska/05.html#populace-pod-predacnim-tlakem. Použijte bezrozměnrou formulaci, tj. rovnici
# sem napiste reseni