Programovací jazyk K: důkaz, že mezi námi žijí mimozemšťané (dokončení)

28. 7. 2022
Doba čtení: 20 minut

Sdílet

 Autor: Depositphotos
Ve druhé a současně i závěrečné části článku o „mimozemském“ programovacím jazyku K se budeme zabývat způsobem práce s vícerozměrnými poli. Taktéž si podrobněji popíšeme práci s funkcemi definovanými uživatelem.

Obsah

1. Matice v programovacím jazyku K

2. Deklarace vektoru, nejjednodušší dyadická forma operátoru #

3. Operátor shape – získání „tvaru“ n-rozměrného pole

4. Operátor reshape – změna „tvaru“ n-rozměrného pole

5. Další konstrukce matic

6. Kombinace operátorů – vytvoření jednotkové matice

7. Konstrukce vícerozměrných polí

8. Modifikátor „outer product“

9. Ukázky dalšího možného využití modifikátoru „outer product“

10. „Outer product“ a uživatelské funkce

11. Uživatelská funkce v roli operátoru

12. Výběr matic, vektorů i skalárních hodnot z n-dimenzionálních polí

13. Přiřazení skaláru a vektoru do části matice

14. Transpozice matice, inverze matice a maticový součin

15. Dyadické uživatelské funkce

16. Monadické a dyadické projekce

17. Monadická projekce výpočtu faktoriálu

18. Několik složitějších příkladů

19. Kam dál?

20. Odkazy na Internetu

1. Matice v programovacím jazyku K

Na úvodní článek o „mimozemském“ programovacím jazyku K dnes navážeme. Zabývat se budeme především zpracováním vícerozměrných polí, protože právě manipulace s poli je v tomto jazyce velmi elegantní (ostatně vychází z APL, který je však v tomto kontextu nepatrně složitější kvůli nutnosti používání „boxingu“, což v K odpadá). Nejprve se seznámíme s klasickými maticemi, tedy vlastně s dvourozměrnými poli. Práce s maticemi vychází z jednorozměrných vektorů, ovšem namísto pouhé délky vektoru musíme pracovat se strukturou popisující počet dimenzí (2) i rozměry matice. Tato datová (resp. přesněji řečeno metadatová) struktura se nazývá shape, což je termín, s nímž se můžeme setkat například i v Pythonu, konkrétně v knihovně NumPy.

2. Deklarace vektoru, nejjednodušší dyadická forma operátoru #

Připomeňme si, jakým způsobem je možné deklarovat v programovacím jazyku K proměnnou typu vektor. Můžeme začít s vektorem délky 1, například s vektorem, jehož jediný prvek má hodnotu 0:

  v:0

Tento vektor můžeme „natáhnout“ na libovolnou zvolenou délku s využitím dyadického operátoru #, jehož levým operandem bude očekávaná výsledná délka vektoru (počet prvků) a operandem pravým původní vektor:

  20#v
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Poznámka: tento operátor je dyadický z toho důvodu, že má dva operandy, tedy levý operand a pravý operand. V článku uvidíme i monadické operátory; ty mají pouze pravý operand.

Můžeme ovšem postupovat i jinak. Například monadickým operandem ! zkonstruujeme vektor s trojicí hodnot 0, 1 a 2:

  v:!3
  v
0 1 2

Tento vektor následně „natáhneme“ na délku dvaceti prvků. Nové prvky vzniknou opakováním prvků původního vektoru:

  20#v
0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1

3. Operátor shape – získání „tvaru“ n-rozměrného pole

Ještě jednou si nadeklarujme proměnnou nazvanou v, která bude tentokrát obsahovat vektoru s 24 prvky s hodnotami od 0 do 23:

  v:!24
  v
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

V některých případech (ovšem není tomu tak často, jak by se mohlo na první pohled zdát) budeme chtít zjistit délku vektoru. K tomuto účelu můžeme použít operátor shape, který se zapisuje znakem #; ovšem v tomto případě se jedná o operátor monadický (s jediným parametrem):

  #v
24

Samotnou hodnotu 24 či pochopitelně jakoukoli jinou skalární hodnotu, jazyk K považuje za vektor s délkou jednoho prvku:

  #42
1

Ale i:

  shape:#v
  shape
24
 
  #shape
1

Ovšem můžeme psát i zkráceně:

  ##v
1

4. Operátor reshape – změna „tvaru“ n-rozměrného pole

Ještě jednou se vraťme k tomuto příkladu:

  v:0
  10#v
0 0 0 0 0 0 0 0 0 0

V něm jsme si operátorem # vynutili prodloužení vektoru na deset prvků. Tento operátor je dyadický a jmenuje se reshape. Jeho úkolem totiž není pouze prodloužení vektoru, ale například i vytvoření dvourozměrné matice z původně jednorozměrného vektoru. Postačuje, aby prvním operandem nebyl skalár s požadovanou délkou ale vektor s požadovaným tvarem.

Vypadá to složitě? Pokusme se z vektoru s 24 prvky vytvořit dvourozměrnou matici 6×4, tedy matici se šesti řádky a čtyřmi sloupci. Levým operandem operátoru # tedy bude vektor 6 4:

  v:!24
  v
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 
  6 4#v
(0 1 2 3
 4 5 6 7
 8 9 10 11
 12 13 14 15
 16 17 18 19
 20 21 22 23)

Pokud si nejste jisti, jak se vyhodnocují operandy, je možné použít i závorky:

  (6 4)#v
(0 1 2 3
 4 5 6 7
 8 9 10 11
 12 13 14 15
 16 17 18 19
 20 21 22 23)

Ve skutečnosti se však operandy vyhodnocují zprava doleva a všechny mají stejnou prioritu, takže závorky zde skutečně nejsou zapotřebí.

Vytvoření jiné matice, tentokrát 4×6:

  4 6#v
(0 1 2 3 4 5
 6 7 8 9 10 11
 12 13 14 15 16 17
 18 19 20 21 22 23)

