Laboration 0: Del 2
Benjamin Kjellson
2016–03–21
Introduktion till matriser, vektorer, och ekvationssystem
I den här filen får ni en kort introduktion till hur man hanterar och räknar med matriser i R, vilket ni
kommer att ha nytta av i kursens laborationsuppgifter.
I kursen Statistisk analys har ni stött på datastrukturen data.frame, vilket är en sorts tabell där kolumnerna
kan vara av olika typer—heltal (integer) i en, decimaltal (numeric) i en annan, textsträngar (character)
i en tredje, och kanske faktorer (factor) i en fjärde. Matriser är lite annorlunda: i dem måste alla kolumner
och rader vara av samma typ, t.ex. numeric.
Definiera matriser
Ibland måste vi skapa en matris för hand, t.ex. när ni tvingas mata in en som är definierad i en bok eller en
labbinstruktion. Låt säga att ni ska definiera matrisen
(
)
1 2 3
A=
4 5 6
i R. Det kan ni göra på följande vis:
A <- matrix(c(1, 2, 3,
4, 5, 6),
nrow = 2,
ncol = 3,
byrow = TRUE)
A # visa matrisen
[1,]
[2,]
[,1] [,2] [,3]
1
2
3
4
5
6
Som första argument till funktionen matrix ger jag datan jag vill ha i matrisen; här skriver jag in vektorn
c(1, 2, 3, 4, 5, 6) (som jag också kan få genom att skriva 1:6) på ett sådant sätt att man enkelt ser
hur matrisen bör se ut. Jag säger att matrisen ska ha två rader med nrow och tre kolumner med ncol. Dock
kommer matrisen inte se ut som jag vill om jag inte också säger till funktionen matrix att data ska fylla ut
matrisen radvis (default är att fylla ut kolumnvis). Jämför med
matrix(1:6, nrow = 2, ncol = 3)
[1,]
[2,]
[,1] [,2] [,3]
1
3
5
2
4
6
Ibland vill man ha en matris fylld av t.ex. ettor. En sån kan man enkelt skapa utan att behöva ange varje
element var för sig. Iställer skriver man bara
1
ettor <- matrix(1, nrow = m, ncol = n)
om man vill ha en m × n-matris fylld med ettor, kallad ettor.
Vill man skapa en diagonalmatris kan man göra det med funktionen diag, som i följande exempel:
diag(1:3, nrow = 5, ncol = 3)
[1,]
[2,]
[3,]
[4,]
[5,]
[,1] [,2] [,3]
1
0
0
0
2
0
0
0
3
0
0
0
0
0
0
Vanligare är att man skapar en kvadratisk diagonalmatris, kanske med samma värde längs hela diagonalen.
Ett exempel är enhetsmatrisen:
diag(1, nrow = 3, ncol = 3)
[1,]
[2,]
[3,]
[,1] [,2] [,3]
1
0
0
0
1
0
0
0
1
Vektorer
Vi är vana vid att skapa vektorer genom att t.ex. skriva c(1, 2, 3) eller 1:3. När vi skriver ut en sådan
vektor ser det ut på följande vis:
1:3
[1] 1 2 3
Om vi vill kan vi göra om en sådan vektor specifikt till en radvektor eller en kolumnvektor, genom att
använda funktionen matrix. Vektorerna räknas då som matriser med en rad eller kolumn, respektive. En
radvektor kan skapas genom
matrix(1:3, nrow = 1)
[1,]
[,1] [,2] [,3]
1
2
3
och en kolumnvektor genom
matrix(1:3, ncol = 1)
[1,]
[2,]
[3,]
[,1]
1
2
3
2
Transponera matriser och vektorer
Vill man transponera en matris eller vektor i R så kan man använda funktionen t, som följande exempel
illustrerar:
A <- matrix(1:6, nrow = 3, ncol = 2, byrow = TRUE) # 3 rader, 2 kolumner
t(A) # 2 rader, 3 kolumner
[1,]
[2,]
[,1] [,2] [,3]
1
3
5
2
4
6
Detsamma gäller vektorer:
radvektor <- matrix(1:3, nrow = 1)
t(radvektor)
[1,]
[2,]
[3,]
[,1]
1
2
3
och en kolumnvektor genom
kolumnvektor <- matrix(1:3, ncol = 1)
t(kolumnvektor)
[1,]
[,1] [,2] [,3]
1
2
3
För vektorer definierade på vanligt vis, genom t.ex. funktionen c eller :, så ser vi att transponaten av dem
blir radvektorer:
t(1:5)
[1,]
[,1] [,2] [,3] [,4] [,5]
1
2
3
4
5
Transponerar vi dem två gånger, vilket bör ge oss det vi startade med, får vi alltså en kolumnvektor:
t(t(1:5))
[1,]
[2,]
[3,]
[4,]
[5,]
[,1]
1
2
3
4
5
3
Hämta element ur matriser och vektorer (slicing)
Vektorer
Ibland vill man hämta ut ett eller flera element ur en vektor eller matris. Låt säga att vi har vektorn
v <- 11:15
v # visa vektorn
[1] 11 12 13 14 15
Säg att vi nu vill hämta ut det första elementet i vektorn. Det kan vi göra genom att skriva
v[1]
[1] 11
Index för vektorer, matriser osv. börjar på 1 i R, så v[1] är det första elementet i v, v[2], är det andra,
osv. Ett sätt att få det sista elementet är att skriva v[length(v)].
Vill vi hämta alla element förutom det första i v så ger vi ett negativt index:
v[-1]
[1] 12 13 14 15
Detsamma gäller om vi vill hämta t.ex. alla förutom det första och det andra:
v[-c(1, 2)]
[1] 13 14 15
Vektorn -c(1, 2) är densamma som c(-1, -2) eftersom minustecknet multipliceras in som -1 i vektorn.
Akta er dock för att skriva
v[-1:2]
eftersom vektorn som skapas av -1:2 inte är densamma som c(-1, -2), som man kanske kan tro, utan är
istället c(-1, 0, 1, 2), och att försöka köra v[-1:2] kommer att resultera i ett fel (Error).
Matriser
Vi kan hämta element ut matriser på liknande sätt. Har vi en matris A och skriver A[i, j] så kommer
elementet på rad i och kolumn j att hämtas. Skriver vi A[c(i, k), j] så hämtas elementen på rad i och
rad k, i kolumn j, som en vektor. Skriver vi A[c(i, k), c(j, m)] så får vi stället en 2 × 2-matris, och det
går givetvis att generalisera detta till indexvektorer (som t.ex. c(i, k) ovan) av större längd än 2.
Ibland vill man hämta ut en hel rad eller kolumn ur en matris som en vektor. Det kan man göra genom att
lämna ett tomt index, som följande exempel illustrerar
4
A <- matrix(c(1, 2, 3,
4, 5, 6),
nrow = 2,
ncol = 3,
byrow = TRUE)
A # visa matrisen
[1,]
[2,]
[,1] [,2] [,3]
1
2
3
4
5
6
Hämta ut rad 2 som en vektor:
A[2, ] # notera det tomma indexet för kolumner
[1] 4 5 6
Hämta ut kolumn 3 som en vektor:
A[, 3] # notera det tomma indexet för rader
[1] 3 6
Matrismultiplikation
För att multiplicera en m×n-matris A med en n×k matris B så använder vi matrismultiplikationsoperatorn
%*% i R, som följande exempel demonstrerar:
A <- matrix(1:6, nrow = 3, ncol = 2, byrow = TRUE)
B <- matrix(0:3, nrow = 2, ncol = 2, byrow = TRUE)
A %*% B
[1,]
[2,]
[3,]
[,1] [,2]
4
7
8
15
12
23
Att multiplicera med vektorer fungerar på samma vis. Vill vi multiplicera med en vektor på höger sida
skriver vi t.ex.
v <- 1:2
A %*% v
[1,]
[2,]
[3,]
[,1]
5
11
17
Vi hade fått samma resultat om vi hade definierat v <- matrix(1:2, ncol = 1). Multiplikation på vänster
sida fungerar likadant:
5
v <- matrix(1:3, nrow = 1) # radvektor
v %*% A
[1,]
[,1] [,2]
22
28
Här hade vi alltså fått samma resultat om vi hade skrivit v <- 1:3.
Ekvationssystem
Vill vi lösa ekvationssystemet Ax = y, där A är en m × m-matris, x är en m × 1-vektor (kolumnvektor) och
y är en m × 1-vektor, så använder vi funktionen solve i R, som följande exempel visar:
A
y
x
x
<- matrix(1:4, nrow = 2, ncol = 2, byrow = TRUE)
<- c(-1, 3)
<- solve(A, y)
# visa lösningen
[1]
5 -3
Prova att lösa systemet för hand och se om du får samma lösning x.
Egenvärden och egenvektorer
Om A är en kvadratisk matris så kallas (det möjligen komplexa) talet λ för ett egenvärde till A om det finns
en vektor v av passande längd sådan att Av = λv. Vektorn v är egenvektorn som svarar mot egenvärdet λ.
Detta kanske ni minns från linjär algebra. Vi kan enkelt räkna ut egenvärden och motsvarande egenvektorer
i R, genom att använda funktionen eigen. Följande exempel demonstrerar:
A <- matrix(c(1, 2, 0, 3), nrow = 2, ncol = 2, byrow = TRUE)
egen_lista <- eigen(A) # Funktionen returnerar en lista
egen_varden <- egen_lista$values
egen_vektorer <- egen_lista$vectors
Det första egenvärdet är alltså
egen_varden[1]
[1] 3
och motsvarande egenvektor hittas i den första kolumnen av matrisen egen_vektorer:
egenvektor1 <- egen_vektorer[, 1]
egenvektor1
[1] 0.7071068 0.7071068
6
Egenvektorerna som funktionen eigen ger är normaliserade på sådant sätt att deras längd är lika med 1.
Som ni kanske minns från linjär algebra så är en egenvektorer inte unika. Om v1 är en egenvektor som
motsvarar egenvärdet λ1 till matrisen A, så är också cv1 en egenvektor motsvarande samma egenvärde, för
c ̸= 0. Som vi såg ovan var elementen i egenvektorn egenvektor1 identiska. Kanske det vore snyggare om
vi multiplicerade/delade egenvektor1 med ett tal som gör att båda elementen tar värdet 1 istället:
egenvektor1 <- egenvektor1 / egenvektor1[1]
egenvektor1
[1] 1 1
Ett annat alternativ vore att låta summan av elementen i egenvektor1 vara t.ex. lika med 1. Detta kan vi
åstadkomma på följande sätt:
egenvektor1 <- egenvektor1 / sum(egenvektor1)
egenvektor1
[1] 0.5 0.5
Skriva matriser i LaTeX
Följande exempel visar hur man skriver en matris i LaTeX. Du kan alltså kopiera “koden” nedan till ett R
Markdown-dokument och sedan knitta.
$$
\mathbf{P}
=
\begin{pmatrix}
0
& 0.25 & 0.75 \\
0.16
& 0.01 & 0.83 \\
0.24
& 0.47 & 0.29
\end{pmatrix}
$$
Detta kommer synas som

