Definició i notacions

Creem una matriu en R amb la funció matrix(). Hem de donar els elements de la matrius en ordre en una sola seqüència, per defecte per columnes. Si ho volem donar per files, hem d’especificar byrow = TRUE. Cal especificar com a mínim una de les dues, o el nombre de files o el de columnes.

A <- matrix(c(2, 0, 3, 4, 7, 5,  5, 4, 9, 10), ncol = 5)
A
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    3    7    5    9
[2,]    0    4    5    4   10
B <- matrix(data=c(2, 3, 7, 5, 9, 0, 4, 5, 4, 10), byrow = TRUE, nrow = 2)
B
     [,1] [,2] [,3] [,4] [,5]
[1,]    2    3    7    5    9
[2,]    0    4    5    4   10

Podem accedir a l’element \(a_{i,j}\) de la matriu utilitzant la notació A[i,j]

Però recorda que R diferencia entre A i a! La matriu l’hem definit amb A majúscula.

A[2,3] # serà l'element de la fila 2 i columna 3
[1] 5
A[,3]  # si no diem quina fila, les torna totes
[1] 7 5
A[1,]  # si no diem quina columna les torna totes
[1] 2 3 7 5 9

En la notació més habitual el que hem demanat s’escriuria la columna \(a_{\cdot 3}\) i la fila \(a_{1\cdot}\) (posem un puntet per indicar tota la fila o tota la columna).

Atenció: quan demanem una fila o una columna, R ens torna sempre un vector fila, horitzontal.

Més exemples

Si volem definir una matriu \(A = a_{ij}\) segons una fórmula donada, per exemple, \(a_{ij}=i-j\) podem començar per crear una matriu de la dimensió desitjada plena de zeros, i després omplir-la mitjançant dos bucles aniuats:

A <- matrix(0, nrow = 5, ncol = 7)
for (i in 1:nrow(A)) 
  for (j in 1:ncol(A)) 
    A[i,j] <- i-j
A
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    0   -1   -2   -3   -4   -5   -6
[2,]    1    0   -1   -2   -3   -4   -5
[3,]    2    1    0   -1   -2   -3   -4
[4,]    3    2    1    0   -1   -2   -3
[5,]    4    3    2    1    0   -1   -2

Un altre exemple, si volem omplir de 1 el triangle superior d’una matriu quadrada:

A2 <- matrix(0, nrow = 7, ncol = 7)
for (i in 1:nrow(A2)) 
  for (j in i:ncol(A2)) # fixa't que la j comença des de i
    A2[i,j] <- 1
A2
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    1    1    1    1    1    1
[2,]    0    1    1    1    1    1    1
[3,]    0    0    1    1    1    1    1
[4,]    0    0    0    1    1    1    1
[5,]    0    0    0    0    1    1    1
[6,]    0    0    0    0    0    1    1
[7,]    0    0    0    0    0    0    1

Igualtat de matrius

Si demanem si dues matrius són iguals, R ens torna la comparació terme a terme.

A <- matrix(c(2, 0, 3, 4, 7, 5,  5, 4, 9, 10), nrow = 2)
B <- matrix(c(2, 0, 3, 4, 7, 5,  5, 4, 9, 10), ncol = 5)
A == B
     [,1] [,2] [,3] [,4] [,5]
[1,] TRUE TRUE TRUE TRUE TRUE
[2,] TRUE TRUE TRUE TRUE TRUE
B[1,3]=13 # canviem l'element (1,3)
A == B
     [,1] [,2]  [,3] [,4] [,5]
[1,] TRUE TRUE FALSE TRUE TRUE
[2,] TRUE TRUE  TRUE TRUE TRUE
all(A == A) # per veure si tots són TRUE
[1] TRUE
all(A == B)
[1] FALSE

Suma, diferència, producte per escalars de matrius

Aquí treballem amb matrius igual que amb nombres.

A <- matrix(c(1, 2, 3, 1, 1, 0), byrow = TRUE, nrow = 2)
B <- matrix(c(1, 0, 5, 1, 1, 6), byrow = TRUE, nrow = 2)
A + B
     [,1] [,2] [,3]
[1,]    2    2    8
[2,]    2    2    6
A - 2 * B
     [,1] [,2] [,3]
[1,]   -1    2   -7
[2,]   -1   -1  -12
3 * A
     [,1] [,2] [,3]
[1,]    3    6    9
[2,]    3    3    0
-B
     [,1] [,2] [,3]
[1,]   -1    0   -5
[2,]   -1   -1   -6

El producte de matrius. No és commutatiu!

Si fem servir el producte de nombres *, R fa el producte terme a terme. El producte matricial es fa amb %*%.

