Sunteți pe pagina 1din 20

Lucrarea 3

REZOLVAREA NUMERIC A SISTEMELOR DE


ECUAII
1. SCOPUL LUCRRII
Prezentarea unor metode de rezolvare a sistemelor de ecuaii liniare i neliniare
i a algoritmilor acestora ntr-o variant de pseudocod asemntoare limbajului
C, implementarea ntr-un limbaj de nivel nalt (n particular, C) i folosirea lor n
rezolvarea unor probleme de electronic.
2. PREZENTARE TEORETIC
Fie funcia f X Y : - > , X R
n
, Y R
n
i f x ( ) = 0 un sistem de ecuaii. Dup
gradul necunoscutelor din ecuaii, sistemele sunt liniare, dac acestea sunt de gradul
nti i neliniare dac exist ecuaii ce conin necunoscute la puteri mai mari ca unu.
2.1. REZOLVAREA NUMERIC A SISTEMELOR LINIARE
Un sistem liniar de n ecuaii cu n necunoscute se prezint astfel:
a x a x ... a x b
a x a x ... a x b
a x a x ... a x b
n n
n n
n n nn n n
11 1 12 2 1 1
21 1 22 2 2 2
1 1 2 2
+ + + =
+ + + =
- - - - - - - - - - - - - - -
+ + + =

(3.1)
sau matriceal
AX=B (3.2)
unde: A=
a a a
a a a
a a a
11 12
21 22
1 2
...
...
...
1n
2n
n n nn
- - - -

(3.3)
ndrumar de laborator pentru Metode Numerice 44
X=
x
x
x
x
1
2
3
M
n

(3.4) i B=
b
b
b
b
1
2
3
M
n

(3.5)
Metodele de rezolvare a sistemelor liniare le putem mpri n dou categorii:
metode directe care presupun un numr finit de operaii i metode indirecte care
implic un numr infinit de operaii.
2.1.1. METODE DIRECTE
Aceste metode sunt caracterizate prin aceea c pot oferi soluia exact a sistemului
de rezolvat, i dac sunt ndeplinite condiiile de existen. Soluia oferit nu cuprinde
dect erorile proprii operaiilor aritmetice, demonstrate cu ajutorul grafurilor de
procedur n prima lucrare de laborator, mpreun cu erorile de rotunjire i trunchiere
interne, d.p.d.v. al reprezentrii interne n virgul mobil.
Dintre metodele directe prezentm metoda pentru sisteme superior i inferior
triunghiulare, metoda eliminrii a lui Gauss, metoda lui Crout, metoda QR i metoda
de rezolvare a sistemelor tridiagonale.
2.1.1.1 SISTEME SUPERIOR TRIUNGHIULARE
Sistemele de tipul superior triunghiular sunt de forma:
11 1 12 2 13 3 1 1
22 2 21 2 2 2
33 3 3 3
a x a x a x a x b
a x a x a x b
a x a x b
a x b
n n
n n
n n
nn n n
+ + + + =
+ + + =
+ + =
=

...
...
...
.................................
(3.6)
Calculul soluiilor sistemului se face printr-o retro-substituie astfel:
n
n
nn
x
b
a
= i
i
i ij
j i
n
j
ii
x
b a x
a
=
-
= +

