Vlastná cvičebnica podľa vzoru Vladimíra Gazdu

Author

Dávid Švihra
(s využitím ChatGPT)

Published

October 1, 2026

Globálne nastavenie Chunkov

V nižšie uvedenom Chunku je urobené základné globálne nastavenie Chunkov v celom Notebooku.

  • echo nastavuje, či chceme v Notebooku vypisovať jednotlivé kódy R
  • message je nastavený na FALSE, čo znamená, že sa budú potláčať pracovné výstupy z R, t.j. napríklad výsledok otvárania knižníc, a niektoré iné výstupy, ktoré ale pre celkový Notebook nemajú takmer žiaden význam a sú vhodné skôr pri ladení kódov.
  • warning nastavený na FALSE potláča varovania (nie všetky chyby)
Code
knitr::opts_chunk$set(
  echo = TRUE,
  message = FALSE,
  warning = FALSE
)

Úvod k základným operáciám v R

Tento notebook demonštruje základné operácie v jazyku R so:

  • skalárnymi číslami (t.j. 1 číslo),
  • textovými (znakovými) reťazcami,
  • logickými (boolovskými) hodnotami a premennými,
  • (numerickými) vektormi,
  • maticami.

Tam, kde je to užitočné, sú zahrnuté malé cvičenia.


Skaláre (jednočíselné hodnoty)

Numerické skaláre

Code
# Priradenie konštanty do premennej
a <- 7
b <- 3.5

# Arithmetic
sum_ab      <- a + b        # sucet
diff_ab     <- a - b        # rozdiel
prod_ab     <- a * b        # násobenie
quot_ab     <- a / b        # delenie
power_ab    <- a ^ b        # umocňovanie
mod_ab      <- a %% 3       # zbytok po delení tromi (tzv modulo)
int_div_ab  <- a %/% b      # celočíselné delenie


# Rounding
round_b   <- round(b)       # zaokruhlovanie smerom k najblizsiemu celemu cislu
ceil_b    <- ceiling(b)     # najblizsie vyssie cele cislo
floor_b   <- floor(b)       # najblizsie nizsie cele cislo

a; b
[1] 7
[1] 3.5
Code
sum_ab; diff_ab; prod_ab; quot_ab; power_ab; mod_ab; int_div_ab
[1] 10.5
[1] 3.5
[1] 24.5
[1] 2
[1] 907.4927
[1] 1
[1] 2
Code
round_b; ceil_b; floor_b
[1] 4
[1] 4
[1] 3

Poznámky

  • ^ operátor umocňovania.
  • %% je modulo, teda zbytok po delení,
  • round(x, digits = 0) zaokrúhľovanie na určitý počet desatinných miest (digits=). ak digits = 0, potom ide o celočíselné zaokrúhľovanie

🎮 Vlastný príklad – herné meny. Nasledujúce hodnoty sú vymyslené na tréning aritmetiky.

Code
herne_kredity <- 4750
cena_vybavy <- 2850
zostatok_kreditov <- herne_kredity - cena_vybavy
bonus_percent <- 12.5
kredity_po_bonuse <- zostatok_kreditov * (1 + bonus_percent / 100)
round(kredity_po_bonuse, 2)
[1] 2137.5

Malé cvičenie

🎯 Quest 01 – CS2 ekonomika. Tím vyhral 15 kôl, za každé získal 3250 herných kreditov. Na výstroj minul 7200 kreditov. Zistite zostávajúci rozpočet a priemerný rozpočet na 5 hráčov.

Code
vyhrate_kola <- 15
odmena_za_kolo <- 3250
naklady_na_vystroj <- 7200
pocet_hracov <- 5
rozpocet_timu <- vyhrate_kola * odmena_za_kolo - naklady_na_vystroj
rozpocet_na_hraca <- rozpocet_timu / pocet_hracov
rozpocet_timu; rozpocet_na_hraca
[1] 41550
[1] 8310

Text

Vytváranie textovými premennými a práca s nimi

Code
first <- "Vladimir"                       # definovanie obsahu textovej premennej first
last  <- "Gazda"                          # definovanie obsahu text. premennej last
full  <- paste(first, last)               # spojenie dvoch text. premennych do jednej (s medzerou)
full_nospace <- paste0(first, last)       # spojenie bez medzery
csv_line <- paste("apple", "banana", "pear", sep = ",")  # spojenie textov s oddelovacom ,
first; last; full; full_nospace; csv_line   # bodkočiarka tu nahradzuje odskok na novy riadok 
[1] "Vladimir"
[1] "Gazda"
[1] "Vladimir Gazda"
[1] "VladimirGazda"
[1] "apple,banana,pear"

