🧮 Calculus v jazyku Python
Knižnica SymPy
Balíček/knižnica SymPy vo všeobecnosti slúži na vykonávanie symbolických operácii v jazyku Python.
Alternativne môžeme symbolické premenné definovať aj samostatne nasledovnou syntaxou:
Vo všeobecnosti je tak definovanie symbolických premenných možné opísať nasledovne:
NÁZOV_PREMENNEJ_1, NÁZOV_PREMENNEJ_2... = sp.symbols("NÁZOV_PREMENNEJ_1 NÁZOV_PREMENNEJ_2...") (Názvy premenných vo funkcii symbols v úvodzovkách sú oddelené medzerami)
Ak chceme jednotlivé symbolické premenné definovať samostatne je syntax nasledovná:
NÁZOV_PREMENNEJ = sp.Symbol("NÁZOV_PREMENNEJ")
Ďalej s premennými vo vzťahoch pracujeme ako štandardne. Avšak pozor na použitie ostatných matematických funckií. Tie musia byť taktiež symbolické. Ukážeme si to na priklade definície zobrazovacích rovníc z cvičenia 3.
Kód
from Degrees import *
P = {"U":np.radians(dms2deg(35,33,0)),"V":np.radians(dms2deg(15,8,0))} # Numerická premenná
R = 6371000 # Numerická premenná
x = ((R/2)*((sp.pi/2)-U))*(V+sp.sin(V)) # Definovanie zobrazovacej rovnice pre x
y = -((R/2)*((sp.pi/2)-U))*(1+sp.cos(V)) # Definovanie zobrazovacej rovnice pre y Všimnime si, že zo symbolickými premennými U a V pracujeme analogicky ako v štandardnom prípade kedy ide o numerické premenné.
V prípade použitia iných matematických funckcí alebo konštánt v tomto zápise je však taktiež nutné použiť symbolický typ. Konkrétne napr. pre výpočet kosínusu uhla by sme využili funkciu z knižnice NumPy, tento postup by v tomto prípade nefungoval. Funckie v symbolických výrazoch je tak potrebné využiť z knižnice SymPy, podobne ako to vydíte v rovniciach vyššie v prípade sínusu a konštanty pí.
Parciálne derivácie pomocou knižnice SymPy
Za predpokladu, že premenné máme definované symbolicky môžeme pristúpiť k derivácii výrazu. Na deriváciu funkcie podľa požadovanej premennej využijeme funkciu sp.diff(). Jej použitie je nasledovné:
sp.diff(DERIVOVANÁ_FUNKCIA, PREMENNÁ_PODĽA_KTOREJ_DERIVUJEME)
Prakticky si to môžeme ukázať na príklade z cvičenia, derivujem funkciu(výraz) x podľa premennej U:
Takto zderivovaná fukcia/výraz je však dzerivovaný len symbolický. Za predpokladu, že výsledkom derivácie nie je len konštanta, vo výsledku stále figurujú premenné. Pre ďalšiu prácu je tak potrebné určiť hodnotu derivácie dosadením numerických hodnôt. To vykonáme substitúciou(dosadením), pomocou metódy .subs(). Tento postup sa mierne líši od použitia bežných funkcií. Vzľadom na objektovo orientovaný prístup balíčka SymPy je potrebné substitúciu vykonať nasledovne:
KAM_CHCEM_DOSADIŤ.subs(ZA_ČO_DOSADZUJEM, HODNOTA_KTORÚ_DOSADZUJEM)
V prípade (je to aj náš prípad), že chcem dosadiť viacero hodnôt, je potrebné použiť zoznam(list) n-tíc(tuples), syntax je nasledovná:
KAM_CHCEM_DOSADIŤ.subs([(ZA_ČO_DOSADZUJEM_1, HODNOTA_KTORÚ_DOSADZUJEM),(ZA_ČO_DOSADZUJEM_2, HODNOTA_KTORÚ_DOSADZUJEM)...])
V našom prípade to urobíme nasledovne:
Takýmto spôsobom získame hodnotu parciálnej derivácie. Má to však jeden problém. Takýto výsledok má definovaný špecifický objektový dátový typ z balíčka SymPy. Pre ďalšie výpočny je tak nie veľmi dobre použiteľný. Opravíme to použitím funckie float(), ktorá z tohot dátového typu urobí štandardný dátový typ čísla z plávjúcou desatinnou čiarkou. Syntax je nasledovná: float(PREMENNÁ)
Celý postup môžeme zapísať aj pomocou rekurentných definícií nasledovne:
Určité integrály pomocou knižnice SymPy
Podobne ako sme realizovali deriváciu pomocou knižnice SymPy tak podobným spôsobom vieme aj integravať, využijeme na to funckiu sp.integrate(). Syntax jej použitia je nasledovná:
sp.integrate(INTEGROVANÁ_FUNKCIA, (INTEGRAČNÁ_PREMENNÁ, DOLNÁ_HRANICA, HORNÁ_HRANICA))
Nezabudnite si všimnúť, že v prípade výpočtu určitého integrálu je druhý argument funkcie sp.integrate() definovaný ako n-tica(tuple) s potrebnými hodnotami, konkrétne
(INTEGRAČNÁ_PREMENNÁ, DOLNÁ_HRANICA, HORNÁ_HRANICA)
Pre optimalizáciu som výpočet zakomentoval, žerie to dosť výpočtového výkonu.
Podobne, ako pri derivácii je vhodné použiť aj funkciu float(), avšak v tomto prípade to nie je vyložene nutné.
Určité integrály pomocou knižnice SciPy
Pre rýchlejší výpočet určitého integrálu je vhodné použiť funkciu z vedeckej knižnice SciPy. Syntax výpočtu je však mierne odlišná v porovnaní z výpočtami pomocou NumPy. Z tohto balíčka budeme potrebovať len jednu konkrétnu funkciu quad(). Preto je vhodné tento balíček importovať nasledovne:
K integrácii pristupíme tak, že najprv definujeme integrovanú matematickú funkciu, ako užívateľskú funkciu v jazyku python. Podrobnostiam tejto definície sa budeme venovať v nasledujúcej kapitole. Pre tento prípad však stačí využiť nasledujúcu syntax:
def NÁZOV_FUNKCIE(PREMENNÉ_ODDELENÉ_ČIARKOU):
return ČO_MÁ_FUNKCIA_VRÁTIŤ
Kód pre náš prípad môžeme zapísať nasledovne:
Následne vieme na takto definovanú funckiu zavolať funkciu z balíčka SciPy quad(). Syntax je nasledovná:
quad(FUNKCIA,DOLNÁ_HRANICA,HORNÁ_HRANICA)
Výsledkom použitia tejto funkcie sú dve hodnoty. Pre ďalšie výpočty je tak nutné uvážiť správny index vypočítanej hodnoty. V našom prípade sú indexy nasledovné:
- O = Numerická hodnota určitého integrálu s dosadenými hranicami
- 1 = Presnosť numerického výpočtu
quad(FUNKCIA,DOLNÁ_HRANICA,HORNÁ_HRANICA)[INDEX]
Pre naše potreby použijeme: quad(FUNKCIA,DOLNÁ_HRANICA,HORNÁ_HRANICA)[0]
Syntaktický zápis tak vyzerá nasledovne:
Pokročilejšie funkcie balíčka SciPy
V rámci minulého tutoriálu sme sa už venovali jednoduchej numerickej integrácii pomociu funkcie quad() z balíčka SciPy. Základné predpoklady pre prácu s matematickými funckcionalitami knižnice SciPy ostávajú nezmenené. Predpokladom je, že funkcia ktorú integrujeme, derivujeme… je definovaná ako užívateľská funkcia v prostredí Python. Na pripomenutie tu je všeobecná syntax:
def NÁZOV_FUNKCIE(PREMENNÉ_ODDELENÉ_ČIARKOU):
return ČO_MÁ_FUNKCIA_VRÁTIŤ
V tomto tutoriáli si priblížíme dve nové funkcie, a tými budú funkcie nquad() a newton(). Pre použitie je potrebné obe funkcie importovat:
Dvojné určité integrály
Dvojný (určitý) integrál vypočítame použitím funckie nquad(). Jej použitie spočíva definovaní integrovanej funkcie. Keďže ide o dvojný (resp. n-tý) integrál, je potrebné aby funkcia ktorú definujeme bola závislá od dvoch (resp. n) premenných podla ktorých budeme integrovať. Zapísať to môžeme nasledovne:
def INTEGROVANÁ_FUNCKCIA(INTEGRAČNÉ_PREMENNÉ_ODDELENÉ_ČIARKOU):
return ZÁPIS_FUNKCIE
Je nutné podotknúť, že itegračná funkcia musí byť závislá len od definovaných premenných, keďže k ostatným premenným sa bude pristupovať ako ku konštantám. Použitie môžeme inlustorvať na príklade s cvičení (výpočet plochy elipsoidického lichobežníka, ohraničeného šírkou a dĺžkou):
Následne na zadefinovanú intregračnú funkciu aplikujeme funkciu nquad(). Jej všeobecná syntax je nasledovná:
nquad(INTEGROVANÁ_FUNKCIA,[[DOLNÁ_HRANICA_1, HORNÁ_HRANICA_1],[DOLNÁ_HRANICA_2, HORNÁ_HRANICA_2]])
Pri použití na konkrétnej situácii je syntax nasledovná:
Newtonova metóda
Funkcia newton() implementuje Newtonovu metódu a umožňuje riešiť nelineárne rovnice. Ak je derivácia ťažko vypočítateľná, môže použiť numerické diferencovanie. Naše riešenie spočíva len vo využití numerického diferencovania, aj napriek tomu, že jedným vstupom funkcie newton() môže byť aj prvá analyticky určená derivácia. Funkciu, ktorá je vstupom pre Newtonovu metódu je potrebné uviesť v tvare \(f(x)=0\). Syntax je tak nasledovná: `newton(FUNKCIA,POČIATOČNÝ_ODHAD_KOREŇA) Použitie je tiež dobre ukázateľné aj na príklade z cvičení: