Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Razcep LU

Za rešitev sistema linearnih enačb zahteva Gaussov eliminacijski postopek najmanjše število računskih operacij.

V primeru, ko se matrika koeficientov A\mathbf{A} ne spreminja in se spreminja zgolj vektor konstant b\mathbf{b}, se je mogoče izogniti ponovni Gaussovi eliminaciji matrike koeficientov. Z razcepom matrike A\mathbf{A} lahko pridemo do rešitve z manj računskimi operacijami. V ta namen si bomo pogledali razcep LU!

Poljubno matriko lahko zapišemo kot produkt dveh matrik:

A=B C.\mathbf{A}=\mathbf{B}\,\mathbf{C}.

Pri tem je možnosti za zapis matrik B\mathbf{B} in C\mathbf{C} neskončno veliko.

Pri razcepu LU zahtevamo, da je matrika B\mathbf{B} spodnje trikotna in matrika C\mathbf{C} zgornje trikotna:

A=L U.\mathbf{A}=\mathbf{L}\,\mathbf{U}.

Vsaka od matrik L\mathbf{L} in U\mathbf{U} ima (n+1) n/2(n+1)\,n/2 neničelnih elementov; skupaj torej n2+nn^2+n neznank. Znana matrika A\mathbf{A} definira n2n^2 vrednosti. Za enolično določitev matrik L\mathbf{L} in U\mathbf{U} torej manjka nn enačb. Tukaj bomo uporabili razcep LU, ki dodatne enačbe pridobi s pogojem Lii=1L_{ii}=1, i=0,1,…,n−1i=0, 1,\dots,n-1.

Sistem linearnih enačb:

Ax=b\mathbf{A}\mathbf{x}=\mathbf{b}

torej zapišemo z razcepom matrike A\mathbf{A}:

L U x⏟y=b.\mathbf{L}\,\underbrace{\mathbf{U}\,\mathbf{x}}_{\mathbf{y}}=\mathbf{b}.

Do rešitve sistema Ax=b\mathbf{A}\mathbf{x}=\mathbf{b} sedaj pridemo tako, da rešimo dva trikotna sistema enačb.

Najprej izračunamo vektor y\mathbf{y}:

L y=b.(direktno vstavljanje)\mathbf{L}\,\mathbf{y}=\mathbf{b}.\qquad \textrm{(direktno vstavljanje)}

Ko je y\mathbf{y} izračunan, lahko iz:

U x=y(obratno vstavljanje)\mathbf{U}\,\mathbf{x}=\mathbf{y}\qquad \textrm{(obratno vstavljanje)}

določimo x\mathbf{x}.

Razcep LU matrike koeficientov A\mathbf{A}

V nadaljevanju bomo pokazali, da Gaussova eliminacija dejansko predstavlja razcep LU matrike koeficientov A\mathbf{A}. Pri tem si bomo pomagali s simbolnim izračunom, zato uvozimo paket sympy:

Prikaz začnimo na primeru simbolno zapisanih matrik L\mathbf{L} in U\mathbf{U} dimenzije 3×33\times 3:

Matrika koeficientov A\mathbf{A} zapisana z elementi matrik L\mathbf{L} in U\mathbf{U} torej je:

Loading...

Izvedimo sedaj Gaussovo eliminacijo nad matriko koeficientov A\mathbf{A}.

S pomočjo prve vrstice izvedemo Gaussovo eliminacijo v prvem stolpcu:

Loading...

Nadaljujemo v drugem stolpcu:

Loading...

Iz zgornje eliminacije ugotovimo:

  1. matrika U\mathbf{U} je enaka matriki, ki jo dobimo, če izvedemo Gaussovo eliminacijo nad matriko koeficientov A\mathbf{A}.

  • izven diagonalni členi L\mathbf{L} so faktorji, ki smo jih uporabili pri Gaussovi eliminaciji.

Numerična implementacija razcepa LU

Numerično implementacijo si bomo pogledali na sistemu, ki je definiran kot:

Izvedimo Gaussovo eliminacijo in koeficiente, s katerim množimo pivotno vrsto m, shranimo v matriko L na mesto z indeksi, kot jih ima v matriki A\mathbf{A} eliminirani element.