1
i=n-1, n-2, ,1 (3.7)
Lucrarea 3 45
2.1.1.1.1. Algoritmul 3.1. Sistem superior triunghiular
real Superior_Triunghiular
(
ntreg n, // ordinul sistemului
real A[N][N], // matricea necunoscutelor sistemului
real B[N], // vectorul termenilor liberi
real X[N] // vectorul soluiilor
)
{
// declararea i definirea variabilelor locale
real d; // reine valoarea determinantului
ntreg i, j; // indici pentru ciclurile for() i pentru
// indexarea vectorilor.
// corpul de instruciuni al funciei
d=1;
pentru i=
n , 1 d = d*A[i][i];
dac(d == 0) return 0;
pentru i= 1 , n
{
x[i] = b[i];
pentru j= 1 , + i n x[i] = x[i] - A[i][j]*x[j];
x[i] = x[i]/A[i][i];
}
returneaz d;
// se poate returna valoarea determinantului, deoarece
// forma particular a sistemului permite calcularea cu
// uurin a acestuia.
}
2.1.1.2. METODA LUI GAUSS DE ELIMINARE
Aceast metod const n realizarea unui sistem triunghiular prin eliminarea
termenilor de sub diagonala principal, sistemul (3.1). Pentru aceasta se analizeaz toi
termenii a
k1
, k=1,...,n , i ecuaia care are valoarea maxim a acestui coeficient este
adus pe primul loc. Dac toi a
k1
=0 pentru k=1,...,n sistemul este incompatibil. Prima
ecuaie a sistemului dup reordonare se nmulete pe rnd cu factorul :
m
a
a
k
k
1
1
11
= , k=2, ... ,n (3.8)
i se scade din ecuaia de pe poziia k, obinnd pe coloana 1 toi termenii zero n afar
de a
11
. Procedeul continu cu linia i coloana a doua, prima linie i prima coloan
rmnnd neschimbate. Ultimul index de linie pentru care se aplic acest procedeu este
n-1.
ndrumar de laborator pentru Metode Numerice 46
2.1.1.2.1. Algoritm 3.2. Metoda lui Gauss de eliminare
real Gauss
(
ntreg n, // ordinul sistemului
real A[ ][N], // matricea sistemului
real B[ ], // vectorul termenilor liberi
real *X // vectorul soluiilor.
)
{ // declaraiile i definiiile variabilelor locale
ntreg i; // indicele liniei
ntreg k; // indice suplimentar al liniei
ntreg j; // indice coloan
real m; // multiplicator
real d; // determinantul sistemului
real max; // elementul maxim de pe coloana coeficienilor
real lp; // indicele liniei cu element maxim
// corpul de instruciuni al funciei
d=1; // iniializarea cu 1 a variabilei n care in valoarea
// determinantului.
pentru i =
1 , 1 - n
{ // for 1 .
max = fabs(A[i][i]);
lp = i; // linia ce conine coeficientul maxim.
pentru k = n i , 1 + { // for 2 .
dac (fabs(A[k][i])>max ) { max = fabs(A[k][i]);
lp = k;
}
} // for 2
dac (max == 0) returneaz 0;
dac (i != lp){ // n caz ca linia ce conine coeficientul maxim
// este diferit de prima linie, se face
// interschimbarea.
pentru j = n i, Schimb(A[i][j], A[lp][j]);
// interschimbarea coeficienilor necunoscutelor
// de pe linia i cu cei de pe linia lp.
Schimb(B[i], B[lp]); // schimbarea ntre ei a
// termenilor liberi.
d = -d;
// odat cu schimbarea a dou linii ntr-un determinant,
// valoarea sa i schimb semnul.
}
pentru k = n i , 1 + {
m = A[k][i]/A[i][i];
pentru j = n i , A[k][j] = A[k][j] - m*A[i][j];
B[k] = B[k] - m*B[i];
}
} // for 1.
// Rezolv sistem superior triunghiular.
dac (A[n][n] = = 0) returneaz 0;
pentru i = n , 1 d = d*A[i][i]; // Calculeaz determinantul
pentru i = 1 , n {
x[i] = B[i];
pentru j = 1 , + i n x[i] = x[i] - A[i][j]*x[j];
x[i] = x[i] / A[i][i];
}
returneaz d; // odat calculat, valoarea determinantului poate
// fi returnat de ctre funcie.
}
Lucrarea 3 47
Obs.: Operaia de interschimbare a coeficienilor necunoscutelor de pe dou linii
distincte se poate face fie prin intermediul unei funcii macro (definit cu ajutorul
directivei #define - vedei i Anexa B - "Noiuni de C necesare desfurrii lucrrilor
de laborator") fie printr-o funcie propriu-zis, avnd argumente referin.
2.1.1.3. METODA LUI CROUT
Rezolvarea sistemului AX=B const n descompunerea matricei A sub forma:
A=LU
L fiind o matrice inferior triunghiular, iar U o matrice superior triunghiular cu
elementele diagonalei principale egale cu unitatea. Sistemul se scrie:
LUX=B
sau, dac notmUX=Y, atunci:
LY=B
Aadar, rezolvarea sistemului dat revine la rezolvarea sistemului inferior
triunghiular LY=B (determinarea elementelor vectorului coloan Y) apoi la rezolvarea
sistemului superior triunghiular UX=Y, cu determinarea elementelor vectorului
necunoscutelor X (de asemenea vector coloan).
2.1.1.3.1. Algoritm 3.3. Metoda lui Crout
ntreg Crout (
ntreg n, // ordinul sistemului
real A[ ][N], // matricea coeficienilor necunoscutelor sistemului
real B[ ], // vectorul termenilor liberi
real X[ ], // vectorul soluiilor sistemului
real U[ ], // matricea superior triunghiular cu diagonala
// principal unitar
real L[ ], // matricea inferior triunghiular
)
{ // declaraiile i definiiile variabilelor locale
ntreg i, j; // indici de linie, respectiv de coloan
ntreg k, s; // indici suplimentari
real D[N]; // vector suplimentar
real sum, prod; // variabile suplimentare
// corpul de instruciuni al funciei
pentru i = n , 1 U[i][i] = 1;
pentru k = n , 1 { // for k .
pentru i = n k, { // for i
sum = 0;
pentru s= 1 , 1 - k sum = sum + L[i][s] * U[s][k];
L[i][k] = A[i][k] sum;
} // for i .
pentru j = n k , 1 + { // for j .
ndrumar de laborator pentru Metode Numerice 48
sum=0;
pentru s = 1 , 1 - k sum = sum + L[k][s] * U[s][j];
dac (L[k][k]= =0) returneaz False;
U[k][j] = (A[k][j] - sum)/L[k][k];
} // for j .
} // for k .
// Rezolv LY=B
prod = 1;
pentru i= n , 1 prod = prod * L[i][i];
dac (prod ==0) returneaz False;
pentru i=
n , 1
{
D[i]=B[i];
pentru j= 1 , 1 - i D[i] = D[i] - L[i][j] * D[j];
D[I] = D[i]/L[i][i];
}
// Rezolv UX=Y
pentru i= 1 , n {
X[i] = D[i];
pentru j= 1 , + i n X[i] = X[i] - U[i][j] * X[j];
X[i] = X[i]/U[i][i];
}
returneaz True;
}
2.1.1.4. METODA FACTORIZRII QR
Aceast metod face posibil rezolvarea sistemelor AX=B pentru cazul cnd
A R
mxn
i B R
m
, m>n caz n care nu au soluie n general. Soluionarea se face cu
ajutorul metodei lui Householder.
2.1.1.4.1. ALGORITMUL 3.4. Metoda factorizrii QR
void QR
(
ntreg m, // numr de ecuaii;
ntreg n, // numr de necunoscute (m>n) ;
real A[ ][N], // matricea sistemului;
real B[ ], // vectorul termenilor liberi;
real X[ ], // vectorul soluiilor;
real Q[ ], // matricea ortogonal de ordinul m*m;
real R[ ], // matricea superior triunghiular de ordinul
m*n;
)
{// declaraiile i definiiile variabilelor locale
ntreg k, i, j; // indici;
real s, p, t; // variabile suplimentare;
real v [N]; // vector reflector;
// corpul de instruciuni al funciei
Lucrarea 3 49
pentru i= m , 1 {
pentru j= m , 1 Q[i][j] = 0;
Q[i][i] = 1;
}
pentru k=
m , 1
{
s = 0.0;
pentru i= m k, s = s + A[i][k] * A[i][k];
s = sqrt(s);
dac (A[k][k]<0) s = -s;
pentru i= 1 , 1 - k v[i] = 0;
v[k] = A[k]k] + s;
A[k][k] = -s;
pentru i= m k , 1 + {
v[i] = A[i][k];
A[i][k]= 0.0;
}
p = s*v[k];
pentru j= n k , 1 + {
t=0;
pentru i= m k, t = t + v[i] *
A[i][j];
t = t/p;
pentru i= m k, A[i][j] = A[i][j] - t*v[i];
}
t=0;
pentru i= m k, t = t + v[i]*tl[i];
t = t/p;
pentru i= m k, t1[i] = tl[i] t * v[i];
pentru j= m , 1 {
t=0;
pentru i= m k, t = t +
v[i]*Q[i][j];
t = t/p;
pentru i= m k, Q[i][j] = Q[i][j]
- t*v[i];
}
}
pentru i= 1 , n {
s=0;
pentru j= n i , 1 + s = s +
A[i][j]*x[j];
X[i] = (B[i]-s)/A[i][i];
}
pentru i= m , 1
ndrumar de laborator pentru Metode Numerice 50
pentru j= n , 1 R[i][j] = A[i][j];
pentru i= m , 1
pentru j= m , 1 { t = Q[i][j]; Q[i][j] =
Q[j][i]; Q[j][i] = t; }
}
2.1.1.5. METODA DE REZOLVARE A SISTEMELOR TRIDIAGONALE
Un tip special de sisteme liniare l reprezint sistemele tridiagonale:
b c
a b c
a b c
a b c
a b
x
x
x
x
d
d
d
d
d
1 1
2 2 2
3 3 3
1 1 1
1
2
3
1
2
3
0 0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0 0
. ..
. ..
. ..
. ..
. ..
- - - - - - - -

