V této lekci si ukážeme, jak s dostatečnou přesností vypočítat obsah plochy pod křivkou (vyjdeme z poznatků z matematické analýzy).
Výpočet obsahu plochy pod funkcí ¶
Našim prvním úkolem bude spočítat obsah plochy pod funkcí na intervalu .

Na hodinách matematické analýzi jste si jistě ukazovali, jak lze určit plochu pod funkci vepisováním obdélníku o stejné délce. Počítal se horní a dolní odhad a bylon zřejmé, že skutečná plocha bude někde mezi těmito hodnotami.
My použijeme podobný postup, ale místo hodního a dolního odhadu budeme počítat jen jeden.

Jak je patrné z obrázku, místo toho, abysme jednotlivé obdélníky konstruovali tak, že budou všechny pod (nebo nad) funkcí (což by bylo náročné na výpočty), spočítáme funkční hodnotu “uprostřed” šířky obdélníku, a tuto hodnotu použijeme jako výšku obdélníku. Tímto se výpočet výrazně sníží. Navíc počítač nebude mít problém těchto obdélníků spočítat opravdu velké množství (o malé šířce) a tím aproximovat plochu s dostatečnou přesností.
Co tedy musíme vypočítat?
Na základě zvoleného počtu obdélníku musíme rozdělit zvolený interval na bodů, které budou stejně daleko od sebe.
Musíme zjistit šířku obdélníku.
Ve “středu” šířky každého obdélníku musíme zjistit funkční hodnotu funkce .
Spočítáme plochu jednotlivých obdélníků a následně tyto plochy sečteme.
1. Jak rozdělit interval na stejně velké úseky¶
Pokud chceme rozdělit například následující interval na 9 stejně dlouhých úseků, lze využít následující kód:
x=0:10:90x =
0 10 20 30 40 50 60 70 80 90
Ovšem pokud bychom stejný interval chtěli rozdělit na 8 stejných úseků, bylo by to již náročnější. Museli bychom spočítat, že délka kroku je
x=0:11.25:90x =
Columns 1 through 7:
0 11.2500 22.5000 33.7500 45.0000 56.2500 67.5000
Columns 8 and 9:
78.7500 90.0000
Obecně pro rozdělení intervalu na N stejných úseků, museli bychom použít následující vzorec pro zjištění šířky jednoho úseku:
Pokud bychom tedy interval chtěli rozdělit na 9 stejně velkých úseků, museli bychom spočítat
a tedy
x=0:pi/18:pi/2x =
Columns 1 through 8:
0 0.1745 0.3491 0.5236 0.6981 0.8727 1.0472 1.2217
Columns 9 and 10:
1.3963 1.5708
Protože by nás takové výpočty jen zdržovali, využijeme funkce linspace(a,b,c), která tyto výpočty provedene za nás. Parametr a je levá strana intervalu, parametr b je pravá strana intervalu a c značí počet bodů (nezapomeňte, že počet bodů je o 1 větší než je počet úseků).
x=linspace(0,pi/2,10)x =
Columns 1 through 8:
0 0.1745 0.3491 0.5236 0.6981 0.8727 1.0472 1.2217
Columns 9 and 10:
1.3963 1.5708
Pomocí příkazu linspace() jsem si tedy rozdělili interval na stejně dlouhé úseky-
2. Zjištění šířky obdélníku.¶
Interval jsem si v přechozím kroce rozdělili na stejné úseky, šířka všech obdélníků je tedy stejná. Zůstává otázkou, jak ji spočítat.
Protože jednotlivé body intervalu jsou uloženy v proměnné , bude stačít najít dvě sousední hodnoty a odečíst menší od větší a výsledek uložit do proměnné delta.
Pomocí x(i) zjistíme i-tou hodnotu vektoru , proto stačí napsat:
delta=x(2)-x(1)delta = 0.1745
Nemusíme nutně brát první dvě hodnoty, stačí libovolné jiné dvě po sobě jdoucí.
3. Zjištění funkční hodnotu funkce ve “středu” šířky každého obdélníku¶
Nyní je třeba zjistit funkční hodnoty funkce “uprostřed” šířky jednotlivých obdélníků. Abyhcom toto mohli udělat, musíme nejprve zjistit střed šířky.
Ukážeme si to na prvním obdélníku. Ten začíná v bodě 0 a končí v bodě 0.1745. Mohli bychom tedy střed zjistit pomocí rozdílu krajních hodnot, ale jednodušší bude k počátečnímu bodu přičíst polovinu šířky obdelníku:
x(1)+delta/2ans = 0.087266
U druhého obdélníku bychom postupovali obdobně
x(2)+delta/2ans = 0.2618
A to stejné u třetího
x(3)+delta/2ans = 0.4363
Z výše uvedého je vidět, že určení středu je poměrně přímočaré a abychom nemuseli všechny výpočty vypisovat, budeme muset použít cyklus for. Pokud by nám šlo pouze o středy obdélníků, vypadala by funkce následovně (pozor, zajímají nás jen počáteční body obdélníku, proto je v cyklu uvedeno 9 místo 10!):
for i=1:1:9
x(i)+delta/2
endans = 0.087266
ans = 0.2618
ans = 0.4363
ans = 0.6109
ans = 0.7854
ans = 0.9599
ans = 1.1345
ans = 1.3090
ans = 1.4835
Když už víme jak určit středy šířky, zbývá nám v těchto bodech spočítat funkční hodnoty funkce . Přidáme tedy k předchozímu kódu funkci sinus:
sin(x(1)+delta/2)ans = 0.087156
A pro všechny hodnoty s využitím cyklu for použijeme
for i=1:1:9
sin(x(i)+delta/2)
endans = 0.087156
ans = 0.2588
ans = 0.4226
ans = 0.5736
ans = 0.7071
ans = 0.8192
ans = 0.9063
ans = 0.9659
ans = 0.9962
4. Výpočet plochy jednotlivých obdélníků a následný součet těchto ploch¶
Když známe šířky obdélníků i jejich výšky (funkční hodnoty ve středech šířky), můžeme již vypočítat plochy jednotlivých obdélníků. Opět si to ukážeme na příkladu prvního obdélníku.
%delta odpovída sirce
%sin(x(1)+delta/2) odpovida vysce
%jejich vynasobenim dostavame plochu obdelniku
delta*sin(x(1)+delta/2)ans = 0.015212
Opět využijeme cyklus for, abychom provedli výpočet pro všechny obdélníky
for i=1:1:9
delta*sin(x(i)+delta/2)
endans = 0.015212
ans = 0.045172
ans = 0.073761
ans = 0.1001
ans = 0.1234
ans = 0.1430
ans = 0.1582
ans = 0.1686
ans = 0.1739
Dostali jsme tedy plochy jednotlivých obdélníků. Poslední co musíme udělat, je tyto hodnoty sečíst. Jendou z možností by bylo hodnoty uložit do vektoru a následně je sečíst. My ovšem použijeme přímočařejší přístup. Nejprve si vytvoříme proměnnou plocha kterou položíme rovnu jedné a následně v každém kroku cyklu for k této hodnotě přičteme vypočtený obsah obdélníku:
plocha=0
for i=1:1:9
plocha=plocha+delta*sin(x(i)+delta/2)
endplocha = 0
plocha = 0.015212
plocha = 0.060384
plocha = 0.1341
plocha = 0.2343
plocha = 0.3577
plocha = 0.5006
plocha = 0.6588
plocha = 0.8274
plocha = 1.0013
Nyní vše spojíme do jednoho kódu a máme hotovo. Kód jsme vylepšili tím, že do na začátku zadáváme počet bodů, na které si interval rozdělíme (tj. budeme mít N-1 obdélníků) a toto pak používáme jak ve funkci linspace tak v cyklu for. Změnou hodnoty v tedy upravíme přesnost celého výpočtu.
N=4000
x=linspace(0i,pi/2,N);
delta=x(2)-x(1)
plocha=0
for i=1:1:N-1
plocha=plocha+delta*abs(sin(x(i)+delta/2));
end
plochaN = 4000
delta = 3.9280e-04
plocha = 0
plocha = 1.0000
Pokud budeme chtít vypočítat hodnotu funkce na intervalu , stačí jen upravit meze ve funkci linspace
n=4000
x=linspace(0,pi,n);
delta=x(2)-x(1)
plocha=0
for i=1:1:n-1
plocha=plocha+delta*abs(sin(x(i)+delta/2));
end
plochan = 4000
delta = 7.8559e-04
plocha = 0
plocha = 2.0000
Pojďme spočítat plochu na intervalu .
n=4000
x=linspace(-2*pi,2*pi,n);
delta=x(2)-x(1)
plocha=0
for i=1:1:n-1
plocha=plocha+delta*sin(x(i)+delta/2);
end
plochan = 4000
delta = 3.1424e-03
plocha = 0
plocha = 1.0381e-15
Výsledkem je číslo, které je velmi blízko nule. Tento výsledek je správně, protože určitý intergrál na tomto intervalu opravdu je 0 (je to způsobeno tím, že funkce má na daném intervalu stejnou plochu nad i pod osou ).
Pokud bychom ovšem chtěli znát celkovou plochu, můžeme kód doplnit o absolutní hodnotu a tím vše vyřešit:
n=4000
x=linspace(-2*pi,2*pi,n);
delta=x(2)-x(1)
plocha=0
for i=1:1:n-1
plocha=plocha+abs(delta*sin(x(i)+delta/2));
end
plochan = 4000
delta = 3.1424e-03
plocha = 0
plocha = 8.0000
Výpočet obsahu ploch pod jinou funkcí¶
Pokud bychom chtěli najednou počítat plochu pod jinou funkcí, museli bychom zasáhnout do našeho kódu a vše upravit. Změna na by bylajendoduchá, jen by se změnila funkce sin na cos a bylo by vystaráno.
Co ovšem dělat v situaci, kdy budeme chtít třeba následující funkci ? Toto by již byla náročnější úprava, protože x(i)+delta/2) bychom museli zadávat dvakrát a výsledný kód by vypadal takto:
n=4000
x=linspace(-2*pi,2*pi,n);
delta=x(2)-x(1)
plocha=0
for i=1:1:n-1
plocha=plocha+abs(delta*((x(i)+delta/2)^2-(x(i)+delta/2)/3+pi-exp(7)));
end
plochan = 4000
delta = 3.142378248151445e-03
plocha = 0
plocha = 13575.85348058021
Nabízí se tedy otázka, jak toto vyřešit elegantněji. Naštestí existují anonymní funkce, které tento problém řeší.
Anonymní funkceumožňují velmi jednoduchým způsobem zadefinovat libovolnou funkci.
Pokud bychom potřebovali funkci treti_mocnina, která libovolné číslo umocní na třetí, použili bychom následující kód:
treti_mocnina=@(x) x^3treti_mocnina =
@(x) x ^ 3
Před rovná se je uveden název funkce, symbol @ zančí , že se jedná o anonymní funkci a do závorky se za něj píšou vstupní proměnné - v našem případě máme jednu vstupní proměnnou a označili jsme si ji . následuje již samotný výpočet.
Když nyní do funkce zadáme libovolné číslo, obdržíme jeho třetí mocninu:
treti_mocnina(3)ans = 27
Ještě jedna ukázka anonymní funkce
nesmysl=@(x) sin(x)-cos(x)
nesmysl(5)nesmysl =
@(x) sin (x) - cos (x)
ans = -1.242586460126365
Tato funkce pro libovolnou hodnotu spočíta rozdíl jejího sinu a cosinu.
S využitím těchto poznatků upravím naši funkci pro výpočet plochy tak, že na začátku si zadefinujeme funkci s využítím anonymní funkce a následně jen upravíme zbytek kódu tak, aby použil při výpočtu onu anonymní funkci.
n=4000
funkce=@(x) x.^2-x./3+pi-exp(7)
x=linspace(-2*pi,2*pi,n);
delta=x(2)-x(1)
plocha=0
for i=1:1:n-1
plocha=plocha+delta*abs(funkce(x(i)+delta/2));
end
plochan = 4000
funkce =
@(x) x .^ 2 - x ./ 3 + pi - exp (7)
delta = 3.142378248151445e-03
plocha = 0
plocha = 13575.85348058021
Pokud tedy budeme chtít spočítat obsah plochy pod křivkou pro libovolnou funkci, stačí tuto funkci zadat na začátku programu (a stejně tak bude třeba upravit meze dle potřeby).