Korak: 0
[[ 8.    -6.     3.   ]
 [ 0.     1.5   -3.75 ]
 [ 0.    -3.75   4.875]]
Korak: 1
[[ 8.   -6.    3.  ]
 [ 0.    1.5  -3.75]
 [ 0.    0.   -4.5 ]]
array([[ 0. , 0. , 0. ], [-0.75 , 0. , 0. ], [ 0.375, -2.5 , 0. ]])

Dopolnimo diagonalo L\mathbf{L}:

array([[ 1. , 0. , 0. ], [-0.75 , 1. , 0. ], [ 0.375, -2.5 , 1. ]])

Sedaj rešimo spodnje trikotni sistem enačb L y=b\mathbf{L}\,\mathbf{y}=\mathbf{b}:

array([-14. , 25.5, 75. ])

Nadaljujemo z reševanjem zgornje trikotnega sistema U x=y\mathbf{U}\,\mathbf{x}=\mathbf{y}:

array([[ 8. , -6. , 3. ], [ 0. , 1.5 , -3.75], [ 0. , 0. , -4.5 ]])
array([-14. , 25.5, 75. ])
array([-14. , -24.66666667, -16.66666667])

Kakor smo navedli zgoraj, ob spremembi vektorja konstant b\mathbf{b} ponovna Gaussova eliminacija ni potrebna. Izvesti je treba samo direktno in nato obratno vstavljanje. Poglejmo primer:

array([-4.33333333, -7.88888889, -4.55555556])
array([-1., 6., 7.])

Pivotiranje

Poglejmo si spodnji sistem enačb:

Če bi izvedli Gaussovo eliminacijo v prvem stolpcu matrike A\mathbf{A}:

C:\Users\janko\AppData\Local\Temp\ipykernel_17316\3999418912.py:1: RuntimeWarning: divide by zero encountered in scalar divide
  A[1,:] - A[1,0]/A[0,0] * A[0,:]
C:\Users\janko\AppData\Local\Temp\ipykernel_17316\3999418912.py:1: RuntimeWarning: invalid value encountered in multiply
  A[1,:] - A[1,0]/A[0,0] * A[0,:]
array([ nan, -inf, inf])

Opazimo, da imamo težavo z deljenjem z 0 v prvi vrstici. Elementarne operacije, ki jih nad sistemom lahko izvajamo, dovoljujejo zamenjavo poljubnih vrstic. Sistem lahko preuredimo tako, da pivotni element ni enak 0. Vseeno se lahko zgodi, da ima pivotni element, s katerim delimo, zelo majhno vrednost ε\varepsilon. Ker bi to povečevalo zaokrožitveno napako, izmed vseh vrstic za pivotno vrstico izberemo tisto, katere pivot ima največjo absolutno vrednost.

Če med Gaussovo eliminacijo zamenjamo vrstice tako, da je pivotni element največji, to imenujemo pivotiranje vrstic ali tudi delno pivotiranje. Tako dosežemo, da je Gaussova eliminacija numerično stabilna.

Pokazati je mogoče, da pri reševanju sistema enačb A x=b\mathbf{A}\,\mathbf{x}=\mathbf{b}, pri katerem je matrika A\mathbf{A} diagonalno dominantna, pivotiranje po vrsticah ni potrebno. Reševanje je brez pivotiranja numerično stabilno.

Kvadratna matrika A\mathbf{A} dimenzije nn je diagonalno dominantna, če je absolutna vrednost diagonalnega elementa vsake vrstice večja od vsote absolutnih vrednosti ostalih elementov v vrstici:

∣Aii∣>∑j=1,j≠in∣Aij∣\left|A_{ii}\right|> \sum_{j=1, j\ne i}^n \left|A_{ij}\right|

Gaussova eliminacija z delnim pivotiranjem

Pogledali si bomo Gaussovo eliminacijo z delnim pivotiranjem. Brez delnega pivotiranja v ii-tem koraku eliminacije izberemo vrstico ii za pivotiranje. Pri delnem pivotiranju pa najprej preverimo, ali je ii-ti diagonalni element po absolutni vrednosti največji element v stolpcu ii na ali pod diagonalo; če ni, zamenjamo vrstico ii s tisto vrstico pod njo, v kateri je v stolpcu ii po absolutni vrednosti največji element. Z delnim pivotiranjem zmanjšamo vpliv zaokrožitvene napake na rezultat.