🎮 Vlastný príklad – menovka hráča.

Code
prezdivka <- "PixelHunter"
tim <- "NIGHT RAIDERS"
mapa <- "Inferno"
popis_hraca <- paste(prezdivka, "hrá za", tim, "na mape", mapa)
popis_hraca
[1] "PixelHunter hrá za NIGHT RAIDERS na mape Inferno"
Code
paste0("#", prezdivka, "_MVP")
[1] "#PixelHunter_MVP"

Dĺžka textového reťazca, podreťazec

Code
x <- "R is great!"
nchar(x)                 # počet znakov  v retazci "R is great!"
[1] 11
Code
substr(x, 1, 5)          # podreťazec od 1. do 5. znaku
[1] "R is "

Tip: Knižnica stringr mnohé zaujímavé možnosti práce s textami, ale implicitné knižnice R pokrývajú väčšinu bežných potrieb páce s textami.


Logické (boolovské) hodnoty a premenné

Code
nchar(prezdivka)          # počet znakov v prezývke
[1] 11
Code
substr(prezdivka, 1, 5)  # prvých päť znakov prezývky
[1] "Pixel"

Základy

Code
p <- TRUE
q <- FALSE
!p                 # NOT
[1] FALSE
Code
p & q              # AND
[1] FALSE
Code
p | q              # OR
[1] TRUE
Code
xor(p, q)          # exclusive OR - platí len jedno z p,alebo q
[1] TRUE

Logický výsledok porovnávania

Code
3 < 5
[1] TRUE
Code
7 >= 7
[1] TRUE
Code
"cat" == "cat"
[1] TRUE
Code
"cat" != "dog"   # vykricnik je tu v zmysle negacie. Napr.:   !=, !>, !<, !TRUE
[1] TRUE
Code
!TRUE
[1] FALSE

🎮 Vlastný príklad – postup do play-off.

Code
vyhry <- 7
minimalne_vyhry <- 5
aktivny_hrac <- TRUE
postup <- (vyhry >= minimalne_vyhry) & aktivny_hrac
postup
[1] TRUE

Zložitejšie logické operácie

Code
x <- 10
x > 5 & x < 20      # a sucasne - logicky prienik (sucin)
[1] TRUE
Code
x < 0 | x > 100     # alebo - logicke zjednotenie (sucet)
[1] FALSE
Code
                    # pri zlozitejsich vztahoch pouzivajte zatvorky ()

Zlučovanie viacerých log. premenných do vektora

Code
vals <- c(TRUE, FALSE, TRUE, TRUE)   # definicia vektora s logickymi hodnotami

Numerické vektory

Generovanie vektorov

Code
v1 <- c(2, 4, 6, 8)
v2 <- 1:5                  # postupnost 1,2,3,4,5
v3 <- seq(from = 0, to = 1, by = 0.25)  # postupnost s krokom 0.25
v4 <- rep(3, times = 5)    # 3,3,3,3,3  # 5 clenna postupnost trojak
v5 <- runif(5)             # generovanie rovnomerne rozdelenych premennych v intervale [0,1]
v6 <- rnorm(5)             # generovanie normalne rozdelenych premennych
v1; v2; v3; v4; v5
[1] 2 4 6 8
[1] 1 2 3 4 5
[1] 0.00 0.25 0.50 0.75 1.00
[1] 3 3 3 3 3
[1] 0.3088054 0.5386144 0.2207791 0.4518826 0.5229187

🎮 Vlastný príklad – eliminácie v zápasoch.

Code
eliminacie <- c(18, 24, 15, 29, 21, 26)
mena_map <- c("Mirage", "Inferno", "Nuke", "Ancient", "Anubis", "Dust2")
names(eliminacie) <- mena_map
eliminacie
 Mirage Inferno    Nuke Ancient  Anubis   Dust2 
     18      24      15      29      21      26 

Aritmetické operácie s vektormi

Code
v <- c(1, 2, 3, 4)
v + 10           # kazdy prvok vektora zvacsime o 10
[1] 11 12 13 14
Code
v * 2            # kazdy prvok vektora prenasobime 2
[1] 2 4 6 8
Code
(v + 1) / 2
[1] 1.0 1.5 2.0 2.5
Code
exp(v)           # exponencialna funkcia z kazdeho prvku vektora
[1]  2.718282  7.389056 20.085537 54.598150
Code
sum(c(1,2,3) * c(1,1,1))     # správny skalárny súčin = 6
[1] 6
Code
crossprod(c(1,2,3),c(1,1,1))    # skalarny sucin - vysledok je matica 1x1
     [,1]
