Hlavní navigace

Matematika v příkazové řádce XVI

17. 5. 2006
Doba čtení: 11 minut

Sdílet

V šestnácté a současně i poslední části seriálu, který je věnován matematicky zaměřeným aplikacím ovládaným zejména z příkazového řádku a/nebo z celoobrazovkového textového terminálu, si ukážeme další možnosti při tvorbě grafů v aplikaci gnuplot. Nejprve se řekneme, jakým způsobem je možné v dvojrozměrném grafu prokládat zadané hodnoty různým typem křivek a posléze si představíme tvorbu trojrozměrných (prostorových) grafů.

Obsah

1. Dvojrozměrné grafy prokládané křivkami
2. Příkaz „fit“ a proložení hodnot libovolnou funkcí
3. Trojrozměrné grafy funkcí dvou nezávislých proměnných
4. Trojrozměrné grafy vytvořené z bodů uložených v externích textových souborech
5. Nastavení stylů trojrozměrných grafů
6. Použití binárních dat pro tvorbu trojrozměrných grafů
7. Další možnosti gnuplotu
8. Závěr

1. Dvojrozměrné grafy prokládané křivkami

V předchozích dvou částech tohoto seriálu jsme si ukázali, jakým způsobem se v gnuplotu tvoří dvojrozměrné grafy, tj. grafy funkcí jedné nezávislé proměnné nebo grafy získané z numerických dat uložených v externích souborech. Ještě jsme si však nepopsali jednu z velmi užitečných funkcí této aplikace: schopnosti prokládat zadanými body různé křivky, včetně spline křivek. V tomto ohledu je gnuplot použitelnější než většina tabulkových procesorů, OpenOffice.org či Microsoft Excel nevyjímaje. Možnosti vytváření křivek je možné využít například při zpracovávání naměřených hodnot u kterých očekáváme určité odchylky od hladkého průběhu funkce. Pomocí křivek se původně lomená čára spojující jednotlivé naměřené body „vyhladí“ a tím se může (ale podle povahy řešeného problému také nemusí) přiblížit skutečnosti.

Pro vytvoření hladké křivky slouží modifikátor smooth, který se zadává spolu s příkazem plot. U dvojrozměrných grafů je možné použít celkem pět různých typů předpřipravených křivek, pro obecné proložení je možné použít poměrně komplikovaný příkaz fit. Nejprve si připravíme datový soubor obsahující body umístěné v ploše. Skript, který taková data bude generovat, může v programovacím jazyku utility bc vypadat následovně (mimochodem, tvoří se body ležící na známé funkci sinc()):

scale=4
for (x=-10.0; x<=10.0; x+=0.8) {
    if (x!=0) {z=s(x)/x} else {z=1}
        print x, " ", z, "\n"
}
print "\n"
quit 

Spuštění výše uvedeného skriptu spolu s přesměrováním výstupu do souboru zajistí příkaz:

bc -l 2d.bc > 2d.txt 

Nyní si můžeme zkusit tato data zobrazit pomocí gnuplotu. Po zadání příkazu plot „2d.txt“ with lines se vykreslí graf podobný grafu zobrazenému na prvním obrázku.

math16_1
Obrázek 1: Dvojrozměrný graf získaný z externích dat

Vidíme, že díky malému počtu bodů uložených v externím souboru jsou v grafu patrné zlomy. Nyní si tedy vyzkoušíme proložení těchto bodů vhodnou křivkou. Pro tento účel se příkaz plot rozšíří o modifikátor smooth, za nímž je zadán jeden z typů křivky. Pro aproximaci bodů, tj. vytvoření křivky, která nemusí nutně procházet zadanými body, se používá modifikátor smooth bezier resp smooth sbezier (tvorba Bézierových křivek stupně N). Dále je možné body proložit přirozenou spline křivkou; to zajistí modifikátory smooth csplines resp. smooth acsplines (zde má každý bod přiřazenou váhu). Poslední možností je konstrukce polynomu prvního stupně pomocí modifikátoru smooth unique.

math16_2
Obrázek 2: Proložení bodů Bézierovou křivkou

math16_3
Obrázek 3: Proložení bodů přirozenou spline křivkou

2. Příkaz „fit“ a proložení hodnot libovolnou funkcí

Mnohem větší možnosti prokládání nám dává příkaz fix. Nejprve je nutné nadeklarovat funkci s několika nezávislými parametry, kterou mají být body proloženy; tuto funkci nazvěme například f(x). Posléze se pomocí příkazu:

fit f(x) via parametry 

iterativním výpočtem zjistí hodnoty zadaných parametrům přičemž se gnuplot v jednotlivých iteracích snaží, aby součet čtverců (druhých mocnin) všech odchylek byl co nejmenší. Nakonec je možné danou funkci vykreslit spolu se zadanými body, například příkazem:

plot "2d.txt", f(x) 

Na čtvrtém obrázku jsou zobrazeny průběhy několika funkcí, které se snaží aproximovat zadané body. Pro aproximační funkce byly vybrány polynomy nižších řádů (které poměrně špatně aproximují zadaný průběh) a příkazy, které vedly k zobrazení čtvrtého obrázku, mají tento tvar:

f1(x)=a1*x+b1
f2(x)=a2*x**2+b2*x+c2
f3(x)=a3*x**3+b3*x**2+c3*x+d3
f4(x)=a4*x**4+b4*x**3+c4*x**2+d4*x+e4

fit f1(x) "2d.txt" via a1,b1
fit f2(x) "2d.txt" via a2,b2,c2
fit f3(x) "2d.txt" via a3,b3,c3,d3
fit f4(x) "2d.txt" via a4,b4,c4,d4,e4

plot "2d.txt" with lines, f1(x), f2(x), f3(x), f4(x) 

math16_4
Obrázek 4: Množina bodů proložená polynomy nízkých stupňů

3. Trojrozměrné grafy funkcí dvou nezávislých proměnných

Jak již víme z předchozích částí tohoto seriálu, tvoří se dvojrozměrné grafy v gnuplotu pomocí příkazu plot. Pro vytvoření trojrozměrných grafů, zejména grafů funkcí dvou nezávislých proměnných, se používá příkaz splot, kde písmeno „s“ značí surface. Pro ilustraci si ukažme velmi jednoduchý příkaz, po jehož zadání se vykreslí výřez známé sedlové plochy:

splot x*y 

math16_5
Obrázek 5: Sedlová plocha zobrazená pomocí příkazu splot

Na dalším příkladu je prezentováno nastavení rozsahů hodnot obou nezávislých proměnných. Toto nastavení (resp. změna standardního nastavení) se provádí buď přímo při zadávání příkazu splot nebo, jak je na příkladu ukázáno, pomocí samostatných příkazů set xrange a set yrange. U obou příkazů se potřebný rozsah specifikuje v hranatých závorkách, minimální a maximální hodnoty jsou od sebe odděleny dvojtečkou:

set xrange [-10:10]
set yrange [-10:10]
splot sin(sqrt(x**2+z**2))/sqrt(x**2+z**2) 

math16_6
Obrázek 6: Graf funkce dvou nezávislých proměnných

4. Trojrozměrné grafy vytvořené z bodů uložených v externích textových souborech

Ve čtvrté kapitole si ukážeme, jakým způsobem se vytváří trojrozměrné grafy sestrojené z numerických dat, které jsou uloženy v externích textových souborech. Tvorba těchto grafů je v mnohém podobná práci s dvojrozměrnými grafy, které jsme si popisovali v předchozí části tohoto seriálu. Datovým základem je v nejjednodušším případě textový soubor (či datový proud) obsahující na každém řádku tři hodnoty reprezentující souřadnice bodu Pij=[x,y,z] v prostoru. Hodnoty by od sebe měly být odděleny mezerou či jiným bílým znakem. Ukážeme si vytvoření takového textového souboru; na rozdíl od předchozího pokračování tohoto seriálu však pro jeho generování nebudeme používat program napsaný v programovacím jazyce C, ale – abychom se přidrželi aplikací popisovaných v tomto seriálu – použijeme skript určený pro utilitu bc, která byla popsána ve druhé a třetí části:

scale=4
for (y=-3.0; y>=3.0; y+=0.1) {
    for (x=-3.0; x>=3.0; x+=0.1) {
        z=s(sqrt(x^2+y^2));
        print x, " ", y, " ", z, "\n"
    }
}
quit 

Výše uvedený skript se může interpretovat utilitou bc způsobem, který je ukázán na následujícím příkladu. Všimněte si volby -l, která způsobí načtení knihovny s matematickými funkcemi, ve které je obsažena i funkce sinus, jež je ve skriptu označená symbolem „s()“. Výsledná data jsou přesměrována do souboru se jménem 3d1.txt:

bc -l 3d_graf1.bc > 3d1.txt 

Po spuštění aplikace gnuplot je možné tato data načíst a zobrazit v trojrozměrném grafu pomocí příkazu:

splot "3d1.txt" 

Výsledek je zobrazen na sedmém obrázku.

math16_7
Obrázek 7: Trojrozměrný graf získaný po provedení příkazu splot „3d1.txt“

V mnoha případech budeme chtít, aby se jednotlivé po sobě následující body spojily pomocí úseček – to vede k vytvoření sítě, resp. mřížky. Nejprve vyzkoušíme účinek příkazu:

splot "3d1.txt" with lines 