V kolikor bi izvedli polno pivotiranje, bi poleg zamenjave vrstic uporabili tudi zamenjavo vrstnega reda spremenljivk (zamenjava stolpcev). Polno pivotiranje izboljša stabilnost, se pa redko uporablja in ga tukaj ne bomo obravnavali.

Algoritem za Gaussovo eliminacijo z delnim pivotiranjem torej je:

array([[ 0., -6., 6.], [-6., 6., -6.], [ 8., -6., 3.]])
Korak: 0
Pivot vrsta: [  8.  -6.   3. -14.]
[[  8.    -6.     3.   -14.  ]
 [  0.     1.5   -3.75  25.5 ]
 [  0.    -6.     6.     6.  ]]
Korak: 1
Pivot vrsta: [ 0. -6.  6.  6.]
[[  8.    -6.     3.   -14.  ]
 [  0.    -6.     6.     6.  ]
 [  0.     0.    -2.25  27.  ]]

Razcep LU z delnim pivotiranjem

Podobno kakor pri Gaussovi eliminaciji lahko tudi razcep LU razširimo z delnim pivotiranjem. Reševanje tako postane numerično stabilno. Pri tem moramo shraniti informacijo o zamenjavi vrstic, ki jo potem posredujemo v funkcijo za rešitev ustreznih trikotnih sistemov.

Poglejmo si primer:

Korak: 0
Pivot vrsta: [ 8. -6.  3.]
[[ 8.   -6.    3.  ]
 [-0.75  1.5  -3.75]
 [ 0.   -6.    6.  ]]
Korak: 1
Pivot vrsta: [ 0. -6.  6.]
[[ 8.   -6.    3.  ]
 [ 0.   -6.    6.  ]
 [-0.75 -0.25 -2.25]]

V zgornjem primeru smo uporabili kompakten način zapisa trikotnih matrik L\mathbf{L} in U\mathbf{U}; vsaka je namreč definirana s 6 elementi, pri matriki L\mathbf{L} pa vemo, da so diagonalni elementi enaki 1. Matrika lu tako vsebuje 3×3=93\times3=9 elementov:

array([[ 8. , -6. , 3. ], [ 0. , -6. , 6. ], [-0.75, -0.25, -2.25]])

Na diagonali in nad diagonalo so vrednosti zgornje trikotne matrike U\mathbf{U}, pod diagonalo pa so poddiagonalni elementi matrike L\mathbf{L}. Pri izračunu rešitve bomo upoštevali, da so diagonalne vrednosti L\mathbf{L} enake 1.

Numerični seznam piv nam pove, kako so bile zamenjane vrstice, kar je treba upoštevati pri izračunu rešitve:

array([2, 0, 1])

Določimo sedaj še rešitev (koda za računanje rešitve je v modulu orodja.py)

array([ -3.66666667, -14.11111111, -16.44444444])

Preverjanje rešitve:

array([-14., 36., 6.])

Modul SciPy

Modul SciPy temelji na numpy modulu in vsebuje veliko različnih visokonivojskih programov/modulov/funkcij. Teoretično ozadje modulov so seveda različni numerični algoritmi; nekatere spoznamo tudi v okviru tega učbenika. Dober vir teh numeričnih algoritmov v povezavi s SciPy predstavlja dokumentacija. Za odličen uvod v SciPy si lahko ogledate YouTube posnetek: SciPy Tutorial (2022): For Physicists, Engineers, and Mathematicians.

Kratek pregled hierarhije modula:

V sledečih predavanjih si bomo nekatere podmodule podrobneje pogledali.

Poglejmo si, kako je znotraj SciPy implementiran razcep LU:

Funkcija scipy.linalg.lu_factor (dokumentacija):

lu_factor(a, overwrite_a=False, check_finite=True)

