Ukázky práce v Pythonu
Python představuje interpretovaný dynamicsky silně typovaný (dynamic, strong, duck) programovací jazyk, který patří k základní předinstalované výbavě prakticky každé distribuce. Matematické schopnosti samotného Pythonu nijak nepřesahují standardní knihovnu C++, základní instalaci Javy či standardy dalších obecných programovacích jazyků. Python si lze „ošahat“ spuštěním jeho interpretu z terminálu příkazem python
. Po spuštění lze interaktivně zadávat příkazy. Můžeme zde pracovat podobně jako například s konzolovou kalkulačkou bc
. Na rozdíl od primitivní bc
je Python extrémně syntakticky bohatý multiparadigmatický jazyk, což demonstruji v následujícím výpisu. Tuto ilustraci v následujícím odstavci okomentuji.
uzivatel@uzivatel-desktop:~$ python Python 2.6.2 [GCC 4.5.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> a = [1,2,4,2,2,8] >>> b = [2,3,4,2,2,2] >>> [a[i] ** b[i] for i in range(len(a))] [1, 8, 256, 4, 4, 64] >>> a = [[0.2,0.3,0.1,3.2,0.1,0.8,0.3],[0.8,0.5,0.8,0.4,0.1],[0.8,2.1,1.8,0.5,0.3,0.4]] >>> a [[0.20000000000000001, 0.29999999999999999, 0.10000000000000001, 3.2000000000000002, 0.10000000000000001, 0.80000000000000004, 0.29999999999999999], [0.80000000000000004, 0.5, 0.80000000000000004, 0.40000000000000002, 0.10000000000000001], [0.80000000000000004, 2.1000000000000001, 1.8, 0.5, 0.29999999999999999, 0.40000000000000002]] >>> reduce(lambda x,y : x+y, a) [0.20000000000000001, 0.29999999999999999, 0.10000000000000001, 3.2000000000000002, 0.10000000000000001, 0.80000000000000004, 0.29999999999999999, 0.80000000000000004, 0.5, 0.80000000000000004, 0.40000000000000002, 0.10000000000000001, 0.80000000000000004, 2.1000000000000001, 1.8, 0.5, 0.29999999999999999, 0.40000000000000002] >>> reduce(lambda x,y : x+y, reduce(lambda x,y : x+y, a)) 13.500000000000002 >>> reduce(lambda x,y : x+y, [i for i in reduce(lambda x,y : x+y, a) if i<1]) 6.4000000000000004 >>>
Python nabízí některé vysokoúrovňové datové typy deklarované s pomocí speciální syntaxe. Třeba posloupnost tří prvků lze vytvořit jednoduše zápisem [první_položka,druhá,třetí]
. Slovník se zapisuje jako {klic0:polozka0,klic1:polozka1,klic2:polozka2}
, n-tice se zapisuje jako (první,druhý,třetí)
, množina jako {první,druhý,třetí}
, komplexní číslo jako například 1+1j
... Na třetím řádku jsem posloupnost nezapsal explicitním výčtem jejích prvků, ale nechal ji vygenerovat jako a[i]
umocněné na b[i]
, kde i
postupně probíhá od nuly do indexu posledního prvku posloupnosti a
.
Takto mohu zapisovat i složitě strukturované datové typy. Nyní si představme, že do a
přiřadím posloupnost měření, kdy každé měření je posloupností reálných čísel. Sečtením dvou posloupností se prvky druhé posloupnosti „dostanou“ na konec první posloupnosti. V následujícím řádku se uchyluji k funkcionálnímu paradigmatu. Redukcí posloupnosti operátorem sčítání zadaného lambda výrazem ruším rozdělení zjištěných hodnot do jednotlivých měření. V dalším příkazu působením opakované redukce získám součet všech změřených hodnot. (Všimněte si ortogonality operátoru sčítání. Většina operátorů v Pythonu je navržena jako ortogonální.) Nyní chci zanedbat hodnoty větší než jedna, protože se s určitostí jedná o výstřelový šum vzniklý v důsledku krátkodobého rozladění měřící aparatury, ionizace alfa zářením apod. V posledním již dosti složitém příkazu tato chybná měření ze součtu vyfiltruji. V dalším komentovaném výpisu budu demonstrovat základy práce s moduly v Pythonu a importuji standardní math
.
uzivatel@uzivatel-desktop:~$ python Python 2.6.2 [GCC 4.5.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> dir(math) ['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] >>> math.__doc__ 'This module is always available. It provides access to the\nmathematical functions defined by the C standard.' >>> math.sin(math.pi * 2) -2.4492127076447545e-16 >>> sin(pi * 2) Traceback (most recent call last): File "", line 1, in NameError: name 'sin' is not defined >>> from math import * >>> sin(pi * 2) -2.4492127076447545e-16 >>> help(math.sin) >>>
Vestavěná funkce dir
vrátí posloupnost všech přístupných symbolů. V rámci konvencí proměnná __doc__
obsahuje krátký dokumentační řetězec. Podrobnější nápovědu zobrazí vestavěná funkce help
, která pracuje podobně jako příkaz man
a manuálové stránky. Funkce sin
je importována jako math.sin
. Opakovaným odlišně zapsaným importem (from math import sin
), mohu importovat math.sin
do globálního jmenného prostoru. Ve výpisu jsem vše (značené hvězdičkou) z math
importoval do globálního jmenného prostoru. Jak je vidět, samotný jazyk Python z hlediska implementované matematiky neoslní. Mnohem zajímavější jsou dostupné balíčky, které s největší pravděpodobností již nebudete mít předinstalovány.
Jakou implementaci Pythonu zvolit?
Většinou se Python využívá jako interpretovaný jazyk, což není z hlediska výkonu příznivý fakt. Standardní běhové prostředí CPython umožňuje volat funkce napsané v kompilovaných programovacích jazycích (především v C/C++), což hojně využívají kritické části níže představovaného softwaru. Navíc z historických důvodů je mnoho numerických knihoven napsáno ve Fortranu. Na platformě Linux se sadou kompilátorů GCC a CPython se tím situace nijak nekomplikuje, což však nelze říci například o platformě Microsoft Windows, IronPython, .NET framework. Poslední řada Python 3+ je zpětně nekompatibilní. Proto doporučuji využívat novější verze dvojkové řady jako Python 2.6.
Jednotlivá řešení
Nejznámějším řešení v Pythonu zaměřené na matematiku jsou následující:
-
Balíček scipy je komplexní knihovna v oblasti numerické matematiky, které konkuruje známým aplikacím jako například GNU Octave. Scipy mimo jiné zvládá lineární algebru, FFT, zpracování signálů, optimalizace výpočtu pro řídké matice, optimalizace, interpolace, numerickou integraci nebo práci s obyčejnými diferenciálními rovnicemi.
-
Balíček numpy je de facto „podvozek“ pro scipy. Především s pomocí jazyka C vylepšuje datové typy, obsahuje také f2py, který zpřístupňuje Fortran.
-
Balíček matplotlib, který závisí na numpy, slouží především k vykreslování (plotting) a vizualizaci matematických dat. Podporované jsou GTK (resp. pygtk), Qt (resp. pyqt), wxWidget (resp. wxpython), Tk (resp. tkinter), SVG, LaTeX, PostScript, PDF. Vykreslování grafu se řídí textovými příkazy podobně jako například v R. (Poznámka: Skutečně se nepíše mathplotlib.)
-
Balík Sage je komplexní matematické prostředí, které využívá mnoho jiných projektů. Sage v sobě integruje přes sto svobodných projektů a jeho celková velikost se pohybuje ve stovkách megabytů.
Jako demonstrační ukázku jsem v Pythonu nasimuloval Brownův pohyb a zobrazil s pomocí matplotlib. Skutečně propracované grafické ukázky naleznete v oficiální galerii k matplotlib. Všechny tři zmíněné knihovny jsou rozsáhlé a jejich manuály se blíží tisíci stránkám. Tuto dokumentaci naleznete na oficiálních stránkách numpy, scipy a matplotlib. Další matematické balíky jsou například:
-
Balík scientificpython se vypořádává s různými praktickými problémy. Uplatnění nalezne především v oblasti aplikovaného výzkumu.
-
Balík simpy se zaměřuje na simulace.
-
Balík sympy se soustředí na symbolickou matematiku (Computer algebra system) podobně jako například Maxima.
Dále existují mnohé zajímavé pomocné moduly. Pokud počítáte na Beowulf clusteru nebo jiném HPC zařízení pravděpodobně oceníte pyMPI, který implementuje MPI (Message Passing Interface) rozhraní. Python se také využívá k psaní rozšiřujících uživatelských skriptů, čehož lze využít ve známých aplikací jako Blender, GIMP, Inkscape, Scribus... Z matematických aplikací tak činí třeba dataminingový program Orange, který konkuruje například javovskému KNIME.