math16_8
Obrázek 8: Trojrozměrný graf získaný po provedení příkazu splot „3d1.txt“ with lines

Na předchozím obrázku vidíme, že výsledný graf není v žádném případě dokonalý. Je to z toho důvodu, že gnuplot nedokáže určit, které body v grafu jsou krajní – ty totiž nemají být spojeny s následujícími body. Vzhledem k tomu, že v externím souboru lze vytvářet takzvané bloky či skupiny pomocí prázdného řádku (který bloky od sebe odděluje), je možné předchozí skript velmi jednoduchým způsobem modifikovat tak, aby se po výpisu všech bodů umístěných na jednom řádku provedlo oddělení bloků. Upravený skript vypadá následovně:

scale=4
for (y=-3.0; y>=3.0; y+=0.1) {
    for (x=-3.0; x>=3.0; x+=0.1) {
        z=s(sqrt(x^2+y^2));
        print x, " ", y, " ", z, "\n"
    }
    print "\n"
}
quit 

Po zpracování výstupu z předchozího skriptu gnuplotem získáme graf, který vypadá podobně, jako graf zobrazený na devátém obrázku.

math16_9
Obrázek 9: Korektní trojrozměrný graf získaný po provedení příkazu splot „3d1.txt“ with lines

Skript je možné dále zjednodušit, protože gnuplot v některých případech nevyžaduje, aby se v externím souboru nacházely x-ové a y-ové souřadnice. Potom je každý bod reprezentován pouze svojí z-ovou souřadnicí, v tomto případě je však nutné oddělovat jednotlivé bloky pomocí prázdného řádku, jinak by gnuplot nedokázat bodům automaticky přiřazovat jejich zbývající dvě souřadnice. Následuje výpis zjednodušeného skriptu, který na svůj výstup posílá pouze hodnoty z-ových souřadnic generovaných bodů.

scale=4
for (y=-3.0; y<=3.0; y+=0.1) {
    for (x=-3.0; x<=3.0; x+=0.1) {
        z=s(sqrt(x^2+y^2));
            print z, "\n"
        }
        print "\n"
}
quit 

5. Nastavení stylů trojrozměrných grafů

Podobně jako u grafů dvojrozměrných, i u prostorových grafů je možné specifikovat jejich styl, tj. způsob zobrazení jednotlivých bodů popř. princip jejich vzájemného propojení. K dispozici jsou některé styly známé už z tvorby dvojrozměrných grafů, ne všechny minule popsané styly je však možné aplikovat – to se týká především zobrazení chybových hodnot (rozptylu). Nejjednodušším způsobem zobrazení prostorového grafu je prosté promítnutí zadaných bodů do roviny obrazovky. Tento styl grafu, který je vhodné používat v případě, že je naměřených či vypočtených bodů velké množství, se zobrazí příkazem:

splot "3d1.txt" with points 

math16_a
Obrázek 10: Prostorový graf zobrazený příkazem splot „3d1.txt“ with points

Alternativně je možné body zvýraznit, implicitně se používá malý křížek. Tento typ grafu se zobrazí po zadání příkazu:

splot "3d1.txt" with dots 

math16_7
Obrázek 11: Prostorový graf zobrazený příkazem splot „3d1.txt“ with dots

Pospojování jednotlivých bodů pomocí úseček jsme si již ukázali v předchozí kapitole, zde tuto možnost uvádím pouze pro přehled. Použije se příkaz:

splot "3d1.txt" with lines 

math16_9
Obrázek 12: Prostorový graf zobrazený příkazem splot „3d1.txt“ with lines

Kombinací výše uvedených stylů je zobrazení jak jednotlivých bodů (implicitně pomocí křížků), tak i úseček spojujících tyto body. Pro vykreslení grafu tímto stylem se používá příkaz:

splot "3d1.txt" with linespoints 

math16_d
Obrázek 13: Prostorový graf zobrazený příkazem splot „3d1.txt“ with linespoints

Velmi názorné je vykreslení prostorového grafu, ve kterém se plocha mezi body vybarví, nikoli však konstantní barvou, ale barevnou škálou (paletou), která zdůrazňuje výšku bodů, tj. hodnoty jejich z-ových souřadnic. Tento typ grafu se vykreslí pomocí dvou příkazů (fungují až od verze 4):

set pm3d
splot "3d1.txt" 

V případě, že by bylo zapotřebí použít monochromatický (jednobarevný) výstup, například pro účely tisku na černobílých tiskárnách, je zapotřebí před oba příkazy uvést ještě příkaz:

set palette gray 

math16_e
Obrázek 14: Prostorový graf zobrazený příkazy set pm3d a splot „3d1.txt“