zahteva vnos matrike koeficientov (ali seznama matrik koeficientov) a, overwrite_a v primeru True z rezultatom razcepa prepiše vrednost a (to je lahko pomembno, da se prihrani spomin in poveča hitrost). Funkcija lu_factor vrne terko (lu, piv):

  • lu - L\mathbf{L} \ U\mathbf{U} matrika (matrika, ki je enake dimenzije kot a, vendar pod diagonalo vsebuje elemente L\mathbf{L}, preostali elementi pa definirajo U\mathbf{U}; diagonalni elementi L\mathbf{L} imajo vrednosti 1.

  • piv - pivotni indeksi, predstavljajo permutacijsko matriko P: vrsta i matrike a je bila zamenjana z vrsto piv[i] (v vsakem koraku se upošteva predhodno stanje, malo drugačna logika kot v naši funkciji LU_razcep_pivotiranje).

lu_factor uporabljamo v paru s funkcijo scipy.linalg.lu_solve (dokumentacija), ki nam poda rešitev sistema:

lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True)

lu_and_piv je terka rezultata (lu, piv) iz lu_factor, b je vektor (ali seznam vektorjev) konstant. Ostali parametri so opcijski.

Poglejmo si uporabo:

array([[ 8. , -6. , 3. ], [ 0. , -6. , 6. ], [-0.75, -0.25, -2.25]])
array([2, 2, 2], dtype=int32)

Pridobimo rešitev:

array([ -3.66666667, -14.11111111, -16.44444444])

Preverimo ustreznost rešitve:

array([-14., 36., 6.])

Računanje inverzne matrike

Inverzno matriko h kvadratni matriki A\textbf{A} reda n×nn\times n označimo z A−1\textbf{A}^{-1}. Je matrika reda n×nn\times n, takšna, da velja

A A−1=A−1 A=I,\mathbf{A}\,\mathbf{A}^{-1} = \mathbf{A}^{-1}\,\mathbf{A} = \mathbf{I},

kjer je I\mathbf{I} enotska matrika.

Najbolj učinkovit način za izračun inverzne matrike od matrike A\mathbf{A} je rešitev matrične enačbe:

A X=I.\mathbf{A}\,\mathbf{X}=\mathbf{I}.

Matrika X\mathbf{X} je inverzna matriki A\mathbf{A}: A−1=X\mathbf{A}^{-1}=\mathbf{X}.

Izračun inverzne matrike je torej enak reševanju nn sistemov nn linearnih enačb:

A xi=bi,i=0,1,2,…,n−1,\mathbf{A}\,\mathbf{x}_i=\mathbf{b}_i,\qquad i=0,1,2,\dots,n-1,

kjer je bi\mathbf{b}_i ii-ti stolpec matrike B=I\mathbf{B}=\mathbf{I}.

Numerična zahtevnost: izvedemo razcep LU nad matriko A\mathbf{A} (računski obseg reda n3n^3) in nato poiščemo rešitev za vsak xi\mathbf{x}_i (2 n22\,n^2 računskih operacij za vsak ii). Skupni računski obseg je torej še vedno reda n3n^3. (Če bi nn krat izvajali Gaussovo eliminacijo, bi bil obseg reda n4n^4.)

(array([[ 8. , -6. , 3. ], [ 0. , -6. , 6. ], [-0.75, -0.25, -2.25]]), array([2, 2, 2], dtype=int32))

Tukaj se sedaj pokaže smisel razcepa LU; razcep namreč izračunamo samo enkrat in potem za vsak vektor konstant poiščemo rešitev tako, da rešimo dva trikotna sistema. Če bi sisteme reševali po Gaussovi metodi, bi rabili (n3+n2) n(n^3+n^2)\,n računskih operacij.

Izračunajmo inverzno matriko od matrike A\textbf{A}. Najprej z uporabo np.identity() pripravimo enotsko matriko:

array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])

Nato rešimo sistem enačb za vsak stolpec enotske matrike:

Rešitev torej je:

array([[-1.66666667e-01, -1.66666667e-01, 1.38777878e-17], [-2.77777778e-01, -4.44444444e-01, -3.33333333e-01], [-1.11111111e-01, -4.44444444e-01, -3.33333333e-01]])

Preverimo rešitev:

array([[ 1.00000000e+00, 0.00000000e+00, 1.11022302e-16], [ 0.00000000e+00, 1.00000000e+00, -1.11022302e-16], [ 5.55111512e-17, 0.00000000e+00, 1.00000000e+00]])