[1,]    6
Code
c(1,2,3)*c(1,1,1)               # Hadamardov sucin (sucin zodpovedajucich prvkov vektora)
[1] 1 2 3

Matematické operácie s 2 vektormi rovnakého rozmeru

Code
length(c(1,2,3,4,5))
[1] 5
Code
length(v5)            #vektor v5 je definovany vyssie
[1] 5
Code
c(1,2,3,4,5) + v5     # pozor, oba vektory musia mat rovnaky rozmer
[1] 1.308805 2.538614 3.220779 4.451883 5.522919

Indexovanie a výber niektorych prvkov vektora

Code
x <- c(5, 12, 3, 18, 7, 0, 21)
x[1]           # indexovanie - novy jedno-prvkovy vektor - prvy prvok vektora x
[1] 5
Code
x[2:4]         # novy vektor s druhym az stvrtym prvkom vektora x
[1] 12  3 18
Code
x[-1]          # novy vektor - vsetky prvky vektora x okrem prvého
[1] 12  3 18  7  0 21
Code
x[x > 10]      # novy vektor definovany prvkami x vacsimi ako 10
[1] 12 18 21
Code
which(x > 10)  # ktore prvky zodpovedaju podmienke vacsieho ako 10?
[1] 2 4 7

Práca s chýbajúcimi hodnotami

Code
y <- c(1, NA, 3, NA, 5)
is.na(y)
[1] FALSE  TRUE FALSE  TRUE FALSE
Code
mean(y)                 # NA
[1] NA
Code
mean(y, na.rm = TRUE)   # remove NAs
[1] 3

Základné štatistiky a usporiadanie prvkov vektora podľa veľkosti

Code
z <- c(10, 3, 5, 8, 2)
mean(z)                 # priemerna hodnota
[1] 5.6
Code
sd(z)                  # standardna odchylka
[1] 3.361547
Code
max(z)                  # maximalna hodnota
[1] 10
Code
summary(z)              # rychly prehlad zakladnych statistik o vektore
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
    2.0     3.0     5.0     5.6     8.0    10.0 
Code
sort(z)                 # rastuce usporiadanie 
[1]  2  3  5  8 10
Code
sort(z, decreasing = TRUE)  # klesajuce
[1] 10  8  5  3  2

🎮 Vlastný príklad – hráčske štatistiky.

Code
mean(eliminacie)
[1] 22.16667
Code
sd(eliminacie)
[1] 5.192944
Code
max(eliminacie)
[1] 29
Code
sort(eliminacie, decreasing = TRUE)
Ancient   Dust2 Inferno  Anubis  Mirage    Nuke 
     29      26      24      21      18      15 

Malé cvičenie

🎯 Quest 02 – Body v zápasoch. Vektor w obsahuje body získané počas 20 herných kôl. Vypočítajte súčet bodov z kôl s párnym poradovým číslom (pozor: filtrujeme indexy, nie párne hodnoty).

Code
w <- c(120, 180, 150, 220, 140, 260, 170, 190, 210, 160,
       240, 180, 130, 270, 200, 250, 190, 230, 210, 300)
parne_kola <- seq(2, length(w), by = 2)
sum(w[parne_kola])
[1] 2240
Code
mean(w); max(w)
[1] 200
[1] 300

Matice

Vytvorenie matíc

Code
m <- matrix(1:12, nrow = 3, ncol = 4)            # hodnoty sú zadavane po stlpcoch
m_byrow <- matrix(1:12, nrow = 3, byrow = TRUE)  # hodnoty su zadavane po riadkoch
m; m_byrow
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    4
[2,]    5    6    7    8
[3,]    9   10   11   12

Rozmery matice

Code
dim(m)                   # (rows, cols)
[1] 3 4
Code
m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

Adresovanie prvkov matice

Code
m[1, 2]      # riadok 1, stlpec 2
[1] 4
Code
m[ , 3]      # tretí stĺpec: R štandardne vráti vektor
[1] 7 8 9
Code
m[2, ]       # druhý riadok: R štandardne vráti vektor
[1]  2  5  8 11
Code
m[1:2, 2:3]  # podmatica tvorena riadkami 1, 2 a stlpcami 2, 3
     [,1] [,2]
[1,]    4    7
[2,]    5    8

Maticové operácie

Code
A <- matrix(c(1,2,3,4), nrow = 2)
B <- matrix(c(5,6,7,8), nrow = 2)

A + B        # scitanie matic
     [,1] [,2]