=
-

- - - n n n
n n
n-1
n
n-1
n
x

(3.9)
Metoda simpl de rezolvare a acestor probleme const n descompunerea matricei
tridiagonale n dou matrice L, U .
LU = A (3.10)
Matricele L i U sunt matrice triunghiulare, adic au fie zona de sub diagonala
principal, fie pe cea de deasupra, diferite de zero.
Forma concret a matricelor este (relaia 3.11):
L=
1
2 2
3 3
n-1 n-1
n n
0 0 ... 0 0 0
0 ... 0 0 0
0 ... 0 0 0
0 0 0 ... 0
0 0 0 ... 0
l
p l
p l
p l
p l





- - - - - - -





, U=
1
2
3
n-1
1 0 0 ... 0 0
0 1 0 ... 0 0
0 0 1 ... 0 0
0 0 0 0 ... 1
0 0 0 0 ... 0 1
u
u
u
u





- - - - - - -





(3.11)
Rezolvarea sistemului se face plecnd de la nmulirea matricei L cu matricea U i
apoi prin identificarea cu matricea A a matricei rezultate, element cu element. Se obin
astfel relaiile de recuren pentru calculul elementelor matricelor L i U:
p a i= , ,...,n
u
c
l
i= , , ,...,n
l b
l b a u i= , ,...,n
i i
i
i
i
i i i i-
=
=
=
= -
2 3
12 3
2 3
1 1
1
(3.12)
Sistemul poate fi scris sub forma
LUX=D (3.13)
Lucrarea 3 51
sau sub forma a dou sisteme
L Y=D
U X=Y

(3.14)
Prin identificare se deduc urmtoarele relaii recursive de calcul:
( )
1
1
1
1
; 0
2 3
i
i i i-
i
i
d
y
l
l
d a y
y , i = , ,...n
l

(3.15)
i