Rešitev z uporabo Numpy:

array([[-1.66666667e-01, -1.66666667e-01, 1.38777878e-17], [-2.77777778e-01, -4.44444444e-01, -3.33333333e-01], [-1.11111111e-01, -4.44444444e-01, -3.33333333e-01]])

Z ustrezno uporabo funkcij iz modula SciPy lahko do rešitve pridemo še hitreje. V funkcijo lu_solve lahko vstavimo vektor b\mathbf{b} ali matriko B\mathbf{B}, katere posamezni stolpec ii predstavlja nov vektor konstant bi\mathbf{b}_i.

array([[-1.66666667e-01, -1.66666667e-01, 1.38777878e-17], [-2.77777778e-01, -4.44444444e-01, -3.33333333e-01], [-1.11111111e-01, -4.44444444e-01, -3.33333333e-01]])

Reševanje predoločenih sistemov

Loading...

Kadar rešujemo sistem mm linearnih enačb z nn neznankami ter velja m>nm>n in je rang razširjene matrike [A ∣ b][\mathbf{A}\,|\,\mathbf{b}] enak n+1n+1, imamo predoločeni (nekonsistenten) sistem.

Predoločeni (tudi nekonsistenten sistem):

A x=b,\mathbf{A}\,\mathbf{x}=\mathbf{b},

nima rešitve. Lahko pa poiščemo najboljši približek rešitve z metodo najmanjših kvadratov.

Vsota kvadratov preostankov je definirana s skalarnim produktom:

∥r∥2=(A x−b)T (A x−b)\left\lVert r\right\rVert ^2=(\mathbf{A}\,\mathbf{x}-\mathbf{b})^T\,(\mathbf{A}\,\mathbf{x}-\mathbf{b})

kar preoblikujemo v:

∥r∥2=xTATAx−2bTAx+bTb,\left\lVert r\right\rVert^2=\mathbf{x}^T\mathbf{A}^T\mathbf{A}\mathbf{x}-2\mathbf{b}^T\mathbf{A}\mathbf{x}+\mathbf{b}^T\mathbf{b},

kjer smo upoštevali, da zaradi skalarne vrednosti velja: bTAx=(bT(Ax))T=(Ax)Tb\mathbf{b}^T\mathbf{A}\mathbf{x}=(\mathbf{b}^T(\mathbf{A}\mathbf{x}))^T=(\mathbf{A}\mathbf{x})^T\mathbf{b}.

Rešitev enačbe, gradient vsote kvadratov, določa njen minimum:

∇x ∥r∥2=2ATA x−2AT b=0\nabla_x\,\left\lVert r\right\rVert^2=2\mathbf{A}^T\mathbf{A}\,\mathbf{x}-2\mathbf{A}^T\,\mathbf{b}=0

Tako iz normalne enačbe:

ATA x=AT b\mathbf{A}^T\mathbf{A}\,\mathbf{x}=\mathbf{A}^T\,\mathbf{b}

določimo najboljši približek rešitve:

x=(ATA)−1AT b.\mathbf{x}=\left(\mathbf{A}^T\mathbf{A}\right)^{-1}\mathbf{A}^T\,\mathbf{b}.

Z vpeljavo psevdo inverzne matrike:

A+=(ATA)−1AT\mathbf{A}^+=\left(\mathbf{A}^T\mathbf{A}\right)^{-1}\mathbf{A}^T

k matriki A\mathbf{A} je rešitev predoločenega sistema zapisana:

x=A+ b.\mathbf{x}=\mathbf{A}^+\,\mathbf{b}.

Zgoraj predstavljen postopek je relativno enostaven, je pa numerično zahteven in lahko v nekaterih primerih slabo pogojen; priporočeno je, da v praksi psevdo inverzno matriko izračunamo z uporabo funkcij:

  • numpy.linalg.pinv iz modula numpy (dokumentacija),

  • Funkcij pinv ali pinvh iz modula scipy.linalg (izbira je odvisna od obravnavanega problema; glejte dokumentacijo),

ki temeljijo na boljših numerični metodah.

Primer sistema z enolično rešitvijo:

array([1., 2.])

