A lineáris algebra a sokváltozós lineáris egyenletrendszerek megoldásával, illetve megoldhatóságának vizsgálatával foglalkozik.
A lineáris algebra gyakorlati jelentősége abban mutatkozik meg, hogy számos bonyolult matematikai probléma numerikus megoldása sok esetben egy sok (esetenként igen sok, akár több millió) ismeretlenes lineáris egyenletrendszerre vezet. Az alábbiakban a numpy
csomag lineáris algebrai rutinjaival fogunk megismerkedni. Először a matrix
típust vizsgáljuk meg, mely segítségével egszerű vektor-mátrix műveletek tömören fogalmazhatóak meg. Ezután a solve
lineáris egyenletrendszereket megoldó függvény használatát sajátítjuk el, végül az eig
sajátérték-, illetve sajátvektor-kereső rutinnal ismerkedünk meg.
In [1]:
# A szokásos import
%pylab inline
A korábbiakban rendszeresen használtuk a numpy
csomag array
válltozóit. Ezek sok szempontból hasznosnak bizonyultak, de alapvetően táblázatként működtek, és nem a lineáris algebrában megszokott mátrixként. Ennek a legszembetűnőbb megnyilvánulása az, hogy a rájuk értelmezett műveletek szigorúan elemenként értendőek voltak. Azaz a *
elemenkénti szorzást és nem mátrixszorzást jelent. Például az alább definiált A
és B
tömbök
In [2]:
# két minta array
A=array([[1,2],
[3,4]])
B=array([[2,2],
[2,2]])
egymással összeszorozva egy olyan array
-t adnak végeredményül, amelynek elemei az A
és a B
elemeinek szorzata:
$$ (A*B)_{ij}=A_{ij}*B_{ij} $$
In [3]:
A*B
Out[3]:
Ez a művelet természetesen nem érzékeny a műveleti sorrendre, azaz A*B=B*A
:
In [4]:
B*A
Out[4]:
A numpy
rendelkezik egy matrix
típussal is, ami sok szempontból hasonlóan viselkedik, mint az array
, de bizonyos műveletek, például a * is a lineáris algebrában megszokott módon van definiálva. Azaz itt a *-jel az alábbiakat jelenti:
$$ (A*B)_{ij}=\sum_l A_{il}B_{lj} $$
A matrix()
-függvény array
vagy list
típusú változókból matrix
típusú változókat csinál:
In [5]:
# Így definiálunk mátrixokat
Am=matrix(A)
Bm=matrix(B)
Figyeljük meg, hogy az Am
és Bm
változókra miként hat a * művelet:
In [6]:
Am*Bm
Out[6]:
In [7]:
Bm*Am
Out[7]:
A szorzás eredménye tehát ahogy vártuk, függ a műveleti sorrendtől!
Nézzünk meg egypár hasznos lineáris algebrai mátrixműveletet:
In [8]:
Am.T # Ez az Am mátrix transzponáltja
Out[8]:
In [9]:
Am+1.0j*Bm #Ez egy komplex mátrix
Out[9]:
In [10]:
(Am+1.0j*Bm).H # Ez a komplex mátrix adjungáltja, azaz a transzponált konjugáltja
Out[10]:
In [11]:
trace(Am) # A mátrix nyoma, (vagy spur-ja) azaz a diagonális elemek összege
Out[11]:
In [12]:
trace(A) # A trace ugyan úgy működik array-ekre
Out[12]:
In [13]:
det(Am) # A mátrix determinánsa
Out[13]:
In [14]:
det(A) # A determináns is alkalmazható array-ekre
Out[14]:
In [15]:
inv(Am) # A mátrix inverze.. ugyebár ez nem feltétlenül létezik
Out[15]:
In [16]:
inv(A) # Ez is megy array -ekre
Out[16]:
In [17]:
inv(Am)*Am # Ennek egységnek kell lennie
Out[17]:
Az egyik gyakran előforduló lineáris algebrai feladat az egyenletrendszerek megoldása. Például keressük azt az $x$ vektort amely teljesíti a
$$ \mathbf{A}x=b$$egyenletet, ahol $\mathbf{A}$ egy ismert mátrix és $b$ egy ismert vektor. A numpy
csomag az ilyen formában megadott egyenletrendszer megoldására a solve
függvényt kínálja.
Fgyelem: ez a függvény nem keverendő össze a sympy
csomag azonos nevű függvényével, amely tetszőleges algebrai egyenletrendszerre kínál analitikus megoldást. A numpy
modul solve
függvénye szigorúan csak numerikus lineáris algebrai feladatok megoldására alkalmas!
Vizsgáljuk meg egy példát ! Keressük meg azt a síkbeli vektort, amit ha $\varphi=30^\circ$-al az óra járásával megegyező irányban elforgatunk, akkor az $y$ irányú egységvektort kapjuk! Azaz
$$A=\begin{pmatrix} \cos(\varphi) & -\sin(\varphi)\\ \sin(\varphi) & \cos(\varphi) \end{pmatrix}$$valamint $$b=\begin{pmatrix} 0 \\ 1 \end{pmatrix}$$
In [ ]:
# az ismert mennyiségek definiálása:
phi=pi/6;
#Ez az A mátrix
A=matrix([[cos(phi), -sin(phi)],
[sin(phi), cos(phi)]])
#Ez pedig a b oszlopvektor, figyeljünk a zárójelezésre!!!
b=matrix([[0],
[1]])
In [19]:
x=solve(A,b)
In [20]:
x
Out[20]:
A másik sokszor felmerülő lineáris algebrai problémakör egy mátrix sajátértékeinek és sajátvektorainak meghatározása. Legyen $A$ egy ismert mátrix, és keressük tehát azon $x$ vektorokat, illetve azon $\lambda$ számokat, melyek teljesítik az alábbi feltételt.
$$ \mathbf{M}x=\lambda x.$$Ilyen jellegű problémákat az eig
rutin segítségével tudunk megoldani. Lássunk erre is egy példát!
Legyen $M$ egy 10x10-es mátrix, melynek mindkét első mellékátlója -1, a többi elem pedig nulla!
In [21]:
M=matrix(zeros((10,10))) # Így gyártunk egy 10x10-es üres mátrixot.
for i in range(9):#A mellékátlók 1-el rövidebbek mint a mátrix mérete!
M[i,i+1]=-1.0 #A mellékátlók feltöltése -1 -el
M[i+1,i]=-1.0
In [22]:
M # nézzük meg a mátrixot
Out[22]:
A sajátérték-probléma megoldása:
In [23]:
ertek,vektor=eig(M)
Most az ertek
valtozó tartalmazza a saját értékeket illetve a vektor
a sajátvektorokat.
In [24]:
ertek
Out[24]:
In [25]:
vektor
Out[25]:
Az $i$-edik sajátvektort a vektor
változó i
-edik oszlopa, vektor[:,i]
tartalmazza.
Ez a sajátvektor az $i$-edik, ertek[i]
sajátértékhez tartozó megoldása az $Mx=\lambda x$ sajátérték-problémának.
Ellenőrizzük ezt le:
In [26]:
#ez tehát a nullvektor kell hogy legyen:
M*vektor[:,3]-vektor[:,3]*ertek[3]
Out[26]:
Jelenítsük meg a két legkisebb sajátértékhez tartozó sajátfüggvényt!
In [27]:
plot(vektor[:,0],'o-',label='elso sajatvektor')
plot(vektor[:,1],'+--',label='masodik sajatvektor')
legend()
Out[27]:
Vajon miért néznek így ki ezek a sajátfüggvények ?