- =
=
+
1 1
1
,..., i=n- , x u y x
y x
i i i i
n n
(3.16)
care reprezint soluiile sistemului tridiagonal.
2.1.1.5.1. Algoritm 3.5. Sisteme Tridiagonale
ntreg Tridiagonal
(
ntreg n, // ordinul sistemului;
real a[ ], // vectorul elementelor sub-diagonle din
// matricea sistemului;
real b[ ],// vectorul elementelor diagonale din matricea
// sistemului;
real c[ ], // vectorul elementelor supra-diagonale din
// matricea sistemului;
real d[ ], // vectorul termenilor liberi;
real x[ ] // vectorul soluiilor
)
{
// declaraiile i definiiile variabilelor locale
real t[N+1]; // vectorul elementelor diagonale din L;
real p[N+1]; // vectorul elementelor sub-diagonale din L;
real s[N]; // vectorul elementelor supra-diagonale din
// matricea U
real y[N+1]; // vectorul UX;
ntreg i, j; // indici pentru ciclurile for() i indexarea
// vectorilor
// corpul de instruciuni al funciei
pentru i= n , 2 p[i] = a[i];
t[1] = b[1];
dac (t[1]= =0) returneaz False;
s[1] = c[1]/t[1];
y[1] = d[1]/t[1];
pentru i= 1 , 2 - n {
t[i] = b[i] - a[i]*s[i-1];
dac (t[i] = = 0) returneaz False;
s[i] = c[i] / t[i];
ndrumar de laborator pentru Metode Numerice 52
y[i] = (d[i] - a[i]*y[i-1]) / t[i];
}
t[n] = b[n] - a[n]*s[n-1];
dac (t[n]= =0) returneaz False;
x[n] = (d[n] - a[n]*y[n-1])/t[n];
pentru i= 1 , 1 - n X[i] = Y[i] - s[i]*X[i+1];
returneaz True;
}
2.1.2. METODE INDIRECTE
Dintre metodele indirecte sau metodele iterative care rezolv un sistem de ecuaii
liniare prezentmmetoda lui Jacobi.
2.1.2.1. METODA LUI JACOBI
Fie sistemul liniar (3.1). Se expliciteaz fiecare necunoscut din sistem de pe
diagonala principal funcie de celelalte necunoscute ale sistemului .