Naredimo sedaj predoločeni sistem (funkcija numpy.vstack (dokumentacija) zloži sezname kot vrstice, numpy.random.seed (dokumentacija) ponastavi generator naključnih števil na vrednost semena seed, numpy.random.normal (dokumentacija) pa generira normalno porazdeljeni seznam dolžine size in standardne deviacije scale):

array([[1.01764052, 2.00400157], [2.00978738, 3.02240893], [1.01867558, 1.99022722], [2.00950088, 2.99848643], [0.99896781, 2.00410599], [2.00144044, 3.01454274]])
array([5.00761038, 8.00121675, 5.00443863, 8.00333674, 5.01494079, 7.99794842])

Rešimo sedaj predoločen sistem:

array([0.94512271, 2.02675939])

Vidimo, da predoločeni sistem z naključnimi vrednostmi (simulacija šuma pri meritvi) poda podoben rezultat kakor rešitev brez šuma. V kolikor bi nivo šuma povečevali, bi se odstopanje od enolične rešitve povečevalo.

Psevdo inverzno matriko lahko določimo tudi sami in preverimo razliko z vgrajeno funkcijo:

array([[-8.88178420e-16, 2.77555756e-15, 3.33066907e-16, 3.33066907e-15, -1.11022302e-15, 2.99760217e-15], [ 1.22124533e-15, -6.10622664e-16, 4.44089210e-16, -6.66133815e-16, 1.11022302e-15, -1.27675648e-15]])

Iterativne metode

Pogosto se srečamo z velikimi sistemi linearnih enačb, katerih matrika koeficientov ima malo od nič različnih elementov (take matrike imenujemo redke ali tudi razpršene, angl. sparse).

Pri reševanju takih sistemov linearnih enačb se zelo dobro izkažejo iterativne metode; prednosti v primerjavi z direktnimi metodami so:

  • računske operacije se izvajajo samo nad neničelnimi elementi (kljub iterativnemu reševanju jih je lahko manj)

  • zahtevani spominski prostor je lahko neprimerno manjši.

Gauss-Seidelova metoda

V nadaljevanju si bomo pogledali idejo Gauss-Seidelove iterativne metode. Najprej sistem enačb A x=b\mathbf{A}\,\mathbf{x}=\mathbf{b} zapišemo kot:

∑j=0n−1Aijxj=bii=0,1,…,n−1.\sum_{j=0}^{n-1} A_{ij}x_j=b_i\qquad{}i=0,1,\dots,n-1.

Predpostavimo, da smo v k−1k-1 koraku iterativne metode in so znani približki xj(k−1)x_{j}^{(k-1)} (j=0,1,…,n−1j=0,1,\dots, n-1). Iz zgornje vsote izpostavimo člen ii:

Aii xi(k−1)+∑j=0,j≠in−1Aijxj(k−1)=bii=0,1,…,n−1.A_{ii}\,x_{i}^{(k-1)} +\sum_{j=0, j\ne i}^{n-1} A_{ij}x_{j}^{(k-1)}=b_i\qquad{}i=0,1,\dots,n-1.

Ker približki xj(k−1)x_{j}^{(k-1)} ne izpolnjujejo natančno linearnega problema, lahko iz zgornje enačbe določimo nov približek xi(k)x_{i}^{(k)}:

xi(k)=1Aii(bi−∑j=0i−1Aijxj(k)−∑j=i+1n−1Aijxj(k−1))x_{i}^{(k)} =\frac{1}{A_{ii}}\left(b_i-\sum_{j=0}^{i-1} A_{ij}x_{j}^{(k)}-\sum_{j=i+1}^{n-1} A_{ij}x_{j}^{(k-1)}\right)

Vsoto smo razdelili na dva dela in za izračun ii-tega člena upoštevali v kk-ti iteraciji že določene člene z indeksom manjšim od ii.

Iterativni pristop prekinemo, ko dosežemo želeno natančnost rešitve ϵ\epsilon:

∣xi(k)−xi(k−1)∣<ε\left|x_{i}^{(k)}-x_{i}^{(k-1)}\right|<\varepsilon

Zgled

Začetni približek:

array([0., 0., 0.])

Pripravimo matriko A\mathbf{A} brez diagonalnih elementov (Zakaj? Poskusite odgovoriti spodaj, ko bomo izvedli iteracije.)

