Obsah
2. Praktické příklady práce s vektory
6. Porovnávání skalárních hodnot i prvků vektorů
7. Obsah následující části seriálu
1. Operace s vektory
Programovací jazyk J je, podobně jako jeho ideový předchůdce APL, určen především pro tvorbu aplikací, v nichž se zpracovávají data uložená ve vektorech, maticích či polích s větším počtem dimenzí (může se jednat například o hierarchické mřížky atd.). Z tohoto důvodu je jazyk J vybaven jak jednoduchou syntaxí určenou pro zápis vektorů a matic, tak i sadou primitivních (základních) funkcí, pomocí nichž lze nad vektory i maticemi provádět různé operace. Nejprve si popíšeme primitivní funkce určené pro vytváření i další práci s vektory, které jsou vypsány v následující tabulce. U všech popisovaných funkcí bude uvedena i informace o tom, zda se jedná o funkci monadickou (tj. s jedním parametrem zapisovaným za symbol funkce) či dyadickou (s dvojicí parametrů, z nichž první se zapisuje před a druhý za symbol funkce). Tato informace je v případě jazyků J i APL velmi důležitá, protože již víme, že stejný symbol může být použit pro pojmenování dvou primitivních funkcí lišících se „pouze“ počtem svých parametrů:
Symbol funkce | Forma funkce | Popis funkce (význam) |
---|---|---|
+ – * % | dyadická | základní aritmetické operace prováděné nad dvojicí vektorů na korespondujících prvcích (též prováděné nad skalárem a vektorem) |
< <: > >: = ~: | dyadická | porovnání korespondujících prvků dvou vektorů |
# | monadická | vrací délku vektoru |
# | dyadická | kopie prvků vektoru představovaného druhým parametrem |
{ | dyadická | výběr prvku či více prvků z vektoru na základě indexů vybíraných prvků |
{. | dyadická | výběr prvních n prvků z vektoru |
}. | dyadická | výběr posledních délka-n prvků vektoru (= odstranění prvních n prvků) |
, | dyadická | spojení dvou vektorů či vektoru se skalárem |
/: | monadická | setřídění prvků vektoru sestupně (funkce vrací indexy prvků, ne jejich hodnoty) |
\: | monadická | setřídění prvků vektoru vzestupně (funkce též vrací indexy prvků, ne jejich hodnoty) |
i. | monadická | vytváří seznam (vektor) obsahující řadu čísel začínající nulou, popř. prázdný vektor |
i: | monadická | vytváří seznam (vektor) obsahující čísla on -n do n, kde n je parametr funkce |
p. | monadická | výpočet kořenů polynomu reprezentovaného vektorem obsahujícím koeficienty ai |
2. Praktické příklady práce s vektory
Základní aritmetické operace, se kterými jsme se již seznámili v předchozí části tohoto seriálu, je možné využít i při práci s vektory. V tomto případě se operace provádí vždy nad dvojicí odpovídajících prvků (dyadické funkce) popř. postupně pro všechny prvky vektoru (funkce monadické). Pokud nejsou délky vektorů shodné, nahlásí interpretr jazyka J chybu typu „length error“:
NB. Nejdříve vytvoříme tři proměnné NB. představující trojici vektorů x =: 1 2 3 4 y =: 9 8 7 6 z =: 11 12 NB. Čtyři základní aritmetické operace NB. (součet, rozdíl, součin, podíl) NB. prováděné nad prvky vektorů x+y 10 10 10 10 y-x 8 6 4 2 x*y 9 16 21 24 x%y 0.111111 0.25 0.428571 0.666667 NB. Následující příkaz skončí s chybou NB. neboť délky vektorů (=počty jejich NB. prvků) nejsou shodné x+z |length error | x +z
Při použití aritmetických funkcí může být jedním z parametrů i skalární hodnota, viz následující demonstrační příklady:
NB. Při volání aritmetických funkcí NB. je možné zkombinovat skalární hodnotu NB. s vektorem 2 * x 2 4 6 8 x * 2 2 4 6 8 NB. Předchozí dva výrazy 2 * x a 2 * y NB. sice vrátily shodný výsledek, ale některé NB. další aritmetické operace nejsou NB. komutativní, například dělení: 10 % x 10 5 3.33333 2.5 x % 10 0.1 0.2 0.3 0.4
Následují dva příklady použití dalších funkcí, konkrétně dyadické exponenciální funkce a monadické funkce pro výpočet faktoriálu:
NB. Při práci s vektory lze samozřejmě NB. použít i další primitivní funkce, NB. zde například funkci exponenciální x^y 1 256 2187 4096 NB. Monadická funkce (výpočet faktoriálu) ! x 1 2 6 24
3. Výběr prvků z vektorů
Další důležitou a současně i často používanou skupinou základních (primitivních) funkcí určených pro práci s vektory jsou funkce, které umožňují z vektoru vybrat hodnoty některých prvků. Jedná se o rozšíření funkcí „take“ a „drop“, se kterými jsme se již seznámili při popisu programovacího jazyka APL, ovšem s tím rozdílem, že prvky vektorů jsou v případě jazyka J číslovány od nuly, tj. první prvek má index roven 0 a index posledního prvku je roven délce vektoru-1. Dále se v této skupině nachází funkce umožňující provést spojení dvou vektorů, která se zapisuje pomocí ASCII znaku „,“ – čárka. V aplikacích se poměrně často vyskytuje i funkce vracející délku vektoru (ASCII znak „#“). V případě matic či polí tato funkce vrací rozměr všech jejich dimenzí, což si ukážeme v navazujících kapitolách:
NB. Nejdříve opět vytvoříme tři proměnné NB. představující trojici vektorů x =: 1 2 3 4 y =: 9 8 7 6 z =: 11 12 NB. Zjistíme délky (počet prvků) všech vektorů #x 4 #y 4 #z 2 NB. Spojení vektorů pomocí primitivní NB. funkce , (čárka) w =: x,y,z w 1 2 3 4 9 8 7 6 11 12 NB. Jak je výsledný vektor w dlouhý? #w 10 NB. Výběr pátého prvku (s indexem 4) 4 { w 9 NB. Výběr pátého, šestého a sedmého NB. prvku vektoru w (obdoba funkce take) 4 5 6 { w 9 8 7 NB. Výběr prvních čtyř prvků vektoru 4 {. w 1 2 3 4 NB. Vrácení vektoru BEZ jeho prvních NB. čtyř prvků (obdoba funkce drop) 4 }. w 9 8 7 6 11 12
4. Využití generátorů indexů
Ve čtvrté kapitole si ukážeme způsob použití takzvaných generátorů indexů představovaných primitivními funkcemi zapisovanými pomocí symbolů i. a i:. Jedná se o funkce, které odpovídají primitivní funkci ι, s níž jsme se již seznámili při popisu programovacího jazyka APL, ovšem s tím podstatným rozdílem, že první číslo generované funkcí i. má hodnotu nula, nikoli jedna, a poslední číslo má hodnotu n-1 a nikoli n (to souvisí s tím, že v programovacím jazyce J jsou položky vektorů číslovány–indexovány od nuly, podobně jako například v programovacích jazycích C, C++ či Java – viz též předchozí kapitolu věnovanou indexování). Povšimněte si taktéž, že se pomocí funkce i. dá vytvořit velké množství různých (nejenom) aritmetických řad, takže pro tyto účely není nutné používat programové smyčky. Navíc mohou být primitivní funkce i. a i: součástí nějakého složitějšího výrazu, čehož se při psaní aplikací poměrně často využívá, například při programové tvorbě matic (jednotková matice, trojúhelníková matice atd.):
NB. Základní použití generátoru indexů i. 10 0 1 2 3 4 5 6 7 8 9 NB. Poměrně snadno můžeme dosáhnout toho, NB. aby se počáteční hodnota generované NB. číselné řady "posunula" 20 + i. 10 20 21 22 23 24 25 26 27 28 29 NB. Řada začínající hodnotou -10 _10 + i. 10 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 NB. Posun a současně i změna "kroku" NB. při generování číselné řady 3 + 0.5 * i. 15 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.5 10 NB. Mocninná řada čísla 2 vytvořená NB. bez použití programové smyčky 2 ^ i. 10 1 2 4 8 16 32 64 128 256 512 NB. Výpočet prvních faktoriálu prvních deseti NB. přirozených čísel a nuly. NB. (připomeňme si, že funkce se vyhodnocují NB. zprava doleva, tj. nejdříve se vytvoří NB. vektor čísel, na jehož prvky je aplikována NB. primitivní funkce představující faktoriál) ! i. 10 1 1 2 6 24 120 720 5040 40320 362880 NB. Pomocí primitivní funkce i: lze vygenerovat NB. číselnou řadu symetrickou okolo nuly i: 10 _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10 NB. Změna kroku číselné řady 2* i: 10 _20 _18 _16 _14 _12 _10 _8 _6 _4 _2 0 2 4 6 8 10 12 14 16 18 20 NB. Opět výpočet mocnin čísla 2, tentokrát však NB. včetně záporných exponentů 2^ i: 5 0.03125 0.0625 0.125 0.25 0.5 1 2 4 8 16 32 NB. Vytvoření prázdného vektoru (jedna z nejčastěji NB. používaných možností tvorby prázdného vektoru) i. 0 NB. Ovšem pozor: v následujícím případě NB. se vytvoří vektor obsahující jeden prvek i: 0
5. Matice
Práce s maticemi je v programovacím jazyku J stejně snadná jako práce s vektory. Základní funkci při práci s maticemi představuje funkce reshape zapisovaná pomocí symbolu $. Tato funkce má stejné vlastnosti jako funkce ρ zmiňovaná při popisu programovacího jazyka APL – v prvním parametru (zapisovaného nalevo od symbolu $) jsou uloženy rozměry matice, v parametru druhém (uváděném napravo od symbolu $) pak její jednotlivé prvky, typicky uložené ve vektoru nebo v jiné matici:
NB. Vytvoření nulové matice NB. o rozměrech 3x3 prvky 3 3 $ 0 0 0 0 0 0 0 0 0 0 NB. Vytvoření matice a současně NB. i nastavení hodnot jejích prvků 3 2 $ 1 2 3 4 5 6 1 2 3 4 5 6 NB. Použití generátoru indexů NB. při vytváření matice 3 4 $ i. 12 0 1 2 3 4 5 6 7 8 9 10 11
Velmi důležitou „maticovou“ funkcí je funkce pro výpočet inverzní matice zapisovaná symbolem %.. Pomocí této funkce lze například vypočítat soustavu n rovnic o n neznámých:
x + 2y -3z = 15 x + y + z = 12 2x - y - z = 0
Nejprve vytvoříme příslušnou matici a zapíšeme do ní koeficienty (multiplikativní konstanty) uvedené před neznámými:
NB. Prvky ležící na jednotlivých řádcích jsou NB. od sebe pro větší přehlednost odděleny NB. trojicí mezer. m =: 3 3 $ 1 2 _3 1 1 1 2 _1 _1 m 1 2 _3 1 1 1 2 _1 _1
S využitím funkce %.m lze snadno vypočítat inverzní matici:
%.m 0 0.333333 0.333333 0.2 0.333333 _0.266667 _0.2 0.333333 _0.0666667
Po vynásobení inverzní matice vektorem obsahujícím pravé strany rovnic dostaneme kýžený výsledek – hodnoty neznámých x, y a z:
15 12 0 %.m 4 7 1
Další (ještě pokročilejší) maticové operace si ukážeme příště.
6. Porovnávání skalárních hodnot i prvků vektorů
Pro vzájemné porovnávání skalárních hodnot i hodnot prvků uložených ve vektorech, maticích i polích s vyššími dimenzemi se používají predikátové funkce nahrazující relační operátory známé z jiných programovacích jazyků. Návratovou hodnotou těchto funkcí je buď skalární hodnota 0 nebo 1, popř. vektor či matice obsahující pouze nuly a jedničky (nula samozřejmě značí nepravdu, jednička pravdu). Tyto funkce jsou popsány v následující tabulce. Povšimněte si především způsobu zápisu podmínky „menší nebo rovno“, „větší nebo rovno“ a „nerovnost“, protože se v nich používají znaky, které jsou oproti jiným programovacím jazykům odlišné:
Symbol funkce | Forma funkce | Popis (význam) |
---|---|---|
< | dyadická | predikát „menší než“ |
<: | dyadická | predikát „menší nebo rovno“ |
> | dyadická | predikát „větší než“ |
>: | dyadická | predikát „větší nebo rovno“ |
= | dyadická | predikát rovnosti |
~: | dyadická | predikát nerovnosti |
e. | dyadická | predikát „obsahuje“ |
Použití výše uvedených funkcí při porovnávání skalárních hodnot je velmi snadné:
1 <: 2 1 1 >: 2 1 <: 1 1 1 ~: 2 1 1 ~: 1
Kromě vzájemného porovnání skalárních hodnot je možné porovnat všechny prvky vektoru (matice) se skalární hodnotou, popř. prvky dvou vektorů (matic) navzájem. V tomto případě je výsledkem porovnání též vektor či matice obsahující hodnoty 0 a 1:
NB. Porovnání všech prvků vektoru se skalární hodnotou 1 2 3 4 > 2 0 0 1 1 1 2 3 4 < 2 1 0 0 0 1 2 3 4 = 2 0 1 0 0 NB. Porovnání dvou vektorů, které v tomto NB. případě musí mít shodnou délku. 1 2 3 4 < 4 3 2 1 1 1 0 0
Poslední funkcí, kterou si v této kapitole popíšeme, je funkce testující existenci prvku (prvků) ve vektoru či matici. Jedná se o funkci označovanou symbolem e., jejímž prvním parametrem je skalární hodnota či vektor hodnot, které se hledají v datové struktuře předané ve druhém parametru této funkce. Návratovou hodnotou funkce e. je pravdivostní hodnota 0 nebo 1 udávající, zda se příslušná hledaná hodnota (první parametr) skutečně ve druhém parametru nachází. Pokud se současně vyhledává více hodnot, je návratovou hodnotou vektor nul a jedniček, jak je to ostatně ukázáno v následujících demonstračních příkladech:
NB. Vytvoření vektoru čísel x=:1 2 3 4 5 0.3 _1 42 NB. Zjištění, zda vektor obsahuje hodnotu 10 10 e. x NB. Zjištění, zda vektor obsahuje hodnotu 1 1 e. x 1 NB. Dtto pro hodnotu 2 2 e. x 1 NB. Vytvoření vektoru hledaných čísel y=:1 3 5 NB. Zjištění, zda vektor x obsahuje čísla 1, 3 a 5 y e. x 1 1 1 NB. Vyhledání více prvků bez použití NB. pomocného vektoru 1 10 100 1000 42 e. x 1 0 0 0 1 NB. Vektor, ve kterém je prováděno vyhledávání, NB. může být sestrojen funkcí i. 1 5 10 e. i. 10 1 1 0 NB. Vyhledání všech násobků dvou v řadě NB. obsahující násobky čísla 3. (2* i. 20) e. (3* i. 20) 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0
7. Obsah následující části seriálu
V následující části seriálu o historii výpočetní techniky dokončíme popis programovacího jazyka J. Řekneme si, jaké knihovny jsou dodávané spolu s interpretrem tohoto jazyka a ukážeme si též tvorbu grafů, které v mnoha případech tvoří poměrně významnou část aplikací vytvářených v tomto programovacím jazyce (jedná se například o různé simulace nebo finanční aplikace). Nezapomeneme ani na vysvětlení termínu tacit programming.
Před přípravou dalších dílů prosím laskavé čtenáře, aby sami dopředu určili, kterým směrem by se tento seriál měl vyvíjet; zda popisem hardware (další mainframy, grafické stanice SGI, superpočítače) nebo spíše software a programovacích jazyků (PL/I, RPG, K – pokračovatel J, programovací jazyky zaměřené na výuku).
8. Literatura
- Linda Alvord and Norman Thomson, „Easy-J: An Introduction to the World's most Remarkable Programming Language“
October 2002 - Ulf Grenander, „Mathematical Experiments on the Computer,“
Academic Press, 1982, ISBN 0–12–301750–5. - K. E. Iverson, „A Programming Language“,
Wiley, 1962. - K. E. Iverson, „Algebra : an algorithmic treatment“,
APL Press 1977, Copyright 1972 by Addison Wesley,
Preliminary Edition entitled „Elementary Algebra“
Copyright 1971 by IBM Corporation.
- K. E. Iverson, „Elementary analysis“,
APL press 1976, Preliminary Edition „Elementary Functions“
Copyright 1974 by IBM Corporation ISBN 0–917326–01–6
- K. E. Iverson, „A personal view of APL,“
IBM Systems Journal, - C. Reiter, „Fractuals Visualization and J“,
Iverson Software, Inc, 1995 ISBN 1–895721–11–3. - „J Phrases,“
Iverson Software, 1996, ISBN 1–895721–12–1 - „Exploring Math“, Iverson Software, 1996, ISBN 1–895721–13-X
- „J Primer,“
Iverson Software, 1996, ISBN 1–895721–14–8
9. Odkazy na Internetu
- Learning J (Roger Stokes)
http://www.jsoftware.com/…contents.htm - J: a modern, high-level, general-purpose, high-performance programming language
http://www.jsoftware.com/ - K, Kdb: an APL derivative for Solaris, Linux, Windows
http://www.kx.com - Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
http://www.vector.org.uk/ - APL – A Glimpse of Heaven
http://www.vector.org.uk/…/legrand.htm - APL Interpreters
http://www.vector.org.uk/?… - APL_(programming_language
http://en.wikipedia.org/wiki/APL_(programming_language - APL FAQ
http://www.faqs.org/faqs/apl-faq/ - APL FAQ (nejnovější verze)
http://home.earthlink.net/…apl.faq.html - A+
http://www.aplusdev.org/ - Rosetta Code
http://rosettacode.org/wiki/Main_Page