Lze vytvořit i větší matici, než by odpovídalo počtu prvků vstupního vektoru. Prvky se budou v tomto případě opakovat, stejně jako při prodlužování samotných vektorů:

  8 6#v
(0 1 2 3 4 5
 6 7 8 9 10 11
 12 13 14 15 16 17
 18 19 20 21 22 23
 0 1 2 3 4 5
 6 7 8 9 10 11
 12 13 14 15 16 17
 18 19 20 21 22 23)

5. Další konstrukce matic

Vytvoření matice 10×10 s nulovými prvky, delší způsob zápisu:

  x:100#0
  10 10#x
(0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0)

„Natáhnout“ lze ovšem i skalární hodnotu, nikoli pouze vektor:

  x:0
  10 10#x
(0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0)

Což lze zkrátit na jediný řádek:

  10 10#0
(0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0)

6. Kombinace operátorů – vytvoření jednotkové matice

Pro vytvoření jednotkové matice neexistuje speciální operátor a ani to vlastně není nutné. Jednotková matice 5×5 se totiž zkonstruuje takto:

  5 5#1,5#0
(1 0 0 0 0
 0 1 0 0 0
 0 0 1 0 0
 0 0 0 1 0
 0 0 0 0 1)

Tento zápis si můžeme postupně složit z několika podvýrazů, z nichž jasně vysvitne onen trik:

  5#0
0 0 0 0 0
 
  1,5#0
1 0 0 0 0 0
 
  25#1,5#0
1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
 
  5 5#1,5#0
(1 0 0 0 0
 0 1 0 0 0
 0 0 1 0 0
 0 0 0 1 0
 0 0 0 0 1)

Celý zajímavý trik tedy spočívá v tom, že si uvědomíme, že matici 5×5 lze vytvořit z vektoru s 25 prvky, kde za jednotkovým prvkem následuje vždy pět prvků nulových.

Poznámka: později si ukážeme, jak se tato konstrukce „schová“ do uživatelské funkce.

7. Konstrukce vícerozměrných polí

Vícerozměrná pole se konstruují prakticky stejným způsobem jako matice. Pouze tvar (shape) bude reprezentován vektorem s větším množstvím prvků. Celkový počet prvků tohoto vektoru odpovídá počtu rozměrů pole, hodnoty prvků pak počtu prvků v každé dimenzi. Trojrozměrné pole 2×3×4 prvky tedy můžeme vytvořit například následujícím způsobem:

  2 3 4#!24
((0 1 2 3
  4 5 6 7
  8 9 10 11)
 (12 13 14 15
  16 17 18 19
  20 21 22 23))

Čtyřrozměrné pole 2×3×4×5 prvků:

  dimensions:2+!4
  dimensions
2 3 4 5
 
  dimensions#0
(((0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0)
  (0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0)
  (0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0))
 ((0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0)
  (0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0)
  (0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0
   0 0 0 0 0)))

Konstrukce takového pole na jediném řádku (závorky jsou zde nutné):

  (2+!4)#42
 
(((42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42)
  (42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42)
  (42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42))
 ((42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42)
  (42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42)
  (42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42
   42 42 42 42 42)))

8. Modifikátor „outer product“

V předchozí části tohoto článku jsme se mj. zabývali významem modifikátorů v programovacím jazyce K a taktéž jsme si některé nejdůležitější modifikátory popsali. Připomeňme si, že se jednalo o modifikátory nazvané over, scan a each. Ovšem v jazyce K je možné použít i další modifikátory. Jedním z prozatím nepopsaných modifikátorů je modifikátor nazvaný „outer product“ zapisovaný znakem : (dvojtečka), před níž následuje operátor a typicky modifikátor over. Tento modifikátor je založen na principu aplikace zvoleného dyadického operátoru nebo funkce na dvojici vektorů x a y, přičemž vybraná funkce (či operátor) je aplikována na všechny možné kombinace složek prvního a druhého vektoru. Výsledkem je tedy nová matice m obsahující v prvku mij návratovou hodnotu funkce aplikované na prvky xi a yj.

Ukažme si nyní použití tohoto modifikátoru. Začneme vytvořením matice ze dvou vektorů [1 2 3 4 5]; matice je složena ze všech možných kombinací součtů prvků:

  1 2 3 4 5 +/: 1 2 3 4 5
(2 3 4 5 6
 3 4 5 6 7
 4 5 6 7 8
 5 6 7 8 9
 6 7 8 9 10)

Tabulka malé násobilky (resp. její malá část):

  1 2 3 4 5 */: 1 2 3 4 5
(1 2 3 4 5
 2 4 6 8 10
 3 6 9 12 15
 4 8 12 16 20
 5 10 15 20 25)

Tabulka celé malé násobilky:

  (1+!10)*/:(1+!10)
(1 2 3 4 5 6 7 8 9 10
 2 4 6 8 10 12 14 16 18 20
 3 6 9 12 15 18 21 24 27 30
 4 8 12 16 20 24 28 32 36 40
 5 10 15 20 25 30 35 40 45 50
 6 12 18 24 30 36 42 48 54 60
 7 14 21 28 35 42 49 56 63 70
 8 16 24 32 40 48 56 64 72 80
 9 18 27 36 45 54 63 72 81 90
 10 20 30 40 50 60 70 80 90 100)

Závorky u nejpravějšího pod výrazu lze vynechat (operátory nemají prioritu):

  (1+!10)*/:1+!10
(1 2 3 4 5 6 7 8 9 10
 2 4 6 8 10 12 14 16 18 20
 3 6 9 12 15 18 21 24 27 30
 4 8 12 16 20 24 28 32 36 40
 5 10 15 20 25 30 35 40 45 50
 6 12 18 24 30 36 42 48 54 60
 7 14 21 28 35 42 49 56 63 70
 8 16 24 32 40 48 56 64 72 80
 9 18 27 36 45 54 63 72 81 90
 10 20 30 40 50 60 70 80 90 100)

Ještě lepší způsob – využití anonymní uživatelské funkce, takže se hodnota 10 ve výrazu vyskytuje pouze jedenkrát:

  {x*/:x}1+!10
(1 2 3 4 5 6 7 8 9 10
 2 4 6 8 10 12 14 16 18 20
 3 6 9 12 15 18 21 24 27 30
 4 8 12 16 20 24 28 32 36 40
 5 10 15 20 25 30 35 40 45 50
 6 12 18 24 30 36 42 48 54 60
 7 14 21 28 35 42 49 56 63 70
 8 16 24 32 40 48 56 64 72 80
 9 18 27 36 45 54 63 72 81 90
 10 20 30 40 50 60 70 80 90 100)

9. Ukázky dalšího možného využití modifikátoru „outer product“

Modifikátor „outer product“ je velmi univerzální, protože ho lze využít společně s jakýmkoli dyadickým (binárním) operátorem. To nám umožňuje realizovat různé triky, které budou ukázány v této kapitole.

Příprava pro vytvoření jednotkové atd. matice:

  (!10)-/:!10
(0 1 2 3 4 5 6 7 8 9
 -1 0 1 2 3 4 5 6 7 8
 -2 -1 0 1 2 3 4 5 6 7
 -3 -2 -1 0 1 2 3 4 5 6
 -4 -3 -2 -1 0 1 2 3 4 5
 -5 -4 -3 -2 -1 0 1 2 3 4
 -6 -5 -4 -3 -2 -1 0 1 2 3
 -7 -6 -5 -4 -3 -2 -1 0 1 2
 -8 -7 -6 -5 -4 -3 -2 -1 0 1
 -9 -8 -7 -6 -5 -4 -3 -2 -1 0)

V předchozí matici nastavíme nulové prvky na jedničku a nenulové na nulu – tím vytvoříme jednotkovou matici:

  0=(!10)-/:!10
(1 0 0 0 0 0 0 0 0 0
 0 1 0 0 0 0 0 0 0 0
 0 0 1 0 0 0 0 0 0 0
 0 0 0 1 0 0 0 0 0 0
 0 0 0 0 1 0 0 0 0 0
 0 0 0 0 0 1 0 0 0 0
 0 0 0 0 0 0 1 0 0 0
 0 0 0 0 0 0 0 1 0 0
 0 0 0 0 0 0 0 0 1 0
 0 0 0 0 0 0 0 0 0 1)

Horní trojúhelníková matice bez hlavní diagonály vznikne podobným trikem:

  0<(!10)-/:!10
(0 1 1 1 1 1 1 1 1 1
 0 0 1 1 1 1 1 1 1 1
 0 0 0 1 1 1 1 1 1 1
 0 0 0 0 1 1 1 1 1 1
 0 0 0 0 0 1 1 1 1 1
 0 0 0 0 0 0 1 1 1 1
 0 0 0 0 0 0 0 1 1 1
 0 0 0 0 0 0 0 0 1 1
 0 0 0 0 0 0 0 0 0 1
 0 0 0 0 0 0 0 0 0 0)

Podobná matice, ovšem s přidanou hlavní diagonálou:

  -1<(!10)-/:!10
(1 1 1 1 1 1 1 1 1 1
 0 1 1 1 1 1 1 1 1 1
 0 0 1 1 1 1 1 1 1 1
 0 0 0 1 1 1 1 1 1 1
 0 0 0 0 1 1 1 1 1 1
 0 0 0 0 0 1 1 1 1 1
 0 0 0 0 0 0 1 1 1 1
 0 0 0 0 0 0 0 1 1 1
 0 0 0 0 0 0 0 0 1 1
 0 0 0 0 0 0 0 0 0 1)
Poznámka: pozor si musíme dát jen na to, že nelze použít operátor <= atd.

Matice s vedlejší diagonálou:

  10=(!10)+/:!10
(0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 1
 0 0 0 0 0 0 0 0 1 0
 0 0 0 0 0 0 0 1 0 0
 0 0 0 0 0 0 1 0 0 0
 0 0 0 0 0 1 0 0 0 0
 0 0 0 0 1 0 0 0 0 0
 0 0 0 1 0 0 0 0 0 0
 0 0 1 0 0 0 0 0 0 0
 0 1 0 0 0 0 0 0 0 0)

10. „Outer product“ a uživatelské funkce

Předchozí výrazy mohou být v praxi užitečné a proto si je můžeme přepsat do uživatelských funkcí akceptujících velikost matice. Tato velikost bude předána jako jediný parametr dané funkci (tento parametr se uvnitř funkce jmenuje x).

Funkce konstruující jednotkovou matici 10×10 prvků:

  eye:{0=(!10)-/:!10}
 
  eye
{0=(!10)-/:!10}
 
  eye 42
(1 0 0 0 0 0 0 0 0 0
 0 1 0 0 0 0 0 0 0 0
 0 0 1 0 0 0 0 0 0 0
 0 0 0 1 0 0 0 0 0 0
 0 0 0 0 1 0 0 0 0 0
 0 0 0 0 0 1 0 0 0 0
 0 0 0 0 0 0 1 0 0 0
 0 0 0 0 0 0 0 1 0 0
 0 0 0 0 0 0 0 0 1 0
 0 0 0 0 0 0 0 0 0 1)
Poznámka: parametr předaný do funkce ve skutečnosti může být libovolný – není zde využit.

Zobecnění pro libovolnou velikost matice:

  eye:{0=(!x)-/:!x}
 
  eye
{0=(!x)-/:!x}
 
  eye 5
(1 0 0 0 0
 0 1 0 0 0
 0 0 1 0 0
 0 0 0 1 0
 0 0 0 0 1)

Funkce pro vytvoření trojúhelníkové matice s vynulovanou hlavní diagonálou:

  tri1:{0<(!x)-/:!x}
 
  tri1 8
(0 1 1 1 1 1 1 1
 0 0 1 1 1 1 1 1
 0 0 0 1 1 1 1 1
 0 0 0 0 1 1 1 1
 0 0 0 0 0 1 1 1
 0 0 0 0 0 0 1 1
 0 0 0 0 0 0 0 1
 0 0 0 0 0 0 0 0)