array([[ 0., -1., 1.], [-1., 0., -1.], [ 0., -1., 0.]])

Izvedemo iteracije:

xi(k)=1Aii(bi−∑j=0i−1Aijxj(k)−∑j=i+1n−1Aijxj(k−1))x_{i}^{(k)} =\frac{1}{A_{ii}}\left(b_i-\sum_{j=0}^{i-1} A_{ij}x_{j}^{(k)}-\sum_{j=i+1}^{n-1} A_{ij}x_{j}^{(k-1)}\right)

(Ker bomo vrednosti takoj zapisali v x, ni treba razbiti vsote na dva dela)

-----iteracja 0-----
Približek za element 0 [-1.75  0.    0.  ]
Približek za element 1 [-1.75        5.70833333  0.        ]
Približek za element 2 [-1.75        5.70833333  1.95138889]
Norma 6.281360365408393
-----iteracja 1-----
Približek za element 0 [-1.28038194  5.70833333  1.95138889]
Približek za element 1 [-1.28038194  6.11183449  1.95138889]
Približek za element 2 [-1.28038194  6.11183449  2.01863908]
Norma 0.6227976321231091
-----iteracja 2-----
Približek za element 0 [-1.23835057  6.11183449  2.01863908]
Približek za element 1 [-1.23835057  6.13004808  2.01863908]
Približek za element 2 [-1.23835057  6.13004808  2.02167468]
Norma 0.04590845211691733

Preverimo rešitev

array([-14.01517799, 35.9969644 , 6. ])

Metoda deluje dobro, če je matrika diagonalno dominantna (obstajajo pa metode, ki delujejo tudi, ko matrika ni diagonalno dominantna, glejte npr.: J. Petrišič, Reševanje enačb, 1996, str 149: Metoda konjugiranih gradientov).


Vprašanja za vaje


LU razcep

Vprašanje 1: Enačbe ravnotežja sil in momentov za nosilec na sliki zapišemo:

Določite reakcije v podporah za pet različnih kotov φ\varphi iz podanega seznama, tako, da razcep matrike koeficientov opravite le enkrat. Rešitev vsakič izpišite s funkcijo print.

smer x:Ax=F cos⁡(φ)smer y:Ay+B=F sin⁡(φ)moment okoli A:Bl=Fa sin⁡(φ)\begin{align} \text{smer }x &:\quad A_x = F\,\cos(\varphi)\\ \text{smer }y &:\quad A_y + B = F\,\sin(\varphi)\\ \text{moment okoli }A&:\quad Bl = Fa\,\sin(\varphi) \end{align}

Računanje inverza matrike

Vprašanje 2: uporabite LU razcep in po zgoraj opisanem postopku določite inverz matrike A\mathbf{A} iz prejšnje naloge.


Reševanje predoločenih sistemov - psevdoinverz

Vprašanje 3: Določite aproksimacijsko premico, ki z minimalno kvadratično napako opiše nn podanih točk (X,Y)(X, Y). Parametra kk in nn aproksimacijske premice y=kx+ny = kx+n poiščite z rešitvijo sistema linearnih enačb:

[X,1] n×2 x=[Y]\mathbf{[X, 1]}_{~n\times 2}~\mathbf{x} = \mathbf{[Y]}

kjer so v prvem stolpcu matrike koeficientov koordinate XX podanih točk, v drugem stolpcu pa same enice. Vektor desnih strani je enak vektorju YY koordinat obravnavanih točk.

Izrišite na isti sliki množico točk (X,Y)(X, Y) in dobljeno aproksimacijsko premico.


Iterativne metode reševanja sistemov linearnih enačb

Gauss-Seidelova metoda

xi=1Aii(bi−∑j=0,j≠inAijxj)i=0,1,…,n−1x_i =\frac{1}{A_{ii}}\left(b_i-\sum_{j=0, j\ne i}^n A_{ij}x_j\right)\qquad{}i=0,1,\dots,n-1

Vprašanje 4: Z uporabo iterativne Gauss-Seidel metode rešite podan sistem enačb.

Primerjajte rezultat z Gaussovo eliminacijo. Opazujte vpliv števila iteracij na natančnost rešitve.