[1,]    6   10
[2,]    8   12
Code
A * B        # Hadamard product - nasobenie po zodpovedajucich prvkoch
     [,1] [,2]
[1,]    5   21
[2,]   12   32
Code
A %*% B      # nasobenie matic
     [,1] [,2]
[1,]   23   31
[2,]   34   46
Code
t(A)         # transpozicia matice A - vymena riadkov a stlpcov
     [,1] [,2]
[1,]    1    2
[2,]    3    4
Code
det(A)       # determinant matice
[1] -2
Code
solve(A)     # inverzia matice (ak je matica regularna - teda inverzia sa da spocitat)
     [,1] [,2]
[1,]   -2  1.5
[2,]    1 -0.5

Zlučovanie vektorov do matíc

Code
C <- cbind(1:3, 4:6)   #  - po stlpcoch 
D <- rbind(1:3, 4:6)   #  - po riadkoch 
C; D
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6

Vypočítanie zvolenej štatistiky po riadkoch (stĺpcoch) matice

Code
M <- matrix(1:9, nrow = 3)
M
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
Code
apply(M, 1, sum)   # suma po riadkoch
[1] 12 15 18
Code
apply(M, 2, mean)  # priemery po stĺpcoch
[1] 2 5 8

🎮 Vlastný príklad – skóre tímu. V riadkoch sú hráči, v stĺpcoch mapy; každé číslo je počet eliminácií.

Code
skore <- matrix(c(21, 19, 25,
                  17, 22, 20,
                  24, 23, 18,
                  15, 18, 21), nrow = 4, byrow = TRUE)
rownames(skore) <- paste0("Hrac_", 1:4)
colnames(skore) <- c("Mirage", "Inferno", "Nuke")
skore
       Mirage Inferno Nuke
Hrac_1     21      19   25
Hrac_2     17      22   20
Hrac_3     24      23   18
Hrac_4     15      18   21
Code
rowSums(skore)        # výsledky hráčov naprieč mapami
Hrac_1 Hrac_2 Hrac_3 Hrac_4 
    65     59     65     54 
Code
colSums(skore)        # výsledky na jednotlivých mapách
 Mirage Inferno    Nuke 
     77      82      84 
Code
apply(skore, 1, mean) # priemer podľa hráča
  Hrac_1   Hrac_2   Hrac_3   Hrac_4 
21.66667 19.66667 21.66667 18.00000 
Code
apply(skore, 2, mean) # priemer podľa mapy
 Mirage Inferno    Nuke 
  19.25   20.50   21.00 

Malé cvičenie

🎯 Quest 03 – Päť hráčov, päť máp. Zostavte maticu 5 × 5, v ktorej riadky predstavujú hráčov a stĺpce päť máp. Vypočítajte súčet eliminácií na jednotlivých mapách a maticový súčin (M^T M).

Code
M2 <- matrix(c(18, 22, 17, 25, 20,
               21, 19, 23, 16, 24,
               15, 20, 18, 22, 19,
               26, 24, 21, 23, 27,
               17, 16, 20, 19, 22),
             nrow = 5, byrow = TRUE)
rownames(M2) <- paste0("Hrac_", 1:5)
colnames(M2) <- c("Mirage", "Inferno", "Nuke", "Ancient", "Anubis")
M2
       Mirage Inferno Nuke Ancient Anubis
Hrac_1     18      22   17      25     20
Hrac_2     21      19   23      16     24
Hrac_3     15      20   18      22     19
Hrac_4     26      24   21      23     27
Hrac_5     17      16   20      19     22
Code
colSums(M2)            # eliminácie podľa mapy
 Mirage Inferno    Nuke Ancient  Anubis 
     97     101      99     105     112 
Code
rowSums(M2)            # eliminácie podľa hráča
Hrac_1 Hrac_2 Hrac_3 Hrac_4 Hrac_5 
   102    103     94    121     94 
Code
t(M2) %*% M2           # súčin transponovanej a pôvodnej matice
        Mirage Inferno Nuke Ancient Anubis
Mirage    1955    1991 1945    2037   2225
Inferno   1991    2077 1995    2150   2276
Nuke      1945    1995 1983    2052   2241
Ancient   2037    2150 2052    2255   2341
Anubis    2225    2276 2241    2341   2550

Vlastné čísla a vlastné vektory matíc

Čo znamenajú vlastné čísla a vlastné vektory?

Nech \(\mathbf A\) je štvorcová matica. Vlastné číslo (eigenvalue) \(\lambda\) a príslušný vlastný vektor (eigenvector) \(\mathbf v \ne \mathbf 0\) spĺňajú vzťah