Funkce pro vytvoření trojúhelníkové matice včetně hlavní diagonály:

  tri2:{-1<(!x)-/:!x}
  tri2 6
(1 1 1 1 1 1
 0 1 1 1 1 1
 0 0 1 1 1 1
 0 0 0 1 1 1
 0 0 0 0 1 1
 0 0 0 0 0 1)

atd.

Poznámka: mezi názvem funkce a parametrem musí být zapsána mezera, na rozdíl od operátoru, který okolo sebe mezery nevyžaduje.

11. Uživatelská funkce v roli operátoru

Uživatelská funkce se v mnoha ohledech chová stejně jako operátor. Můžeme ji tedy zkombinovat s libovolným modifikátorem. Podívejme se opět na naši funkci pro konstrukci jednotkové matice:

  eye:{0=(!x)-/:!x}
 
  eye
{0=(!x)-/:!x}

Díky použití modifikátoru each můžeme snadno vytvořit jednotkové matice 0×0 až 5×5:

  eye' !6
(()
 ,,1
 (1 0
  0 1)
 (1 0 0
  0 1 0
  0 0 1)
 (1 0 0 0
  0 1 0 0
  0 0 1 0
  0 0 0 1)
 (1 0 0 0 0
  0 1 0 0 0
  0 0 1 0 0
  0 0 0 1 0
  0 0 0 0 1))

Mezery jsou zde zbytečné, takže:

  eye'2+!5
((1 0
  0 1)
 (1 0 0
  0 1 0
  0 0 1)
 (1 0 0 0
  0 1 0 0
  0 0 1 0
  0 0 0 1)
 (1 0 0 0 0
  0 1 0 0 0
  0 0 1 0 0
  0 0 0 1 0
  0 0 0 0 1)
 (1 0 0 0 0 0
  0 1 0 0 0 0
  0 0 1 0 0 0
  0 0 0 1 0 0
  0 0 0 0 1 0
  0 0 0 0 0 1))

V případě, že je funkce použita na jediném místě, nic nám nebrání použít funkci anonymní:

  {0=(!x)-/:!x}'2+!5
((1 0
  0 1)
 (1 0 0
  0 1 0
  0 0 1)
 (1 0 0 0
  0 1 0 0
  0 0 1 0
  0 0 0 1)
 (1 0 0 0 0
  0 1 0 0 0
  0 0 1 0 0
  0 0 0 1 0
  0 0 0 0 1)
 (1 0 0 0 0 0
  0 1 0 0 0 0
  0 0 1 0 0 0
  0 0 0 1 0 0
  0 0 0 0 1 0
  0 0 0 0 0 1))
Poznámka: což jsou výrazy, které již skutečně začínají připomínat šum na lince.

12. Výběr matic, vektorů i skalárních hodnot z n-dimenzionálních polí

Podívejme se nyní na způsob výběru matic, vektorů i skalárních hodnot z n-dimenzionálních polí. Začneme maticí, z níž budeme vybírat jak jednotlivé prvky (skalární hodnoty), tak i sloupce či řádky nebo dokonce celé podmatice:

  m:5 5 # !25
  m
(0 1 2 3 4
 5 6 7 8 9
 10 11 12 13 14
 15 16 17 18 19
 20 21 22 23 24)

Výběr n-tého řádku je snadný:

  m[1]
5 6 7 8 9

Vybrat můžeme i více řádků současně:

  m[1,2]
(5 6 7 8 9
 10 11 12 13 14)
 
  m[2,3]
(10 11 12 13 14
  15 16 17 18 19)

Výběr jednoho sloupce je zvláštní – vrátí se totiž vektor:

  m[;2]
2 7 12 17 22

Naproti tomu výběr většího množství sloupců již vrátí matici:

  m[;2,3]
(2 3
 7 8
 12 13
 17 18
 22 23)

Výběr jediného prvku z matice vyžaduje použití dvou hranatých závorek:

  m[1][2]
7

A konečně se podívejme na výběr podmatic, tedy nejprve řádků a následně sloupců:

  m[1,2,3;2,4]
(7 9
 12 14
 17 19)
 
  m[1,2,3;2,3,4]
(7 8 9
 12 13 14
 17 18 19)

Předchozí možnosti lze zkombinovat – z nové matice se vybere jen druhý řádek (s indexem rovným jedné):

  m[1,2,3;2,3,4][1]
12 13 14

13. Přiřazení skaláru a vektoru do části matice

Ve skutečnosti může být výběr matice, vektoru či skaláru použit i na levé straně přiřazovacího příkazu – tímto způsobem můžeme modifikovat stávající matici, a to efektivním způsobem. Opět začneme naší maticí 5×5 prvků:

  m:5 5 # !25
  m
(0 1 2 3 4
 5 6 7 8 9
 10 11 12 13 14
 15 16 17 18 19
 20 21 22 23 24)

Změna jediného prvku matice se zobrazením modifikované matice:

  m[2;2]:42
  42
 
  m
(0 1 2 3 4
 5 6 7 8 9
 10 11 42 13 14
 15 16 17 18 19
 20 21 22 23 24)

Změna celého řádku matice (druhý řádek s indexem rovným jedné):

  m:5 5 # !25
  m[1]:0 0 0 0 0
  m
(0 1 2 3 4
 0 0 0 0 0
 10 11 12 13 14
 15 16 17 18 19
 20 21 22 23 24)

Změna celého sloupce matice (druhý sloupec s indexem rovným jedné):

  m:5 5 # !25
  m[;1]:-1 -1 -1 -1 -1
  m
(0 -1 2 3 4
 5 -1 7 8 9
 10 -1 12 13 14
 15 -1 17 18 19
 20 -1 22 23 24)

14. Transpozice matice, inverze matice a maticový součin

V této kapitole si popíšeme některé často prováděné maticové operace. Začneme s maticí 10×10 prvků, která vznikne následovně:

  m:10 10 # !100
  m