0
0.25
P = 0.16 0.01
0.24 0.47

0.75
0.83
0.29
Vill man ha matriser med hakparenteser, dvs [ ], istället, så kan man skriva bmatrix istället för pmatrix.
Övningsuppgifter
Uppgift 1
Med kod, definiera matrisen
(
A=
1 2
−1 1
7
)
genom att använda funktionen matrix och matrisen
(
)
1 0
D=
0 −1
genom att använda funktionen diag, och bilda sedan matrisen C = A′ D, där A′ är transponatet av A.
Dubbelkolla resultatet genom att utföra uträkningen för hand.
Uppgift 2
Lös följande ekvationssystem genom att definiera en matris A och en vektor y, och använda funktionen solve
för att hitta lösningen (vektorn) x = (x1 , x2 , x3 )′ :


2x1 + x2 + 3x3 = 1
2x1 + 6x2 + 8x3 = 3


6x1 + 8x2 + 18x3 = 5
Jämför med lösningen du får när du löser systemet för hand.
Uppgift 3
Om A är en kvadratisk matris, så kan vi definiera potenser av A rekursivt genom A1 = A och An+1 = AAn
för n > 1. Vi skulle också kunna definiera A0 = I, där I är enhetsmatrisen.
Skapa nu en funktion
mpower <- function(A, n) {
...
}
som tar som argument en (kvadratisk) matris A och ett heltal n större än (eller lika med—ditt val) 0, och
returnerar A upphöjt till n i överensstämmelse med definitionen ovan. OBS! Din funktion behöver dock inte
vara rekursiv, som i definitionen som gavs ovan. Den kan lika gärna vara iterativ, i vilket fall du kanske
behöver använda dig av någon slags loop. Prova gärna att skriva både en rekursiv och en iterativ funktion.
8