\[ \mathbf A \mathbf v = \lambda \mathbf v. \]

Násobenie maticou \(\mathbf A\) teda pôsobí na vlastný vektor rovnako ako násobenie číslom \(\lambda\). Výsledok reprezentuje vektor rovnakého smeru, ale rozličných veľkostí:

  • ak \(\lambda > 0\), orientácia vektora sa zachová;
  • ak \(\lambda < 0\), orientácia sa obráti;
  • ak \(\lambda = 0\), výsledkom je nulový vektor.

Dĺžka sa násobí hodnotou \(|\lambda|\). Napríklad pri \(\lambda = 3\) sa vektor predĺži trojnásobne, pri \(\lambda = 0.5\) sa skráti na polovicu. Tento geometrický opis sa týka reálnych vlastných čísel a vektorov.

Jednoduchý príklad: matica 2 × 2

Použijeme symetrickú maticu, teda maticu, pre ktorú platí \(A^T = A\):1

\[ \mathbf A = \begin{pmatrix} 2 & 1 \\ 1 & 2 \end{pmatrix}. \]

Vlastné čísla nájdeme podľa nasledovného postupu:

\[\begin{eqnarray} \mathbf A \mathbf h & = & \lambda \mathbf h \\ \mathbf A \mathbf h - \lambda \mathbf h & = & \mathbf 0 \\ (\mathbf A - \lambda \mathbf I)\mathbf h & = & \mathbf 0, \end{eqnarray} \]

kde \(\mathbf I\) je jednotková matica.

Netriviálne (nenulové) riešenie tejto sústavy existuje vtedy, keď

\[ \det(\mathbf A-\lambda \mathbf I)=0. \]

V našom prípade

\[ \mathbf A-\lambda \mathbf I = \begin{pmatrix} 2-\lambda & 1 \\ 1 & 2-\lambda \end{pmatrix}, \]

a preto

\[ \det(\mathbf A-\lambda \mathbf I) = \begin{vmatrix} 2-\lambda & 1 \\ 1 & 2-\lambda \end{vmatrix} = (2-\lambda)^2-1. \]

Dostávame charakteristickú rovnicu

\[ (2-\lambda)^2-1 = \lambda^2-4\lambda+3 = (\lambda-3)(\lambda-1) = 0. \]

Vlastné čísla sú koreňmi (riešeniami) kvadratickej rovnice a teda

\[ \lambda_1=3, \qquad \lambda_2=1. \]

Výpočet vlastného vektora pre \(\lambda_1=3\)

Vlastný vektor vypočítame zo vzťahu

\[ (\mathbf A-\lambda_1\mathbf I)\mathbf h_1=\mathbf 0. \]

Po dosadení \(\lambda_1=3\) dostávame

\[ \left[ \begin{pmatrix} 2 & 1\\ 1 & 2 \end{pmatrix} - 3 \begin{pmatrix} 1&0\\ 0&1 \end{pmatrix} \right] \begin{pmatrix} h_{11}\\ h_{21} \end{pmatrix} = \begin{pmatrix} 0\\ 0 \end{pmatrix}. \]

Teda

\[ \begin{pmatrix} -1&1\\ 1&-1 \end{pmatrix} \begin{pmatrix} h_{11}\\ h_{21} \end{pmatrix} = \begin{pmatrix} 0\\ 0 \end{pmatrix}. \]

Získame sústavu rovníc

\[ \begin{eqnarray} -h_{11}+h_{21} &=&0,\\ h_{11}-h_{21} &=&0, \end{eqnarray} \] pričom zavedieme ešte dodatočnú podmienku normalizácie vlastných vektorov2, teda

\[\sqrt{h_{11}^2 + h_{21}^2} = 1\]

Prvé dve rovnice vyjadrujú tú istú podmienku:

\[ h_{11}=h_{21}. \]

Teda z normalizačnej podmienky dostávame

\[\sqrt{h_{11}^2 + h_{21}^2} = 1 \Longleftrightarrow h_{11} = h_{21} = \pm \sqrt{\frac{1}{2}}\]

Môžeme preto napríklad zvoliť

\[ h_{11}=+\sqrt{\frac{1}{2}}, \]

a potom

\[ h_{21}=+\sqrt{\frac{1}{2}}. \]

Vlastný vektor zodpovedajúci vlastnému číslu \(\lambda_1=3\) môže byť teda

\[ \mathbf h_1= \begin{pmatrix} +\sqrt{\frac{1}{2}}\\ +\sqrt{\frac{1}{2}} \end{pmatrix}. \]