(0 1 2 3 4 5 6 7 8 9
 10 11 12 13 14 15 16 17 18 19
 20 21 22 23 24 25 26 27 28 29
 30 31 32 33 34 35 36 37 38 39
 40 41 42 43 44 45 46 47 48 49
 50 51 52 53 54 55 56 57 58 59
 60 61 62 63 64 65 66 67 68 69
 70 71 72 73 74 75 76 77 78 79
 80 81 82 83 84 85 86 87 88 89
 90 91 92 93 94 95 96 97 98 99)

Transpozici matice zajišťuje operátor +:, který by byl jinak nevyužitý, protože ostatní tři varianty -:, *: a %: mají odlišný význam – jedná se o unární operace nad všemi prvky:

  +:m
(0 10 20 30 40 50 60 70 80 90
 1 11 21 31 41 51 61 71 81 91
 2 12 22 32 42 52 62 72 82 92
 3 13 23 33 43 53 63 73 83 93
 4 14 24 34 44 54 64 74 84 94
 5 15 25 35 45 55 65 75 85 95
 6 16 26 36 46 56 66 76 86 96
 7 17 27 37 47 57 67 77 87 97
 8 18 28 38 48 58 68 78 88 98
 9 19 29 39 49 59 69 79 89 99)

Maticový součin provádí funkce/operátor _mul. Pochopitelně se kontroluje, zda jsou vstupní matice kompatibilní z hlediska maticového součinu (počet sloupců první matice je totožný s počtem řádků matice druhé):

  m1:3 4#!12
  m1
(0 1 2 3
 4 5 6 7
 8 9 10 11)
  m2:4 5#!20
  m2
(0 1 2 3 4
 5 6 7 8 9
 10 11 12 13 14
 15 16 17 18 19)
  m1 _mul m2
(70 76 82 88 94
 190 212 234 256 278
 310 348 386 424 462)
  m2 _mul m1
length error
x _dot\:y
  ^

Inverzní matice se vypočte unárním operátorem/funkcí _inv:

  m1:3 3#0 1 0 1 1 1 0 1 1
  m1
(0 1 0
 1 1 1
 0 1 1)
  _inv m1
(-1.110223e-16 1 -1.0
 1 -1.110223e-16 5.551115e-17
 -1 -2.775558e-16 1.0)

Kontrola, zda po vynásobení původní matice s maticí inverzní získáme jednotkovou matici:

  m2:_inv m1
  m1 _mul m2
(1 -1.110223e-16 5.551115e-17
 -5.551115e-16 1 3.330669e-16
 -4.440892e-16 -3.885781e-16 1.0)
Poznámka: ano, získáme, tedy s ohledem na přesnost výpočtů. Hodnoty Xe-17 jsou z tohoto pohledu prakticky nulové.

15. Dyadické uživatelské funkce

V krátkosti se ještě podívejme na deklaraci dyadických funkcí. Tyto funkce pracují s parametry pojmenovanými x a y, takže lze například psát:

  add:{x+y}

Volání takové funkce ovšem není v čistě dyadické formě, ale provádí se takto:

  add[1;2]
3
Poznámka: což se zdá být omezení konkrétní verze jazyka K.

Parametry lze i přejmenovat, což se provádí takto:

  add:{[first;second] first+second}
  add[1;2]
3

Podobně lze vytvořit funkce s větším množstvím parametrů (triadické funkce?):

  add3:{[first;second;third] first+second+third}
  add3 [1;2;3]
6

16. Monadické a dyadické projekce

V této kapitole se budeme zabývat programovými konstrukcemi s poněkud strašidelným názvem monadické a dyadické projekce. Jedná se o formu tacit programmingu, což je téma, kterému jsme se již na stránkách Roota věnovali v tomto článku. Celý princip projekcí spočívá v tom, že se definuje pouze část výrazu, který sice sám o sobě nemůže být vykonán (typicky proto, že mu chybí jeden operand), ale může být pojmenován a použit později. Jedná se tedy o zjednodušenou formu zápisu některých typů funkcí.

Takto si můžeme vytvořit dyadickou projekci nazvanou minus, která se vyhodnotí až po dosazení pravého operandu výrazu 0-(chybějící operand):

  minus:0-
  minus 42
-42

Naproti tomu monadická projekce vyžaduje dvojtečku na konci (zde je operátor – použit v monadické podobě, tedy s jediným operandem):

  minus:-:
  minus 42
-42

Dyadická projekce použitá pro vytvoření funkce/operátoru pojmenovaného inc:

  inc:1+
  inc 42
43

Dyadická projekce bez výchozích operandů:

  add:+
  add
+
  add[1;2]
3

17. Monadická projekce výpočtu faktoriálu

Připomeňme si, jak je možné v jazyku K vypočítat faktoriál, například faktoriál vstupní hodnoty 10. Nejprve si necháme vygenerovat vektor 0 1 2 … 9:

  !10
0 1 2 3 4 5 6 7 8 9

Ke všem prvkům vektoru připočteme jedničku:

  1+!10
1 2 3 4 5 6 7 8 9 10

A aplikujeme modifikátor over s operátorem *, čímž všechny prvky vektoru vynásobíme:

  */1+!10
3628800

Tento zápis, až na poslední hodnotu 10, můžeme použít pro definici výpočtu vektoru ve formě monadické projekce:

  fact:*/1+!:
  fact 10
3628800

Modifikátorem each snadno vytvoříme vektor s hodnotami 0!, 1!, … 9!:

  fact'!10
1 1 2 6 24 120 720 5040 40320 362880
Poznámka: taktéž by šlo použít modifikátor scan s menším počtem operací (ovšem s výjimkou 0!):
  *\1+!10
1 2 6 24 120 720 5040 40320 362880 3628800

18. Několik složitějších příkladů

Zkusme se podívat na několik složitějších příkladů, které ukazují jak krátký (stručný) zápis programů, tak i do značné míry jejich nečitelnost.