- - - =
- - - - =
- - - - - =
+ x
a
a
... x
a
a
a
b
x
---------- ---------- ----------
x
a
a
... x
a
a
x
a
a
a
b
x
x
a
a
... x
a
a
x
a
a
a
b
x
n-
nn
nn-
nn
n
nn
n
n
n
n
n
n
0
0
0
1
1
1
2
22
2
3
22
23
1
22
21
22
2
2
11
1
3
11
13
2
11
12
11
1
1
(3.17)
Se alege o soluie a sistemului oarecare
( ) ( ) ( )
x ,x ,...,x ,
n 1
0
2
0 0
ce va reprezenta soluia de
start, dup care se continu iteraiile, pn cnd dou soluii succesive difer cu mai
puin de o eroare impus (precizia impus).
2.1.2.1.1. Algoritm 3.6. Metoda Jacobi
#define N 16 // presupunem c gradul sistemului nu depete 15
ntreg Jacobi
(
ntreg n, // ordinul sistemului;
real A[ ][N], // matricea sistemului;
real B[ ], // vectorul termenilor liberi;
real X[ ] // vectorul de start la intrare, soluia la
ieire
)
{
// declaraiile i definiiile variabilelor locale
Lucrarea 3 53
ntreg i, j; // indici;
real sum; // variabil auxiliar;
real Xn[N], Xn1[N]; // soluiile la pasul curent i precedent
ntreg sem; // variabil logic auxiliar;
// Verific dac matricea e dominant-diagonal
pentru i= n , 1 {
sum = 0;
pentru j= n , 1 sum = sum + fabs(A[i][j]);
dac (sum > 2*fabs(A[i][i])) returneaz False;
}
// Iteraiile efective ale metodei
pentru i= n , 1 Xn[i] = X[i];
// se pornete n calcule cu valorile coninute de vectorul de
// start (rolul vectorului de start este inut de ctre
// vectorul X)
execut
{
sem = True;
pentru i= n , 1 Xn_1[i] = Xn[i];
pentru i= n , 1
{
Xn[i] = B[i];
pentru j= n , 1
dac (j != i) Xn[i] = Xn[i] - A[i][j] * Xn_1[j];
Xn[i] = Xn[i]/A[i][i];
}
pentru i= n , 1
dac (fabs(Xn[i]-Xn_1[i]) > eps ) sem = False;
} ct timp (sem = = False);
pentru i= n , 1 X[i] = Xn[i];
returneaz True;
}
2.1.2.2. METODA GAUSS-SEIDEL
Are acelai principiu cu cel al metodei Jacobi, ns prezint o difereniere major:
pentru calculul necunoscutelor la pasul curent, se folosesc, acolo unde este posibil, i
valorile necunoscutelor calculate chiar la acest pas, i nu n exclusivitate toate valorile
de la pasul anterior.
Nu aceeai este situaia n metoda Jacobi. Dup cum s-a prezentat, soluia la pasul
n se bazeaz n ntregime pe valorile de la pasul n-1, i nu folosete nici un calcul de la
pasul n.
n consecin, metoda Gauss-Seidel prezint un avantaj incontestabil: viteza mrit
de convergen, i aceasta pentru c, de exemplu, componenta a treia de la pasul n este
aceeai cu cea de la pasul n+1 din Jacobi. Deci valorile calculate n Gauss-Seidel sunt
'naintea' celor din Jacobi, i aceasta din cauza modului n care sunt calculate.
ndrumar de laborator pentru Metode Numerice 54
2.1.2.2.1. Algoritmul metodei Gauss-Seidel
definete tipul de dat LOGIC; // tipul Boolean nu este
// definit n ANSI C
definete constantele False i True; // eventual cu o enumerare
intreg GaussSeidel
(
intreg n, // ordinul sistemului
real a[][DIM], // matricea sistemului
real b[DIM], // vectorul termenilor liberi
real x[DIM], // vectorul soluie; la intrare este vector de
// start
real epsilon // precizia impusa solutiilor
)
{
// corpul funciei
intreg i, j, pas=1;
LOGIC stop, marker[DIM]; // marker este vectorul in care
// marchez care componente au fost
// calculate la pasul curent.
real sum; // pentru verif dominant-diagonalitatii
real xn[DIM], xn1[DIM]; // componentele curent si anterior
real eroare[DIM]; // vectorul erorilor componentelor
real valFolosita; // pt depanare.
// Testul de dominant-diagonalitate al matricei de intrare;
// in caz de eroare se iese cu False
for i = 0,n
{
suma = 0; // inainte de fiecare suma, variabila suma devine
// zero
for j = 0,n
{
suma = suma + absolut(a[i][j]);
daca (2*absolut(a[i][i]) < suma) returneaza False;
// Structura matricei nu permite rezolvarea sist...
}
}
// iteratiile asociate calculului solutiilor sistemului
execut
{
for i = 0,n
{
xn1[i] = xn[i]; // comp curente devin anterioare;
marker[i] = False; // reset marker pt pasul curent
}
// se calc comp la pasul curent
stop = True;
for i = 0, n
{
xn[i] = b[i];// se ncepe calculul componentelor
// curente de la term liber.
// Pentru calculul comp curente se ine cont de
// valorile logice memorate ntr-un vector de
// markeri
Lucrarea 3 55
for j = 0,n
{
daca (marker[j] == 0) valFolosita = xn1[j];
else valFolosita = xn[j];
dac (j != i) xn[i] = xn[i] - a[i][j]*valFolosita;
}
xn[i] = xn[i]/a[i][i]; // s-a ncheiat calc comp
curente
marker[i] = True; // si se marcheaza acest lucru
}
for i = 0,n
{
eroare[i] = fabs(xn[i] - xn1[i]);
dac (eroare[i] > epsilon) stop = False;
}
} ct timp (stop este False);
// stabilirea vectorului soluie i marcarea succesului la ieire
for i = 0,n
x[i] = xn[i]; // se considera solutie ultimele valori
calculate
returneaz True;
}
2.2. REZOLVAREA NUMERIC A SISTEMELOR
NELINIARE
Se numete sistem neliniar acel sistem pentru conine cel puin o ecuaie avnd
gradul peste 1, din punctul de vedere al necunoscutelor.
Sistemul se prezint astfel:
( )
( )
( )
f x ,x ,...,x
f x ,x ,...,x
---------------
f x ,x ,...,x
n
n
n n
1 1 2
2 1 2
1 2
0
0
0
=
=
=