Posledním typem grafu, který byl zaveden ve čtvrté verzi gnuplotu, je zobrazení výšek bodů ve formě rastrového obrázku. Je to podobný způsob zobrazení, jaký se využívá v tématických mapách zvýrazňujících výšku hor a hloubku moří. Nastavení tohoto způsobu zobrazení se provede příkazem:

set pm3d map 

math16_f
Obrázek 15: Zobrazení výšek bodů ve formě rastru

6. Použití binárních dat pro tvorbu trojrozměrných gra­fů

Gnuplot při práci s prostorovými daty v omezené míře podporuje i načítání binárních souborů, tj. zpracování numerických údajů typu float (single) uložených v externím souboru. Vlastní načtení, zpracování a vykreslení je zajištěno příkazem:

splot "3d.bin" binary 

Všimněte si použití modifikátoru binary, jímž je gnuplotu sděleno, že má data ze souboru načítat v binární podobě. Vlastní formát uložení by měl být následující (všechny hodnoty umístěné v závorkách jsou uloženy binárně):

     <N+1>  <y0>   <y1>   <y2>  ...  <yN>
      <x0> <z0,0> <z0,1> <z0,2> ... <z0,N>
      <x1> <z1,0> <z1,1> <z1,2> ... <z1,N>
       :      :      :      :   ...    : 

Všimněte si způsobu rozmístění dat v binárním souboru. Nejdříve je uložena velikost celé matice resp. mřížky. Poté je uložen vektor y-ových souřadnic následovaný N vektory, přičemž každý tento vektor ve svém prvním prvku obsahuje x-ovou souřadnici následovanou N souřadnicemi z-ovými. Z toho vyplývá, že do binárních souborů se ukládají body umístěné v pravoúhlé mřížce, tato mřížka však nemusí mít ekvidistantní vzdálenosti mezi svými sloupci či řádky. Gnuplot takto uložená data načte a převede je pro každý bod P(i,j) na trojice souřadnic x(i), y(j) a z(i,j):

     <x0> <y0> <z0,0>
     <x0> <y1> <z0,1>
     <x0> <y2> <z0,2>
      :    :     :
     <x0> <yN> <z0,N>

     <x1> <y0> <z1,0>
     <x1> <y1> <z1,1>
      :    :     : 

7. Další možnosti gnuplotu

Kromě všech výše uvedených možností vykreslování plošných i prostorových grafů nabízí gnuplot i dva další typy grafů. Prvním z ještě nepopisovaných typů je graf zobrazující takzvaná vektorová pole. Ve své podstatě se jedná o plošný graf, ve kterém však není zobrazen průběh nějaké funkce, ale množina orientovaných čar či šipek (vektorů), které ukazují intenzitu a směr působení nějaké veličiny (například síly) v daném místě roviny. V současné době se technikám vizualizací vektorových polí věnuje velká pozornost, pro jejich zobrazování se dokonce používají i animace pomocí částicových systémů. Gnuplot však prozatím takové ambice nemá a vykresluje vektorová pole opravdu pomocí úseček či šipek. Jednoduchá ukázka vykreslení vektorového pole je uvedena na stránce http://gnuplot­.sourceforge.net/de­mo4.1/vector.html.

Druhým nepopsaným typem grafu je graf, ve kterém jsou zobrazeny kontury plochy funkce dvou nezávislých proměnných nebo plochy vytvořené z bodů načtených z externího souboru. Kontury jsou získané tím způsobem, že je vypočten průnik zpracovávané plochy s nějakými význačnými rovinami, typicky to bývají roviny s rovnicí z=c. Ukázka vytváření kontur je uvedena na stránce http://gnuplot­.sourceforge.net/de­mo4.1/contours­.html.

Tip do článku - TOP100

8. Závěr

Úspěšně jsme došli až k závěrečné části tohoto seriálu. Popsali jsme si v něm jak standardní součásti všech Unixových systémů odpovídajících normě POSIX, které slouží k matematickým výpočtům (jednalo se o utility dc a bc), tak i sice nePOSIXové, ale velmi užitečné aplikace umožňující provádění matematických výpočtů zapsaných pomocí jednoduchého a přitom mocného programovacího jazyka (calc), výkonný tabulkový procesor pracující v celoobrazovkovém terminálu (sc) a konečně aplikaci gnuplot, kterou je možné použít pro vykreslování plošných i prostorových grafů, a to nejenom na obrazovku v grafickém uživatelském rozhraní, ale i do mnoha typů externích souborů včetně stále populárního PostScriptu. Kromě popisovaných aplikací samozřejmě existuje i množství dalších matematicky orientovaných utilit a programů, nicméně zde prezentované aplikace je možné považovat za základ, jehož možnosti se násobí vzájemným propojením aplikací, což je ostatně i jedna ze základních myšlenek všech Unixových systémů.

Autor článku

Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.