A <- matrix(c(1, 2, 3, 1, 1, 0, -2, 1), byrow = TRUE, nrow = 2) # matriu 2 x 4
B <- matrix(c(1, 0, 5, 1, 1, 6, -1, 0), byrow = TRUE, nrow = 4) # matriu 4 x 2
A %*% B  # serà matriu 2 x 2
     [,1] [,2]
[1,]   13   20
[2,]   -2  -12
B %*% A  # serà matriu 4 x 4
     [,1] [,2] [,3] [,4]
[1,]    1    2    3    1
[2,]    6   10   13    6
[3,]    7    2   -9    7
[4,]   -1   -2   -3   -1

En el cas de matrius quadrades sempre podem canviar l’ordre del producte, de vegades el resultat serà el mateix, de vegades no.

A <- matrix(c(1, 2, 3, 1, 1, 0, -2, 1, 0), byrow = TRUE, nrow = 3) # matriu 3 x 3
B <- matrix(c(-2, 1, 0, 5, 1, 1, 6, -1, 0), byrow = TRUE, nrow = 3) # matriu 3 x 3
A %*% B
     [,1] [,2] [,3]
[1,]   26    0    2
[2,]    3    2    1
[3,]    9   -1    1
B %*% A
     [,1] [,2] [,3]
[1,]   -1   -3   -6
[2,]    4   12   15
[3,]    5   11   18
C <- diag(c(1,2,3)) # matriu diagonal amb 1, 2, 3 a la diagonal
D <- diag(c(2,-1, 0))
D %*% C == C %*% D
     [,1] [,2] [,3]
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE

La matriu identitat

Amb la funció diag que hem fet servir suara, podem construir la matriu identitat de la dimensió que ens interessi

I5 <- diag(1, nrow = 5)
I5
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    1    0
[5,]    0    0    0    0    1

Com has vist, no cal que donem 1 cinc vegades, R recicla el que donem si li cal.

Potència de matrius quadrades

A <- matrix(c(1, 0, 3, 0.5), nrow=2)
A %*% A
     [,1] [,2]
[1,]    1 4.50
[2,]    0 0.25
A %*% A %*% A %*% A
     [,1]   [,2]
[1,]    1 5.6250
[2,]    0 0.0625

La transposada

Fem servir la funció t() per transposar matrius.

A <- matrix(c(1, 2, 3, 1, 1, 0, -2, 1, 0), byrow = TRUE, nrow = 3) # matriu 3 x 3
B <- matrix(c(-2, 1, 0, 5, 1, 1, 6, -1, 0), byrow = TRUE, nrow = 3) # matriu 3 x 3
C <- matrix(1:12, nrow = 3)  # matriu 3 x 4 omplerta amb els nombres del 1 al 12 per columnes
C
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
t(C)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
t(A %*% B) == t(B) %*% t(A)
     [,1] [,2] [,3]
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE

Matrius simètriques

A <- matrix(c(1, 2, 3, 1, 1, 0, -2, 1, 0), byrow = TRUE, nrow = 3) # matriu 3 x 3
TA <- A %*% t(A)
TA == t(TA)  # és una matriu simètrica?
     [,1] [,2] [,3]
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE

Traça d’una matriu quadrada

No hi ha una funció específica en R per calcular la traça, no cal. La funció diag() que abans hem fet servir per construir una matriu diagonal a partir dels nombres de la diagonal, també serveix per extreure la diagonal d’una matriu.

Aqui construirem una matriu amb nombres aleatoris de \([0,1]\) i en farem la traça:

A <- matrix(runif(9), byrow = TRUE, nrow = 3)
diag(A)
[1] 0.1940975 0.2299436 0.7947368
sum(diag(A)) # serà la traça
[1] 1.218778

Exercicis

Ara et toca a tu.

1.- Comprova la propietat associativa del producte de matrius amb tres matrius de dimensions 2 per 3, 3 per 4 i 4 per 2.

2.- Producte de matriu i vector. Si entrem un vector en R fent servir la funció c(), R d’entrada l’interpreta con un vector fila (de fet com un vector sense dimensions). Però quan el fem servir en un producte matricial, R el “promou” a les dimensions adequades. Comprova-ho amb alguns exemples: fes una matriu de 3 per 4, pre-multiplica-la per v <- c(1,0,-1) i comprova si ha interpretat v com a un vector fila de 1 per 3. Post-multiplica-la per w <- c(1,0,-1,-2) i comprova si ha interpretat correctament w com a vector columna de 4 per 1.