(3.18)
Dac cel puin una din funciile f f f f
n 1 2 3
, , . .. sunt neliniare n variabilele
x ,x ,...,x
n 1 2
sistemul de ecuaii (3.18) se numete sistem de ecuaii neliniare.
2.2.1. METODA LUI NEWTON DE REZOLVARE A
ECUAIILOR NELINIARE
2.2.1.1. Algoritm 3.7. Metoda lui Newton
Prezentm n cele ce urmeaz aplicarea metodei Newton-Raphson pentru
rezolvarea unui sistem neliniar cu dou ecuaii i dou necunoscute. Generalizarea este
imediat.
ndrumar de laborator pentru Metode Numerice 56
ntreg Sis_Newton_Raphson
(
Adr(f1), // adresa primei funcii de dou variabile care
// formeaz sistemul (pointer la o funcie);
Adr(f2), // adresa celei de-a doua funcii de dou
// variabile care formeaz sistemul (pointer la o
// funcie);
Adr(dxf1),
Adr(dxf2), // Adresele derivatelor celor dou funcii n
// raport cu prima variabil (pointeri la
// funcie);
Adr(dyf1),
Adr(dyf2), // Adresele derivatelor celor dou funcii n
// raport cu a doua variabil (pointeri la
// funcie);
real *solx, // la intrare: soluia de start pentru prima
// variabil la ieire: soluia final a primei
// variabile;
real *soly, // la intrare: soluia de start pentru a doua
// variabil la ieire: soluia final a celei
de-
// a doua variabile;
real eps, // eroarea de calcul;
ntreg niter // numrul maxim de iteraii .
)
{
// declaraiile i definiiile variabilelor locale
real xn, xn_1; // pasul curent i precedent al variabilei x;
real yn, yn_1; // pasul curent i precedent al variabilei y;
real dx, dy; // variaiile celor dou variabile;
// corpul de instruciuni al funciei
xn = *solx;
yn = *soly;
execut
{
xn_1 = xn; yn_1 = yn;
dac ((*Adr(dxf1))(xn_1,yn_1) * (*Adr(dyf2))(xn_1,yn_1)
(*Adr(dxf2))(xn_1,yn_1) * (*Adr(dyf1))(xn_1,yn_1)
= = 0 )
returneaz False;
dx = (-(*Adr(f1))(xn_1,yn_1) * (*Adr(dyf2))(xn_1,yn_1)
+ (*Adr(f2))(xn_1,yn_1) * (*Adr(dyf1))(xn_1,yn_1) )
/ ((*Adr(dxf1))(xn_1,yn_1) * (*Adr(dyf2))(xn_1,yn_1)
- (*Adr(dxf2))(xn_1,yn_1) * (*Adr(dyf1))(xn_1,yn_1) );
dy = (- (*(Adr(dxf1))(xn_1,yn_1)*(*Adr(f2))(xn_1,yn_1)
+ (*Adr(dxf2))(xn_1,yn_1) * (*Adr(f1))(xn_1,yn_1))
/ ((*Adr(dxf1))(xn_1,yn_1) * (*Adr(dyf2))(xn_1,yn_1)
- (*Adr(dxf2))(xn_1,yn_1) * (*Adr(dyf1))(xn_1,yn_1));
niter = niter-1;
xn=xn_1+dx;
yn=yn_1+dy;
} ct timp( ((fabs(dx) >= eps) SAU (fabs(dy) >= eps))
I (niter >0) );
dac (niter = = 0) returneaz False;
*solx = xn;
*soly = yn;
returneaz True;
}
Lucrarea 3 57
Obs.: Notaiile Adr(f
i
) i (*Adr(f)) sunt simbolice. Ele reprezint, respectiv, un
pointer la o funcie i apelul unei funcii prin pointer. Vedei Anexa B - Noiuni de C
pentru laborator pentru lmuriri.
2.2.1.2. Implementarea algoritmului 3.7 (paragraful 2.2.1.1.) A metodei lui
newton de rezolvare a sistemelor de ecuaii neliniare
// Varianta unui sistem de trei ecuaii cu trei necunoscute
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define h 0.0001 // pentru calculul derivatei numerice (relaia
// conform definiiei matematice).
// prototipurile funciilor folosite n program.
double ec1(double x,double y,double z); // prima ecuaie a sistemului.
double ec2(double x,double y,double z); // a doua ecuaie a sistemului.
double ec3(double x,double y,double z); // a doua ecuaie a sistemului.
double dec1x(double x,double y,double z);
// derivata prin dou puncte, n raport cu x, a primei ecuaii.
double dec1y(double x,double y,double z);
// derivata prin dou puncte, n raport cu y, a primei ecuaii.
double dec1z(double x, double y, double z);
// derivata prin dou puncte, n raport cu z, a primei ecuaii.
double dec2x(double x,double y,double z);
// derivata prin dou puncte, n raport cu x, a celei de-a doua ecuaii.
double dec2y(double x,double y,double z);
// derivata prin dou puncte, n raport cu y, a celei de-a doua ecuaii.
double dec2z(double x,double y,double z);
// derivata prin dou puncte, n raport cu z, a celei de-a doua ecuaii.
double dec3x(double x,double y,double z);
// derivata prin dou puncte, n raport cu x, a celei de-a treia ecuaii.
double dec3y(double x,double y,double z);
// derivata prin dou puncte, n raport cu y, a celei de-a treia ecuaii.
double dec3z(double x,double y,double z);
// derivata prin dou puncte, n raport cu z, a celei de-a treia ecuaii.
// calculul determinantului unui sistem liniar de trei ecuaii cu trei
// necunoscute, conform regulii lui Sarrus.
double dt3( double a11, double a12, double a13,
double a21, double a22, double a23,
double a31 ,double a32, double a33);
// funcia propriu-zis de determinare a soluiilor sistemului.
int RezSistN(double *x0,double *y0,double *z0,int MAX,double err);
// Programul principal.
void main()
{
double x0,y0,z0,err;
int imax,flag;
clrscr();
ndrumar de laborator pentru Metode Numerice 58
// citirea componentelor vectorului soluiilor de start: (x0, y0, z0).
printf("x0=");scanf("%lf",&x0);
printf("y0=");scanf("%lf",&y0);
printf("z0=");scanf("%lf",&z0);
// citirea erorii de calcul a soluiilor.
printf("err=");scanf("%lf",&err);
// numrul maxim de iteraii.
printf("Nr maxim de iteratii=");scanf("%d",&imax);
// apelul funciei de rezolvare a sistemului neliniar.
flag = RezSistN(&x0,&y0,&z0,imax,err);
if(flag) printf("\nRezultat:\n x=%lf y=%lf z=%lf",x0,y0,z0);
else printf("\nEroare");
getch();
}
// Implementarea funciilor
double ec1(double x,double y,double z) // prima ecuaie a sistemului.
{
// return x+y+z-3;
// return x*x + x*y + 2*z - 3.09;
return x*y + y*y + 2*z - 2.48;
// return x*y + 2*y*y + 2*z - 2.84;
// return x*x + 2*x*y + 2*z - 3.28;
// return x*x + 2*y*x + z - 1.61;
// return x*x + y*y + z*z - 1;
}
double ec2(double x,double y,double z) // a doua ecuaie a sistemului.
{
// return x*x-y+4*z*z-4;
// return x*z + z*y + 4*z - 7.35;
return x + z*y + 3*z - 3.8;
// return x + y*z + z - 1.8;
// return 2*x + y*z + 2*z - 3.;
// return x*z + 3*y*z + z - 4.5;
// return 2*x*y + y*z + z - 2.35;
// return 2*x*x + y*y - 4*z;
}
double ec3(double x,double y,double z) // a treia ecuaie a sistemului.
{// return x*x+y*y*y+2*z-4;
// return x + y*y + z*y - 1.94;
return x + y + z*z - 1.8;
// return x + y + 2*z*z - 2.8;
// return 2*x + y + z*z - 2.;
// return x + y*y + 4*y*z - 4.16;
// return x + y*y + 2*y*z - 1.85;
// return x + y*y + y*z - 1.94;
// return 3*x*x - 4*y + z*z;
}
double dec1x(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu x, a primei ecuaii.
{
return
(ec1(x-2*h,y,z)-8*ec1(x-h,y,z)+8*ec1(x+h,y,z)-ec1(x+2*h,y,z))/(12*h);
}
Lucrarea 3 59
double dec1y(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu y, a primei ecuaii.
return
(ec1(x,y-2*h,z)-8*ec1(x,y-h,z)+8*ec1(x,y+h,z)-ec1(x,y+2*h,z))/(12*h);
}
double dec1z(double x, double y, double z)
{
// derivata prin dou puncte, n
// raport cu z, a primei ecuaii.
return
(ec1(x,y,z-2*h)-8*ec1(x,y,z-h)+8*ec1(x,y,z+h)-ec1(x,y,z+2*h))/(12*h);
}
double dec2x(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu x, a celei de-a doua ecuaii.
return
(ec2(x-2*h,y,z)-8*ec2(x-h,y,z)+8*ec2(x+h,y,z)-ec2(x+2*h,y,z))/(12*h);
}
double dec2y(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu y, a celei de-a doua ecuaii.
return
(ec2(x,y-2*h,z)-8*ec2(x,y-h,z)+8*ec2(x,y+h,z)-ec2(x,y+2*h,z))/(12*h);
}
double dec2z(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu z, a celei de-a doua ecuaii.
return
(ec2(x,y,z-2*h)-8*ec2(x,y,z-h)+8*ec2(x,y,z+h)-ec2(x,y,z+2*h))/(12*h);
}
double dec3x(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu x, a celei de-a treia ecuaii.
return
(ec3(x-2*h,y,z)-8*ec3(x-h,y,z)+8*ec3(x+h,y,z)-ec3(x+2*h,y,z))/(12*h);
}
double dec3y(double x,double y,double z)
{
// derivata prin dou puncte, n raport cu y, a celei de-a treia
// ecuaii.
return
(ec3(x,y-2*h,z)-8*ec3(x,y-h,z)+8*ec3(x,y+h,z)-ec3(x,y+2*h,z))/(12*h);
}
double dec3z(double x,double y,double z)
{
// derivata prin dou puncte, n
// raport cu z, a celei de-a treia ecuaii.
{
return
(ec3(x,y,z-2*h)-8*ec3(x,y,z-h)+8*ec3(x,y,z+h)-ec3(x,y,z+2*h))/(12*h);
}
ndrumar de laborator pentru Metode Numerice 60
double dt3( double a11, double a12, double a13,
double a21, double a22, double a23,
double a31, double a32, double a33){
return a11*a22*a33+a21*a32*a13+a12*a23*a31-
a31*a22*a13-a21*a12*a33-a11*a32*a23;
}
int RezSistN(double *x0,double *y0,double *z0,int MAX,double err)
{
int i;
double dx,dy,dz,det,detx,dety,detz,xn1,yn1,zn1,xn,yn,zn;
i=0;
xn=*x0;yn=*y0;zn=*z0;
do{
xn1=xn;yn1=yn;zn1=zn;
det= dt3(dec1x(xn1,yn1,zn1),dec1y(xn1,yn1,zn1),dec1z(xn1,yn1,zn1),
dec2x(xn1,yn1,zn1),dec2y(xn1,yn1,zn1),dec2z(xn1,yn1,zn1),
dec3x(xn1,yn1,zn1),dec3y(xn1,yn1,zn1),dec3z(xn1,yn1,zn1));
detx=dt3(-ec1(xn1,yn1,zn1),dec1y(xn1,yn1,zn1),dec1z(xn1,yn1,zn1),
-ec2(xn1,yn1,zn1),dec2y(xn1,yn1,zn1),dec2z(xn1,yn1,zn1),
-ec3(xn1,yn1,zn1),dec3y(xn1,yn1,zn1),dec3z(xn1,yn1,zn1));
dety=dt3(dec1x(xn1,yn1,zn1),-ec1(xn1,yn1,zn1),dec1z(xn1,yn1,zn1),
dec2x(xn1,yn1,zn1),-ec2(xn1,yn1,zn1),dec2z(xn1,yn1,zn1),
dec3x(xn1,yn1,zn1),-ec3(xn1,yn1,zn1),dec3z(xn1,yn1,zn1));
detz=dt3(dec1x(xn1,yn1,zn1),dec1y(xn1,yn1,zn1),-ec1(xn1,yn1,zn1),
dec2x(xn1,yn1,zn1),dec2y(xn1,yn1,zn1),-ec2(xn1,yn1,zn1),
dec3x(xn1,yn1,zn1),dec3y(xn1,yn1,zn1),-ec3(xn1,yn1,zn1));
if(det==0) return 0;
dx=detx/det;dy=dety/det;dz=detz/det;
// aplicarea relaiilor lui Cramer pentru determinarea soluiilor
// sistemului liniar n necunoscutele dx, dy i dz.
xn=xn1+dx;yn=yn1+dy;zn=zn1+dz;printf("\n");
printf("%lf\t",xn);printf("%lf\t",yn);printf("%lf",zn);
i++; // contorizarea numrului de iteraii.
}
while(((fabs(xn-xn1)>err)||(fabs(yn-yn1)>err)
||(fabs(zn-zn1)>err))&&(i<=MAX));
if(i>=MAX) return 0;
*x0=xn;*y0=yn;*z0=zn;
return 1;
}
3. DESFURAREA LUCRRII
3.1. PROBLEME LABORATOR
1. S se implementeze algoritmii 3.1-3.7 n limbajul C.
2. Se d circuitul electric din figura 3.1 ce are urmtoarele componente:
1 2 3 4
5 6 7 8
1 2 3
24 36 15 1
18 2 7 12 3
10 12 15
R R R R
R R R R
E E E
k k k k
k k k k
V V V
= = = =
= = = =
= = =
. , . , . , ,
. , . , . , ,
, ,
W W W W
W W W W
Lucrarea 3 61
Se cer curenii prin fiecare latur a circuitului.
3. Se consider sistemul:
4 4 04 07 32
023 54 15 01 2 7
13 034 62 0 3 14
03 14 034 2 8 21
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
. . . .
. . . . .
. . . . .
. . . . .
x x x x
x x x x
x x x x
x x x x
- + + =
+ - + =
+ + - =
+ - + =
S se determine soluiile sistemului cu ajutorul metodelor care au fost
programate ntr-un limbaj de nivel nalt.
4. Modificnd programul scris pentru tei ecuaii cu trei necunoscute, s se
rezolve sistemul:
x xy
xy y
2
2
305
324
+ =
+ =
.
.
lund vectorul de start (1,1).
5. S se rezolve urmtorul sistem neliniar folosind algoritmul general de rezolvare
a ecuaiilor neliniare (paragraful 2.2.1.2.1), afindu-se vectorul soluiilor i
eroarea de calcul corespunztoare fiecrei componente, dup trei pai de
iteraie:
8 . 1
8 . 3 3
48 . 2 2
2
2
= + +
= + +
= + +
z y x
z z y x
z y y x
Se va considera vectorul de start: (0.4, -0.3, 0.6). Comentai valabilitatea
alegerii acestui vector de start.
6. S se rezolve prin metoda lui Jacobi i prin metoda Gauss-Seidel urmtorul
sistem:
5x + y + z = 4
x + 2y + 8z = 8
3x +10 y + z = 9
Comparai viteza de calcul (prin numrul iteraiilor) i rezultatele. Comparai
rezultatele dup iteraia a 4-a . Se consider vectorul de start X
0
= (1,1,1).
ndrumar de laborator pentru Metode Numerice 62
3.2. TEME DE CAS
1. Se consider circuitul de mai jos. S se determine curenii prin fiecare latur.
Se dau:
R
1
= 1 k, R
2
= 5.6 k,, R
3
= 3.6 k, R
4
= 10 k, R
5
= 3 k,
R
6
= 7.5 k, R
7
= 8.2 k, R
8
= 12 k, R
9
= 4.7 k.
V
1
= 5V; V
2
= 9V, V
3
= 12V.
2. Se consider sistemul liniar ptratic:
5x + y + z = 1
x + y + 4z = 1.5
x + 6y + z = 1.6
S se rezolve prin metoda lui Jacobi i Gauss-Seidel. Vectorul de start este:
(1,1,1). Ce alt vector de start se poate alege?
3. S se rezolve sistemele neliniare urmtoare, prin metoda iterativ a lui
Newton:
a.

= - -
= - + + +
0 1
36 . 0
5 . 1
0 6 . 1 ) 4 . 0 cos(
2
2
2 2 2
y
x
y x x y
,
cu valorile de start: x
0
=1.04, y
0
=0.47.
b.

= + +
+ - =
7 . 0 ) 5 . 0 (
1 . 1
2 2
2
y x
y x e
y
x
Se consider valori de start: x
0
=0.1, y
0
=0.1.
BIBLIOGRAFIE
1. RUSU Metode numerice n electronic. Aplicaii n limbaj C, Editura Tehnic,
Bucureti, 1997
2. N.V. Kopchenova, I.A. Maron - "Computational Mathematics - worked examples
and problems with elements of theory", Ed. Mir Publisher Moscow, 1975.

S-ar putea să vă placă și