Každý nenulový násobok tohto vektora je však tiež vlastným vektorom. Napríklad

\[ \begin{pmatrix} +1\\ +1 \end{pmatrix} \]

predstavuje ten istý smer.

Výpočet vlastného vektora pre \(\lambda_2 = 1\)

Keďže platí

\[ \begin{aligned} \left[ \begin{pmatrix} 2 & 1 \\ 1 & 2 \end{pmatrix} - 1 \cdot \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} \right] \begin{pmatrix} h_{12} \\ h_{22} \end{pmatrix} &= \begin{pmatrix} 0 \\ 0 \end{pmatrix} \\[1em] \Longleftrightarrow \qquad \begin{pmatrix} 1 & 1 \\ 1 & 1 \end{pmatrix} \begin{pmatrix} h_{12} \\ h_{22} \end{pmatrix} &= \begin{pmatrix} 0 \\ 0 \end{pmatrix}. \end{aligned} \]

dostávame sústavu rovníc

\[ \begin{eqnarray} h_{12}+h_{22} &=&0,\\ h_{12}+h_{22} &=&0. \end{eqnarray} \]

Z toho vyplýva

\[ h_{22}=-h_{12}. \]

Ak zvolíme dodatočnú normalizačnú podmienku

\[\sqrt{h_{12}^2 + h_{22}^2} = 1,\] potom ak

\[ h_{12}=\sqrt{\frac{1}{2}}, \]

pre druhý prvok vektora bude platiť

\[ h_{22}=-\sqrt{\frac{1}{2}}. \]

Vlastný vektor zodpovedajúci vlastnému číslu \(\lambda_2=1\) teda môžeme zapísať ako

\[ \mathbf h_2= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix}. \]

Opäť platí, že ľubovoľný nenulový násobok tohto vektora je tiež vlastným vektorom.


Overenie pre prvý vlastný vektor

Pre prvý vlastný vektor platí

\[ \mathbf A\mathbf h_1 = \begin{pmatrix} 2&1\\ 1&2 \end{pmatrix} \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix} = 3 \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix} = \lambda_1 \mathbf h_1 \]

Teda

\[ \mathbf A\mathbf h_1=\lambda_1\mathbf h_1. \]

Podobne sa to dá ukázať aj pre druhé vlastné číslo \(\lambda_2\) a druhý vlastný vektor \(\mathbf h_2\).


Matice vlastných čísel a vlastných vektorov

Dostávame teda dvojice vlastných čísel a vlastných vektorov:

\[ \lambda_1=3, \qquad \mathbf h_1= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix}, \]

a

\[ \lambda_2=1, \qquad \mathbf h_2= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix}. \]

Keďže matica \(\mathbf A\) je symetrická, vlastné vektory zodpovedajúce rôznym vlastným číslam sú navzájom ortogonálne (navzájom kolmé a po dvojiciach ich skalárne súčiny sa rovnajú nule). Skutočne,

\[ \mathbf h_1^T\mathbf h_2 = \left( \sqrt{\frac{1}{2}},\sqrt{\frac{1}{2}} \right) \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix} = \frac{1}{2} - \frac{1}{2} = 0. \]


Výpočet pomocou R funkcie eigen()

Funkcia eigen() je súčasťou základného R; nepotrebujeme ďalšiu knižnicu. Argument symmetric = TRUE použijeme, keď vieme, že matica je symetrická. Pri všeobecnej matici môžeme napísať jednoducho eigen() a R symetriu skontroluje samo.

Code
# Vytvorenie matice z analytického príkladu
A_eig <- matrix(c(2, 1,
                  1, 2),
                nrow = 2, byrow = TRUE)

A_eig
     [,1] [,2]
[1,]    2    1
[2,]    1    2
Code
# Výpočet vlastných čísel a vlastných vektorov
eig_A <- eigen(A_eig, symmetric = TRUE) #vyuzitie funkcie eigen()
eig_A                                   # vysledok sa ulozil do listu, ktory sme nazvali eig_A
eigen() decomposition
$values
[1] 3 1