Podeu trobar un resum de com treballar amb matrius en R al web (https://www.statmethods.net/advstats/matrix.html), amb més funcions de les que hem vist aquí.

Només per friquis del R

(o gent interesada en aprendre a programar)

Si volguéssim fer potències d’exponent més alt, podem definir

potencia.matriu <- function(matriu, exponent) {
  if(exponent==1) 
    return(matriu)
  else
    return(matriu %*% potencia.matriu(matriu, exponent-1))}

A <- matrix(c(1, 0, 3, 0.5), nrow=2)
potencia.matriu(A, 100)
     [,1]         [,2]
[1,]    1 6.000000e+00
[2,]    0 7.888609e-31

Hem definit la funció potencia.matriu(A,n) com a una funció recursiva, dient que \(A^1\) és \(A\) i \(A^n\) és \(A\cdot A^{n-1}\).

Cadenes de Markov, matrius de transició

Matrius de transferència de vots

Posem que en una enquesta s’ha demanat a l’entrevistat què va votar a les darreres eleccions i què vol votar ara. Disposarem les dades en una matriu \(T=(t_{ij})\) on l’element \(i, j\), fila \(i\) i columna \(j\) és el percentatge de votants del partit \(i\) que ara han decidit votar al partit \(j\). Posem que tenim aquestes dades:

Això vol dir que dels votants anteriors al partit A, el 20% es passen al B, el 10% al C, però el 50% resten fidels al partit A.

Si tenim les dades en un full Excel Transf-Vots.xlxs, podem llegir-les en R:

library(readxl)
t.data <- read_excel("Transf-Vots.xlsx", col_names = TRUE)
New names:
* `` -> ...1
T <- as.matrix(t.data[,-1]) # suprimim la primera columna que son els noms
T
      P-A  P-B  P-C  P-D  P-E
[1,] 0.50 0.20 0.10 0.10 0.10
[2,] 0.20 0.60 0.05 0.05 0.10
[3,] 0.05 0.15 0.40 0.20 0.20
[4,] 0.05 0.05 0.05 0.80 0.05
[5,] 0.15 0.20 0.20 0.15 0.30

Per suposat, també podem entrar les dades “a mà”, en columnes:

T <- matrix(c(0.5, 0.2, 0.05, 0.05, 0.15, 0.2, 0.6, 0.15, 0.05, 0.2, 0.1, 0.05, 0.4, 0.05, 0.2, 0.1, 0.05, 0.2, 0.8, 0.15, 0.1, 0.1, 0.2, 0.05, 0.3), nrow = 5)
T
     [,1] [,2] [,3] [,4] [,5]
[1,] 0.50 0.20 0.10 0.10 0.10
[2,] 0.20 0.60 0.05 0.05 0.10
[3,] 0.05 0.15 0.40 0.20 0.20
[4,] 0.05 0.05 0.05 0.80 0.05
[5,] 0.15 0.20 0.20 0.15 0.30

En qualsevol cas tenim la mateixa matriu que en direm la “matriu de transferència de vots”.

Aquesta matriu ens permet passar de la distribució de vots de les anteriors eleccions als resultats previstos per a la següent. Com ho hem de fer?

Posem que a les anteriors la distribució dels vots va ser A: 0.35, B: 0.25, C:0.20, D: 0.15, E: 0.05. Això ho podem representar en un vector:

V <- c(0.35, 0.25, 0.20, 0.15, 0.05)
V
[1] 0.35 0.25 0.20 0.15 0.05

Lavors, per calcular quina seria la distribució de vots per les properes elecions, quin càlcul matricial hem de fer? Creus que hauria de ser \(T\cdot V\)? O bé \(V\cdot T\)? Raona la teva resposta.

Cadena de Markov pels usos de transport públic

Aquest tipus de model reben el nom de Cadenes de Markov. Ara veiem un altre exemple: els viatges a la ciutat de Barcelona es poden realitzar en cotxe privat (P), transport públic (M), bicicleta (B) o a peu (P). Posem que actualment les proporcions siguin, respectivament, 0.18, 0.38, 0.12, 0.32.

Podeu consultar dades reals del 2018 a [https://www.idescat.cat/serveis/biblioteca/docs/bib/pec/paae2018/a07322018.pdf]

Segons els estudis de l’autoritat metropolitana del transport, la gent que va ara en cotxe seguirà usant-lo en un 60% dels casos però canviarà a M, B, P en proporcions 25%, 5%, 10% respectivament. Els que van en transport públic passaran a C, B, P en proporcions 10%, 12%, 5%. Els de la bicicleta canviaran a C, M, P amb proporcions 2%, 5%, 5%. I els que van a peu canviaran a C, M, B en proporcions 2%, 10%, 5%.

Calcula la matriu de transició T i les proporcions previstes segons auqestes dades per l’any següent.

       [,1]   [,2]   [,3]   [,4]
[1,] 0.1644 0.3528 0.1582 0.3246

Resposta: el vector de les proporcions actuals és 0.18, 0.38, 0.12, 0.32, i el resultant d’aplicar la matriu de transició serà 0.1644, 0.3528, 0.1582, 0.3246.