1.3. Matrisr¨ akning
I kursens f¨orra del beskrevs hur man l¨oser ett line¨art ekvationssystem i matrisform: Ax = b. Vi kommer nu att studera problemet i detalj, men f¨orst skall vi behandla multiplikation av en matris och en vektor, samt multiplikation av tv˚a matriser. I princip finns dessa operationer f¨ardigt implementerade i MATLAB, men f¨or att vi b¨attre skall l¨ara oss att handskas med matriser, s˚a l¨onar det sig att studera uppst¨allningen av matrisproblem och operationer med matriser mera i detalj.
Elementen i en matris kan konstrueras p˚a olika s¨att. Det finns t.ex. speciella matriser, som kan genereras utg˚aende fr˚an ett matematiskt uttryck f¨or matriselementen. Ett exempel ¨ar Hilberts matris:
aij = 1
i + j − 1, som kan genereras med programmet
A = zeros(n,n);
for i = 1:n for j = 1:n
A(i,j) = 1/(i+j-1);
end end
d¨ar matrisen f¨orst blivit nollst¨alld med zeros(n,n).
Detta program utnyttjar inte det faktum, att Hilberts matris ¨ar symmetrisk: aij = aji ∀(i, j). Om vi beaktar detta, r¨acker det med att ber¨akna elementen p˚a diagonalen och (t.ex.) elementen ovanf¨or diagonalen, resten f¨oljer av symmetrivillkoret:
A = zeros(n,n);
for i = 1:n for j = i:n
A(i,j) = 1/(i+j-1);
A(j,i) = A(i,j);
end end
Det finns faktiskt en inbyggd funktion hilb(n) i MATLAB, som alstrar en n–radig Hilbert-matris, som ocks˚a kan anv¨andas ( type hilb visar en listning av programmet).
Ett annat exempel ¨ar en matris, som uppbyggs av binomialkoefficienterna (Pascals triangel)
n k
=
( n!
k!(n−k)! om 0 ≤ k ≤ n 0 i annat fall
I detta fall kan vi konstruera matriselementen t.ex. genom formeln pij =
i − 1 j − 1
.
Att r¨akna ut binomialkoefficienterna direkt via deras definition ¨ar arbetsdrygt. Ist¨allet l¨onar det sig att anv¨anda rekursionslikheten
pij = pi−1,j−1 + pi−1,j.
Ett program, som utnyttjar denna relation ser vi nedan (jfr pascal i MATLAB):
function p=binomial(n) p = zeros(n,n)
p(:,1) = ones(n,1);
for i=2:n for j=2:i
p(i,j) = p(i-1,j-1) + p(i-1,j);
end end
Vandermondes matris har studerats tidigare i samband med interpolation:
V = 2 66 4
1 x1 x21 x31 1 x2 x22 x32 1 x3 x23 x33 1 x4 x24 x24
3 77 5
Den kan enklast konstrueras kolumnvis p˚a f¨oljande s¨att (jfr ¨aven vander i MATLAB):
n = length(x);
V(:,1) = ones(n,1);
for j = 2:n
V(:,j) = x.*V(:,j-1);
end
I en cirkulant–matris skiftas raderna cykliskt:
C = 2 66 4
a1 a2 a3 a4 a4 a1 a2 a3 a3 a4 a1 a2 a2 a3 a4 a1
3 77 5
En s˚adan matris kan vi t.ex. generera ur definitionen
cij = a[(n−i+j) mod n]+1,
eller utnyttja det faktum att c(i, :) f˚as genom att skifta c(i − 1, :) ett steg mot h¨oger. Vi kan l¨att skriva tv˚a Matlab–program som utnyttjar dessa metoder:
function C=circ1(a)
% Invariabel:
% a : en radvektor
% Utvariabel:
% C : en cirkulant, d¨ar C(1,:) = a n = length(a);
C = zeros(n,n);
for i = 1:n for j = 1:n
C(i,j) = a (rem(n-i+j,n)+1);
end end
function C=circ2(a)
% Invariabel:
% a : en radvektor
% Utvariabel:
% C : en cirkulant, d¨ar C(1,:) = a n = length(a);
C = zeros(n,n);
C(1,:) = a;
for i = 2:n
C(i,:) = [C(i-1,n) C(i-1,1:n-1)];
end
Det andra alternativet ¨ar det kortaste, och samtidigt ocks˚a det snabbaste programmet.
M˚anga av de matriser, som man st¨oter p˚a i fysiken inneh˚aller matriselement, som ¨ar lika med 0. F¨orekommer de rikligt, brukar man tala om glesa (eng.: sparse) matriser. En triangul¨ar matris har element som ¨ar olika noll endast p˚a diagonalen, och under (eller ovanf¨or) densamma (jfr tril, och triu i MATLAB).
En undre triangul¨ar matris ser t.ex. ut s˚a h¨ar:
L = 2 66 4
a 0 0 0
b c 0 0
d e f 0
g h p q
3 77 5
Tridiagonala matriser har element, som ¨ar olika noll endast p˚a diagonalen, och de tv˚a omgivande subdia- gonalerna:
T = 2 66 4
a b 0 0
c d e 0
0 f g h
0 0 h p
3 77 5
Detta slag av matriser kallas ocks˚a bandmatriser, eftersom de element, som ¨ar olika 0, ing˚ar i band, som omger diagonalen. Ett specialfall av en bandmatris ¨ar en diagonal matris, som kan konstrueras fr˚an en vektor med hj¨alp av MATLAB–kommandot diag.
Om t.ex. d = [1 2 3 4], s˚a ger kommandot D = diag(d) upphov till matrisen
D = 2 66 4
1 0 0 0
0 2 0 0
0 0 3 0
0 0 0 4
3 77 5
Vi skall nu studera matrisoperationer, och b¨orja med multiplikation av en matris och en vektor. Antag att vi vill ber¨akna y = Ax, d¨ar A ¨ar en m × n–matris, och x en vektor i ett n–dimensionellt euklidiskt rum. Det normala s¨attet att utf¨ora denna operation ¨ar att ber¨akna elementen yi, i = 1 : m
yi = Xn
j=1
aijxj
som skal¨arprodukter av matrisens rader och vektorn x.
Produkten kan ber¨aknas med MATLAB–programmet
[m,n] = size(A);
y = zeros(m,1);
for i = 1:m for j = 1:n
y(i) = y(i) + A(i,j)*x(j);
end end
Naturligtvis f˚ar man samma resultat med kommandot y = A*x, s˚a vi beh¨over allts˚a inte ber¨akna produkten av en matris och en vektor som en dubbelslinga. Men det ¨ar ¨and˚a l¨arorikt att studera programmet. Vi kan t.ex. vektorisera den inre slingan, som bildar produkten av den i:te raden i A (A(i,:)) och vektorn x:
function y = matvekr(A,x)
% Invariabler:
% A: mxn-matris
% x: kolumnvektor med n element
% Utvariabel:
% y: A*x (radorienterad metod) [m,n] = size(A); y = zeros(m,1);
for i = 1:m
y(i) = A(i,:)*x;
end
Denna metod att ber¨akna produkten ¨ar radorienterad. Vi kan ocks˚a anv¨anda en kolumnorienterad metod.
Principen framg˚ar av f¨oljande exempel:
2
41 2
3 4
5 6
3 5
7 8
= 2
47 · 1 + 8 · 2 7 · 3 + 8 · 4 7 · 5 + 8 · 6
3 5 =
2
47 · 1 7 · 3 7 · 5
3 5 +
2
48 · 2 8 · 4 8 · 6
3
5 = 7 2 41
3 5
3
5 + 8 2 42
4 6
3 5 ,
dvs resultatvektorn ¨ar en line¨arkombination av kolumnerna i A, d¨ar koefficienterna ¨ar xj. Detta leder till f¨oljande program:
function y = matveks(A,x)
% Invariabler:
% A: mxn-matris
% x: vektor med n element
% Utvariabel:
% y: A*x (kolumnorienterad metod) [m,n] = size(A);
y = zeros(m,1);
for j = 1:n
y = y + A(:,j)*x(j);
end
Denna funktion ¨ar ekvivalent med det ursprungliga programmet, d˚a b˚ada slingorna blivit omkastade.
Den inre slingan beskriver nu en operation av formen vektor ← vektor · skal¨ar + vektor (y=A(:,j)*x(j)+y), som kallas f¨or saxpy (”Scalar Alpha X Plus Y”) operationen. Denna ben¨amning kommer fr˚an namnet p˚a en subrutin, som ing˚ar i BLAS (Basic Linear Algebra Subroutines) biblioteket. I vektorform kan saxpy operationen i matveks uttryckas
2 66 4
y(1) y(2)...
y(m) 3 77 5 =
2 66 4
A(1, j) A(2, j)
...
A(m, j) 3 77
5 x(j) + 2 66 4
y(1) y(2)...
y(m) 3 77 5
Trots att vartdera programmet anv¨ander 2mn flyttalsoperationer, s˚a ¨ar kolumnversionen ofta snabbare ¨an radversionen, p˚a grund av att matriser lagras i minnet kolumnvis, dvs kolumnerna f¨oljer efter varandra.
Vi skall nu behandla multiplikation av tv˚a matriser. Produkten av en m×p–matris A och en p×n–matris B ¨ar en m × n–matris C = AB, vars element kan ber¨aknas ur formeln
cij = Xp
k=1
aikbkj,
d¨ar i och j uppfyller villkoren 1 ≤ i ≤ m och 1 ≤ j ≤ n.
Detta inneb¨ar, att varje element i C ¨ar skal¨arprodukten av en rad i A och en kolumn i B. Matrisen C kan s˚alunda ber¨aknas med MATLAB–programmet
C = zeros(m,n);
for j = 1:n for i = 1:m
for k = 1:p
C(i,j) = C(i,j) + A(i,k)*B(k,j);
end end end
Alternativt kan samma ber¨akning utf¨oras med kommandot C = A*B (som i allm¨anhet ¨ar den snabbaste metoden). Men vi kan ocks˚a utnyttja vektorisering vid utf¨orandet.
Om vi vektoriserar den innersta slingan i programmet, som ber¨aknar skal¨arprodukten av den i:te raden i A och den j:te kolumnen i B (allts˚a k ers¨atts med ’:’), s˚a f˚ar vi funktionen
function C = matmulp(A,B)
% Invariabler:
% A: mxp matris.
% B: pxn matris.
% Utvariabel:
% C: A*B (via skal¨arprodukt) [m,p] = size(A);
[p,n] = size(B);
C = zeros(m,n);
for j = 1:n
% Ber¨aknar j:te kolumnen i C.
for i=1:m
C(i,j) = A(i,:)*B(:,j);
end end
Men vi vet ocks˚a, att den j:te kolumnen i C ¨ar lika med matrisen A g˚anger den j:te kolumnen i matrisen B. Om vi utnyttjar den kolumnvisa matris–vektoroperationen (i ers¨atts med ’:’), s˚a f˚ar vi funktionen
function C = matmuls(A,B)
% Invariabler:
% A: mxp matris.
% B: pxn matris.
% Utvariabel:
% C: A*B (saxpy metoden) [m,p] = size(A);
[p,n] = size(B);
C = zeros(m,n);
for j = 1:n
% Ber¨aknar j:te kolumnen i C.
for k = 1:p
C(:,j) = C(:,j) + A(:,k)*B(k,j);
end end
Denna version av matrismultiplikationen anv¨ander saxpy metoden.
Om den innersta slingan ers¨atts av en enda matrisvektorprodukt f˚ar programmet f¨oljande form:
function C = matmulv(A,B)
% Invariabler:
% A: mxp matris.
% B: pxn matris.
% Utvariabel:
% C: A*B (matrisvektorprodukt) [m,p] = size(A);
[p,n] = size(B);
C = zeros(m,n);
for j = 1:n
% Ber¨aknar j:te kolumnen i C.
C(:,j) = A*B(:,j);
end
Man kan ytterligare tolka matrismultiplikationen som en summa av yttre produkter. Yttre produkten av en kolumnvektor u med m element och radvektor v med n element definieras genom
uv0 = 2 66 4
u1 u2 ...
um 3 77 5
v1 v2 · · · vn
= 2 66 4
u1v1 u1v2 · · · u1vn u2v1 u2v2 · · · u2vn
... ... . . . ...
umv1 umv2 · · · umvn 3 77 5
Detta kan uppfattas som en vanlig multiplikation av en m × 1 matris och en 1 × n–matris, t.ex.
2 41
2 3
3
5 4 5 6 = 2
4 4 5 6
8 10 12
12 15 18
3 5
Matrismultiplikationsproblemet kan d˚a formuleras som
C = AB = [A(:, 1)|A(:, 2)| · · · |A(:, p)]
2 66 4
B(1, :) B(2, :)
...
B(p, :) 3 77 5 =
Xp k=1
A(:, k)B(k, :).
Ett exempel p˚a en s˚adan framst¨allning av matrisprodukten ¨ar 2
41 2
3 4
5 6
3 5
7 8
9 10
= 2
41 · 7 + 2 · 9 1 · 8 + 2 · 10 3 · 7 + 4 · 9 3 · 8 + 4 · 10 5 · 7 + 6 · 9 5 · 8 + 6 · 10
3 5
= 2
41 · 7 1 · 8 3 · 7 3 · 8 5 · 7 5 · 8
3 5 +
2
42 · 9 2 · 10 4 · 9 4 · 10 6 · 9 6 · 10
3 5 =
2 41
3 5
3
5 [7 8] + 2 42
4 6
3
5 [9 10]
Vi kan allts˚a ocks˚a konstruera en annan version av matrismultiplikationsprogrammet, som utnyttjar yttre produkten:
function C = matmulo(A,B)
% Invariabler:
% A: mxp matris.
% B: pxn matris.
% Utvariabel:
% C: A*B (som yttre produkt) [m,p] = size(A);
[p,n] = size(B);
C = zeros(m,n);
for k = 1:p
% Bildar yttre produkten.
C = C + A(:,k)*B(k,:);
end
Denna metod ¨ar dock den l˚angsammaste av de fyra metoderna f¨or att multiplicera matriser, vilket man visa genom att skriva ett testprogram, som j¨amf¨or ber¨akningstiderna.
1.4. Linj¨ ara ekvationssystem
L¨osningen av ekvationssystem ¨ar ett av de vanligaste problemen man st¨oter p˚a i fysiken. Ofta g¨aller det ekvationer med m˚anga obekanta, s˚a det ¨ar inte konstigt att de f¨orsta datorerna just anv¨andes f¨or l¨osning av ekvationssystem. Symboliskt kan ett ekvationssystem framst¨allas i matrisform:
Ax = b,
d¨ar A ¨ar en kvadratisk (koefficientmatris) av ordningen n, b en given kolumnvektor med n rader och x en kolumnvektor med n obekanta.
Man kan l¨osa ekvationssystem p˚a m˚anga olika s¨att, t. ex. med Cramers regel 1, d¨ar varje obekant ¨ar kvoten av tv˚a determinanter. Denna metod ¨ar praktisk bara f¨or ett litet antal obekanta. Om vi t.ex.
skulle till¨ampa metoden p˚a ett system med 30 ekvationer, s˚a skulle vi vara tvungna att ber¨akna 31 st.
30-radiga determinanter. Om man skulle uppl¨osa determinanterna direkt, skulle det beh¨ovas 31 · 30! · 29 multiplikationer, och ett motvarande antal additioner. ¨Aven p˚a en snabb dator som kan g¨ora 109 flops, skulle det r¨acka ca 1019 ˚ar! Man skulle ocks˚a kunna t¨anka sig att l¨osa ekvationssystemet genom matrisinversion:
x = A−1y, men det l¨onar sig inte, bl.a. p˚a grund av det finns snabbare metoder.
1efter Gabriel Cramer, schweizisk matematiker (1704-1752), som beskrev metoden i Introduction `a l’analyse des lignes courbes alg´ebraique
En stor matris kan ta upp mycket utrymme i datorns minne. M˚anga matriser, som anv¨ands i fysiken, har ett stort antal element lika med noll, och den kallas d˚a gles. Om matrisen ¨ar gles, l¨onar det sig endast att lagra de matriselement som ¨ar olika noll. I s˚adana fall m˚aste man anv¨anda n˚agon metod f¨or att ange matriselementens l¨age i den ursprungliga matrisen. Om matrisen ¨ar varken gles eller singul¨ar (dvs dess determinant ¨ar olika 0), s˚a kan ekvationssystemet l¨osas enligt en metod som uppt¨acktes av C.F. Gauss. Vi skall dock b¨orja med att studera triangul¨ara ekvationssystem, som kan l¨osas p˚a ett enklare s¨att.
Antag, att vi har triangul¨art ekvationssystem med tre obekanta:
2
4a11 0 0
a21 a22 0 a31 a32 a33
3 5
2 4x1
x2 x3
3 5 =
2 4b1
b2 b3
3 5
Dessa ekvationer kan l¨osas s˚a, att man f¨orst r¨aknar ut x1 ur den f¨orsta ekvationen, substituerar l¨osningen i den andra ekvationen, som sedan kan l¨osas i avseende p˚a x2, och till sist substituerar x1 och x2 i den tredje ekvationen, och ber¨aknar x3:
x1 = b1/a11
x2 = (b2 − a21x1)/a22
x3 = (b3 − a31x1 − a32x2)/a33.
Denna typ av algoritm kallas fram˚atsubstitution. F¨or att den skall fungera, m˚aste det(A) = a11a22a33 vara olika noll.
Vi skall nu skriva ett MATLAB-program f¨or att l¨osa systemet Lx = b, d¨ar L ¨ar en undre triangul¨ar matris. Den i:te ekvationen i detta system kan d˚a skrivas
`i1x1 + . . . + `iixi = bi, och l¨osningen kan skrivas
xi = 0
@bi − Xi−1
j=1
`ijxj 1
A /`ii.
P˚a basen av denna ekvation kan vi skriva ett programfragment f¨or att ber¨akna x:
for i = 1:n
x(i) = b(i);
for j=1:i-1
x(i) = x(i) - L(i,j)*x(j);
end
x(i) = x(i)/L(i,i);
end