Výpočet Fibonacciho posloupnosti pro zadaný počet prvků:

  fib:{x{x,+/-2#x}/!2}
  fib 10
0 1 1 2 3 5 8 13 21 34 55 89

Generátor Pascalova trojúhelníku:

  pasc: {x{+':0,x,0}\1}
  pasc 10
(1
 1 1
 1 2 1
 1 3 3 1
 1 4 6 4 1
 1 5 10 10 5 1
 1 6 15 20 15 6 1
 1 7 21 35 35 21 7 1
 1 8 28 56 70 56 28 8 1
 1 9 36 84 126 126 84 36 9 1
 1 10 45 120 210 252 210 120 45 10 1)

Test, zda je hodnota (či hodnoty) prvočíslem či nikoli:

  isprime:{(x>1)&&/x!'2_!1+_sqrt x}
 
  isprime 3
1
 
  isprime 4
0

Test prvočísel v prvních deseti přirozených číslech:

  isprime' 1+!10
0 1 1 0 1 0 1 0 0 0

Prvočísla v rozsahu 1 až 99:

ict ve školství 24

  (!100)[&isprime' !100]
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Stejný výpočet, ovšem s využitím anonymní funkce (což již začíná připomínat šum na lince):

  (!100)[&{(x>1)&&/x!'2_!1+_sqrt x}' !100]
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

19. Kam dál?

Připadá vám jazyk K dostatečně šílený na to, aby byl zajímavý? Kromě samotného jazyka K (který je z celé skupiny asi nejvíce šílený) existuje i několik podobně koncipovaných programovacích jazyků. Jazykem J jsme se již na stránkách Roota ve stručnosti zabývali. Připomeňme si, že právě v tomto jazyku se do značné míry preferuje tacit programming namísto klasických funkcí s pojmenovanými parametry. Ovšem přímým pokračovatelem jazyka K je jazyk Q, za jehož vývojem opět stojí (pravděpodobný mimozemšťan) Arthur Whitney.

20. Odkazy na Internetu

  1. K language – an introduction
    http://www.math.bas.bg/ban­tchev/place/k.html
  2. K7 Tutorial
    https://cs.nyu.edu/~shasha/pa­pers/tutorial
  3. An Interview with Arthur Whitney, Kx CEO and Developer of Kx Technology, January 4, 2004
    https://web.archive.org/web/20150813004101/htt­p://kx.com/arthur-interview.php
  4. A Shallow Introduction to the K Programming Language
    https://web.archive.org/web/20130801233812/htt­p://www.kuro5hin.org/story/2002/11/14/22741/791
  5. A Conversation with Arthur Whitney
    https://queue.acm.org/deta­il.cfm?id=1531242
  6. Anecdote about Arthur Whitney
    https://news.ycombinator.com/i­tem?id=13590065
  7. K – list of idioms
    https://github.com/kevinlaw­ler/kona/wiki/Idioms
  8. Appendix A. Incunabulum
    http://keiapl.org/rhui/re­member.htm#incunabulum
  9. K code study
    https://docs.google.com/do­cument/d/1W83ME5JecI2hd5hA­UqQ1BVF32wtCel8zxb7WPq-D4f8/edit
  10. K tutorial
    https://github.com/kevinlaw­ler/kona/wiki/Tutorial
  11. K by EXAMPLE
    http://vrabi.web.elte.hu/k/kbyeg.k
  12. BQN: An APL Variant from Marshall Lochbaum (mlochbaum.github.io)
    https://news.ycombinator.com/i­tem?id=24167804
  13. Raytracer in 7 lines in K
    http://www.nsl.com/k/ray/ray.k
  14. Marshall Lochbaum
    https://www.aplwiki.com/wi­ki/Marshall_Lochbaum
  15. BQN
    https://www.aplwiki.com/wiki/BQN
  16. Co-dfns
    https://www.aplwiki.com/wiki/Co-dfns
  17. Array model
    https://www.aplwiki.com/wi­ki/Array_model#Based_arra­y_theory
  18. Fonts for BQN
    https://mlochbaum.github.i­o/BQN/fonts.html
  19. Leading axis theory
    https://www.aplwiki.com/wi­ki/Leading_axis_theory
  20. A based system for general arrays
    https://dl.acm.org/doi/ab­s/10.1145/586656.586663
  21. APL – A Glimpse of Heaven (2006)
    https://news.ycombinator.com/i­tem?id=19325361
  22. APL and J
    https://crypto.stanford.e­du/~blynn/c/apl.html
  23. ivy (dokumentace)
    https://pkg.go.dev/robpike­.io/ivy#section-readme
  24. ivy na GitHubu
    https://github.com/robpike/ivy/
  25. Ivy na APL wiki
    https://aplwiki.com/wiki/Ivy
  26. Implementing a bignum calculator (slajdy)
    https://talks.godoc.org/git­hub.com/robpike/ivy/talks/i­vy.slide#1
  27. Implementing a bignum calculator – Rob Pike – golang-syd November 2014
    https://www.youtube.com/wat­ch?v=PXoG0WX0r_E
  28. Rob Pike na Wikipedii
    https://en.wikipedia.org/wi­ki/Rob_Pike
  29. Rob Pike na cat-v
    http://genius.cat-v.org/rob-pike/
  30. Jazyky umožňující operace s poli aneb rozsáhlý svět „array programmingu“
    https://www.root.cz/clanky/jazyky-umoznujici-operace-s-poli-aneb-rozsahly-svet-bdquo-array-programmingu-ldquo/
  31. Programovací technika nazvaná tacit programming
    https://www.root.cz/clanky/pro­gramovaci-technika-nazvana-tacit-programming/
  32. Oslava 55 let od vzniku první implementace jazyka APL
    https://www.root.cz/clanky/oslava-55-let-od-vzniku-prvni-implementace-programovaciho-jazyka-apl/
  33. NuVoc
    https://code.jsoftware.com/wiki/NuVoc
  34. J (programming language) [Wikipedia]
    https://en.wikipedia.org/wi­ki/J_%28programming_langu­age%29
  35. J – Absolutely Essential Terms
    https://code.jsoftware.com/wi­ki/Vocabulary/AET
  36. J – Atoms and Arrays
    https://code.jsoftware.com/wi­ki/Vocabulary/Nouns#Atom
  37. Why J
    https://www.jsoftware.com/hel­p/primer/why_j.htm
  38. What is an Array?
    https://vector.org.uk/what-is-an-array/
  39. Comments
    http://www.gavilan.edu/csis/lan­guages/comments.html
  40. Vector (Wolfram MathWorld)
    https://mathworld.wolfram­.com/Vector.html
  41. n-Tuple (Wolfram MathWorld)
    https://mathworld.wolfram.com/n-Tuple.html
  42. n-Vector (Wolfram MathWorld)
    https://mathworld.wolfram.com/n-Vector.html
  43. Matrix (Wolfram MathWorld)
    https://mathworld.wolfram­.com/Matrix.html
  44. Array (Wolfram MathWorld)
    https://mathworld.wolfram­.com/Array.html
  45. ND Arrays (Tensors) in different languages
    https://www.youtube.com/wat­ch?v=WbpbEilgQBc
  46. Extending APL to Infinity\
    https://www.jsoftware.com/pa­pers/eem/infinity.htm
  47. Vector Library (R7RS-compatible)
    https://srfi.schemers.org/srfi-133/srfi-133.html
  48. Vectors (pro Gauche)
    https://practical-scheme.net/gauche/man/gauche-refe/Vectors.html
  49. Kawa: Compiling Scheme to Java
    https://www.mit.edu/afs.new/sip­b/project/kawa/doc/kawa-tour.html
  50. Kawa in Languages shootout
    http://per.bothner.com/blog/2010/Kawa-in-shootout/
  51. Kawa 2.0 Supports Scheme R7RS
    https://developers.slashdot­.org/story/14/12/13/2259225/ka­wa-20-supports-scheme-r7rs/
  52. Kawa — fast scripting on the Java platform
    https://lwn.net/Articles/623349/
  53. Incanter is a Clojure-based, R-like platform for statistical computing and graphics.
    http://incanter.org/
  54. Evolution of incanter (Gource Visualization)
    https://www.youtube.com/wat­ch?v=TVfL5nPELr4
  55. Questions tagged [incanter] (na Stack Overflow)
    https://stackoverflow.com/qu­estions/tagged/incanter?sor­t=active
  56. Data Sorcery with Clojure
    https://data-sorcery.org/contents/
  57. Back to the Future: Lisp as a Base for a Statistical Computing System
    https://rd.springer.com/chap­ter/10.1007/978–3–7908–2084–3_2
  58. Incanter Cheat Sheet
    http://incanter.org/docs/incanter-cheat-sheet.pdf
  59. Back to the Future: Lisp as a Base for a Statistical Computing System (celá verze článku)
    https://www.researchgate.net/pu­blication/227019917_Back_to_the_Fu­ture_Lisp_as_a_Base_for_a_Sta­tistical_Computing_System
  60. BQN: finally, an APL for your flying saucer
    https://mlochbaum.github.io/BQN/
  61. Is BQN stable?
    https://mlochbaum.github.i­o/BQN/commentary/stability­.html
  62. Specification: BQN system-provided values
    https://mlochbaum.github.i­o/BQN/spec/system.html
  63. Tutorial: BQN expressions
    https://mlochbaum.github.i­o/BQN/tutorial/expression­.html
  64. BQN primitives
    https://mlochbaum.github.i­o/BQN/doc/primitive.html
  65. Function trains
    https://mlochbaum.github.i­o/BQN/doc/train.html
  66. BQN community links
    https://mlochbaum.github.i­o/BQN/community/index.html
  67. BQN UV
    https://observablehq.com/@lsh/bqn-uv
  68. APL Wiki
    https://aplwiki.com/wiki/
  69. The Array Cast
    https://www.arraycast.com/e­pisodes/episode-03-what-is-an-array
  70. EnthusiastiCon 2019 – An Introduction to APL
    https://www.youtube.com/wat­ch?v=UltnvW83_CQ
  71. Dyalog
    https://www.dyalog.com/
  72. Try APL!
    https://tryapl.org/
  73. Lisp-Stat Information
    http://homepage.cs.uiowa.e­du/~luke/xls/xlsinfo/
  74. Sample Plots in Incanter
    https://github.com/incanter/in­canter/wiki/Sample-Plots-in-Incanter#line
  75. vectorz-clj
    https://github.com/mikera/vectorz-clj
  76. vectorz – Examples
    https://github.com/mikera/vectorz-clj/wiki/Examples
  77. Basic Vector and Matrix Operations in Julia: Quick Reference and Examples
    https://queirozf.com/entries/basic-vector-and-matrix-operations-in-julia-quick-reference-and-examples
  78. Vectors and matrices in Julia
    https://fncbook.github.io/v1­.0/linsys/demos/matrices-julia.html
  79. Array vs Matrix in R Programming
    https://www.geeksforgeeks.org/array-vs-matrix-in-r-programming/
  80. Concurrency (computer science)
    https://en.wikipedia.org/wi­ki/Category:Concurrency_%28com­puter_science%29
  81. Koprogram
    https://cs.wikipedia.org/wi­ki/Koprogram
  82. Coroutine
    https://en.wikipedia.org/wi­ki/Coroutine
  83. Coroutines in C
    http://www.chiark.greenen­d.org.uk/~sgtatham/corouti­nes.html
  84. S-expression (Wikipedia)
    https://en.wikipedia.org/wiki/S-expression
  85. S-Expressions (Rosetta Code)
    http://rosettacode.org/wiki/S-Expressions
  86. Introducing Julia/Metaprogramming
    https://en.wikibooks.org/wi­ki/Introducing_Julia/Meta­programming
  87. Tutorial for the Common Lisp Loop Macro
    http://www.ai.sri.com/pkarp/loop.html
  88. Clojure Macro Tutorial (Part I, Getting the Compiler to Write Your Code For You)
    http://www.learningclojure­.com/2010/09/clojure-macro-tutorial-part-i-getting.html
  89. Clojure Macro Tutorial (Part II: The Compiler Strikes Back)
    http://www.learningclojure­.com/2010/09/clojure-macro-tutorial-part-ii-compiler.html
  90. Clojure Macro Tutorial (Part III: Syntax Quote)
    http://www.learningclojure­.com/2010/09/clojure-macro-tutorial-part-ii-syntax.html
  91. Clojure Macros and Metaprogramming
    http://clojure-doc.org/articles/language/macros.html
  92. Fatvat – Exploring functional programming: Clojure Macros
    http://www.fatvat.co.uk/2009/02/clo­jure-macros.html
  93. CS 2101 Parallel Computing with Julia
    https://www.coursehero.com/fi­le/11508091/CS-2101-Parallel-Computing-with-Julia/
  94. Julia By Example
    https://samuelcolvin.github­.io/JuliaByExample/
  95. Array Programming
    https://en.wikipedia.org/wi­ki/Array_programming
  96. Discovering Array Languages
    http://archive.vector.org­.uk/art10008110
  97. no stinking loops – Kalothi
    http://www.nsl.com/
  98. Vector (obsahuje odkazy na články, knihy a blogy o programovacích jazycích APL, J a K)
    http://www.vector.org.uk/
  99. APL Interpreters
    http://www.vector.org.uk/?a­rea=interpreters
  100. APL_(programming_language
    http://en.wikipedia.org/wi­ki/APL_(programming_langu­age
  101. APL FAQ
    http://www.faqs.org/faqs/apl-faq/
  102. APL FAQ (nejnovější verze)
    http://home.earthlink.net/~swsir­lin/apl.faq.html
  103. A+
    http://www.aplusdev.org/
  104. APLX
    http://www.microapl.co.uk/
  105. FreeAPL
    http://www.pyr.fi/apl/index.htm
  106. Learning J (Roger Stokes)
    http://www.jsoftware.com/hel­p/learning/contents.htm
  107. J: a modern, high-level, general-purpose, high-performance programming language
    http://www.jsoftware.com/
  108. K, Kdb: an APL derivative for Solaris, Linux, Windows
    http://www.kx.com
  109. openAPL (GPL)
    http://sourceforge.net/pro­jects/openapl
  110. Parrot APL (GPL)
    http://www.parrotcode.org/
  111. Learning J (Roger Stokes)
    http://www.jsoftware.com/hel­p/learning/contents.htm
  112. Rosetta Code
    http://rosettacode.org/wiki/Main_Page
  113. Why APL
    http://www.acm.org/sigapl/whyapl.htm
  114. Introducing Julia/Functions
    https://en.wikibooks.org/wi­ki/Introducing_Julia/Functi­ons
  115. Functions (Julia documentation)
    https://docs.julialang.or­g/en/v1/manual/functions/
  116. Evaluate binomial coefficients
    http://rosettacode.org/wi­ki/Evaluate_binomial_coef­ficients
  117. Ackermann function
    http://rosettacode.org/wi­ki/Ackermann_function
  118. Julia (front page)
    http://julialang.org/
  119. Julia – dokumentace
    http://docs.julialang.org/
  120. Julia – repositář na GitHubu
    https://github.com/JuliaLang/julia
  121. Julia (programming language)
    https://en.wikipedia.org/wi­ki/Julia_%28programming_lan­guage%29
  122. IJulia
    https://github.com/JuliaLan­g/IJulia.jl
  123. Introducing Julia
    https://en.wikibooks.org/wi­ki/Introducing_Julia
  124. Julia: the REPL
    https://en.wikibooks.org/wi­ki/Introducing_Julia/The_REPL
  125. Month of Julia
    https://github.com/DataWo­okie/MonthOfJulia
  126. Learn X in Y minutes (where X=Julia)
    https://learnxinyminutes.com/doc­s/julia/
  127. New Julia language seeks to be the C for scientists
    http://www.infoworld.com/ar­ticle/2616709/application-development/new-julia-language-seeks-to-be-the-c-for-scientists.html
  128. Julia: A Fast Dynamic Language for Technical Computing
    http://karpinski.org/publi­cations/2012/julia-a-fast-dynamic-language
  129. The LLVM Compiler Infrastructure
    http://llvm.org/
  130. Julia: benchmarks
    http://julialang.org/benchmarks/
  131. Type system
    https://en.wikipedia.org/wi­ki/Type_system
  132. Half-precision floating-point format
    https://en.wikipedia.org/wiki/Half-precision_floating-point_format
  133. Dartmouth BASIC
    https://en.wikipedia.org/wi­ki/Dartmouth_BASIC
  134. BASIC 4th Edition
    http://www.bitsavers.org/pdf/dar­tmouth/BASIC_4th_Edition_Jan68­.pdf
  135. VECTRAN
    https://encyclopedia2.the­freedictionary.com/VECTRAN
  136. Comparison of programming languages (array)
    https://en.wikipedia.org/wi­ki/Comparison_of_programmin­g_languages_(array)
  137. BASIC at 50
    https://www.dartmouth.edu/ba­sicfifty/commands.html
  138. BBC Basic – arrays
    http://www.riscos.com/sup­port/developers/bbcbasic/par­t2/arrays.html
  139. Datová struktura
    https://cs.wikipedia.org/wi­ki/Datov%C3%A1_struktura
  140. SIMD instrukce využívané v moderních mikroprocesorech řady x86
    https://www.root.cz/clanky/simd-instrukce-vyuzivane-v-modernich-mikroprocesorech-rady-x86/
  141. SIMD instrukce v moderních mikroprocesorech řady x86 (2.část: SSE)
    https://www.root.cz/clanky/simd-instrukce-v-modernich-mikroprocesorech-rady-x86–2-cast-sse/
  142. SIMD instrukce v moderních mikroprocesorech řady x86 (3.část: SSE2)
    https://www.root.cz/clanky/simd-instrukce-v-modernich-mikroprocesorech-rady-x86–3-cast-sse2/
  143. Inductive type
    https://en.wikipedia.org/wi­ki/Inductive_type
  144. JuliaMono, a font for programming
    https://github.com/cormulli­on/juliamono
  145. It’s arrays all the way down
    https://xpqz.github.io/le­arnapl/array.html

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.