$vectors
          [,1]       [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068  0.7071068
Code
 #Dalej pristupime k rozbaleniu obsahu listu eig_A

lambda_A <- eig_A$values    # vektor vlastných čísel - ulozenie do lambda_A
V_A <- eig_A$vectors        # vlastné vektory v stĺpcoch ulozenie do V_A

lambda_A
[1] 3 1
Code
V_A
          [,1]       [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068  0.7071068

Výsledok eig_A je list. Znak $ vyberá jeho pomenovanú zložku:

Zápis v R Význam
eig_A$values Všetky vlastné čísla
eig_A$vectors Vlastné vektory uložené v stĺpcoch
eig_A$values[1] Prvé vlastné číslo
eig_A$vectors[, 1] Vlastný vektor prislúchajúci prvému vlastnému číslu

Pri reálnej symetrickej matici R vráti vlastné čísla zostupne; tu teda 3 a 1. Vlastné vektory majú jednotkovú dĺžku. Môžu sa preto líšiť od našich ručne zvolených vektorov mierkou alebo znamienkom. Vektory \(v\) aj \(-v\) sú rovnako správne: vlastný vektor nie je jednoznačný.

Ak potrebujeme iba vlastné čísla:

Code
eigen(A_eig, symmetric = TRUE, only.values = TRUE)$values
[1] 3 1

Overenie vzťahu Av = λv

V R použijeme na násobenie matice a vektora operátor %*%. Operátor * používame pri násobení vektora skalárom.

Code
lambda_1 <- lambda_A[1]
v_1 <- V_A[, 1]

lava_strana <- as.vector(A_eig %*% v_1)
prava_strana <- lambda_1 * v_1

cat("Ľavá strana je ", paste(lava_strana, collapse = ", "), 
    " a pravá strana je ", paste(prava_strana, collapse = ", "), "!", sep = "")
Ľavá strana je 2.12132034355964, 2.12132034355964 a pravá strana je 2.12132034355964, 2.12132034355964!

Geometrické znázornenie

Porovnáme dva vlastné vektory. Pri vlastnom vektore zostáva jeho obraz (transformácia) na tej istej priamke.

Code
local({
  povodne <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
  on.exit(par(povodne))

  priklady <- list(c(1, 1), c(1, -1))
  nazvy <- c("Vlastný vektor: lambda = 3",
             "Vlastný vektor: lambda = 1")

  for (j in seq_along(priklady)) {
    x_plot <- priklady[[j]]
    Ax_plot <- as.vector(A_eig %*% x_plot)
    plot(NA, xlim = c(-1.5, 3.5), ylim = c(-1.5, 3.5),
         asp = 1, xlab = "Prvá súradnica", ylab = "Druhá súradnica",
         main = nazvy[j], cex.main = 0.85)
    abline(h = 0, v = 0, col = "grey80")
    arrows(0, 0, Ax_plot[1], Ax_plot[2],
           col = "darkorange2", lwd = 4, length = 0.12)
    arrows(0, 0, x_plot[1], x_plot[2],
           col = "steelblue4", lwd = 2, lty = 2, length = 0.10)
    legend("topleft", legend = c("x", "Ax"),
           col = c("steelblue4", "darkorange2"),
           lty = c(2, 1), lwd = c(2, 4), bty = "n", cex = 0.8)
  }
})

Vektor x (modrý) a jeho obraz Ax (oranžový).

V prostrednom obrázku sa šípky prekrývajú, pretože \(Ax = x\). Cyklus for opakuje rovnaký postup oba vektory. Funkcia local() udržiava pomocné premenné grafu oddelene od ostatných výpočtov.

Matica 3 × 3 - príklad v R

Code
B_eig <- matrix(c(2, 1, 0,
                  1, 2, 0,
                  0, 0, 4), nrow = 3, byrow = TRUE)
eig_B <- eigen(B_eig, symmetric = TRUE)
eig_B$values                # 4, 3, 1
[1] 4 3 1
Code
eig_B$vectors
     [,1]      [,2]       [,3]
[1,]    0 0.7071068  0.7071068
[2,]    0 0.7071068 -0.7071068
[3,]    1 0.0000000  0.0000000
Code
# Súčty štvorcov prvkov jednotlivých stĺpcov sú 1.
colSums(eig_B$vectors^2)
[1] 1 1 1
Code
# Overenie všetkých troch vlastných párov.
max(abs(B_eig %*% eig_B$vectors -
        eig_B$vectors %*% diag(eig_B$values)))
[1] 5.551115e-16

Pre štvorcovú maticu platí: súčet vlastných čísel sa rovná stope matice (súčtu diagonálnych prvkov) a ich súčin sa rovná determinantu. Vlastné čísla pritom počítame aj s ich násobnosťami.

Code
c(sucet_vlastnych_cisel = sum(eig_B$values),
  stopa_matice = sum(diag(B_eig)))             # obe hodnoty sú 8
sucet_vlastnych_cisel          stopa_matice 
                    8                     8 
Code
c(sucin_vlastnych_cisel = prod(eig_B$values),
  determinant = det(B_eig))                   # obe hodnoty sú 12
sucin_vlastnych_cisel           determinant 
                   12                    12 

Malé cvičenie

🎯 FINAL BOSS – variančno-kovariančná matica herných štatistík.

Vymysleli sme osem zápasov jedného hráča CS2. Každý riadok predstavuje jeden zápas; stĺpce obsahujú eliminácie, asistencie a damage/10 (škálovaný damage pre prehľadnejšie hodnoty). Z herných dát zostavte variančno-kovariančnú maticu, vypočítajte jej vlastné čísla a vlastné vektory a overte výsledky. Ide o ilustračné údaje, nie o oficiálne herné dáta.

Code
# 1. Vlastné herné dáta: 8 zápasov × 3 ukazovatele
herne_data <- data.frame(
  eliminacie = c(12, 16, 21, 19, 27, 24, 30, 17),
  asistencie = c(3, 5, 4, 7, 8, 6, 9, 4),
  damage_10 = c(35, 42, 58, 53, 72, 65, 81, 46)
)
herne_data
  eliminacie asistencie damage_10
1         12          3        35
2         16          5        42
3         21          4        58
4         19          7        53
5         27          8        72
6         24          6        65
7         30          9        81
8         17          4        46
Code
# 2. Variančno-kovariančná matica zo vzorky zápasov
C <- cov(herne_data)
C
           eliminacie asistencie damage_10
eliminacie   35.92857   10.92857  93.42857
asistencie   10.92857    4.50000  28.28571
damage_10    93.42857   28.28571 244.28571
Code
# 3. Súčet podľa riadkov a stĺpcov (požiadavka vyučujúceho)
rowSums(C)
eliminacie asistencie  damage_10 
 140.28571   43.71429  366.00000 
Code
colSums(C)
eliminacie asistencie  damage_10 
 140.28571   43.71429  366.00000 
Code
apply(C, 1, sum)
eliminacie asistencie  damage_10 
 140.28571   43.71429  366.00000 
Code
apply(C, 2, sum)
eliminacie asistencie  damage_10 
 140.28571   43.71429  366.00000 
Code
# 4. Vlastné čísla a vlastné vektory
eig_C <- eigen(C, symmetric = TRUE)
eig_C$values
[1] 283.3407060   1.2111801   0.1623997
Code
eig_C$vectors
           [,1]        [,2]        [,3]
[1,] -0.3553793 -0.04698683  0.93354044
[2,] -0.1081106 -0.98996683 -0.09098232
[3,] -0.9284490  0.13325884 -0.34673399
Code
# 5. Overenie C %*% V = V %*% diag(lambda)
L <- diag(eig_C$values)
lava <- C %*% eig_C$vectors
prava <- eig_C$vectors %*% L
maximalna_odchylka <- max(abs(lava - prava))
maximalna_odchylka
[1] 1.705303e-13
Code
all.equal(lava, prava, tolerance = 1e-10)
[1] "Attributes: < Length mismatch: comparison on first 1 components >"
Code
# 6. Vlastné čísla kovariančnej matice by mali byť nezáporné
all(eig_C$values >= -1e-10)
[1] TRUE
Code
# 7. Podiel variability vysvetlený jednotlivými komponentmi
podiel_variability <- eig_C$values / sum(eig_C$values) * 100
round(podiel_variability, 2)
[1] 99.52  0.43  0.06

Čo sme si overili?

  • cov() vypočítala variančno-kovariančnú maticu z herných výsledkov.
  • rowSums(C) a colSums(C) sumarizujú riadky a stĺpce; apply() ponúka univerzálny spôsob výpočtu. Súčet kovariancií nie je priemerné skóre hráča.
  • eigen(C, symmetric = TRUE) vráti vlastné čísla a vlastné vektory symetrickej matice.
  • Výraz max(abs(lava - prava)) má byť veľmi blízky nule, čím numericky overujeme vzťah (Cv = v).
  • Záporné vlastné čísla by pri korektnej kovariančnej matici mohli byť len zanedbateľnou numerickou nepresnosťou.

Poznámka k zadaniu: Vzorový analytický výklad vlastných čísel a vektorov z predlohy som zachoval ako učebný základ. Vlastným riešením je herný príklad vypočítaný z dát (nie z postupnosti 1:16).

Footnotes

  1. Aj v budúcnosti budeme pracovať len s takýmito maticami – maticami, ktoré predstavujú variančno-kovariančné vzťahy medzi premennými – tzv. variančno-kovariančnými maticami (variance-covariance matrix).↩︎

  2. normalizované vektory majú veľkosť 1↩︎