Sunteți pe pagina 1din 44

Ministerul Educaţiei, Culturii şi

Cercetării al Republicii Moldova

Universitatea Tehnică a Moldovei

Departamentul Informatică și

Ingineria Sistemelor

RAPORT
despre lucrările de laborator
nr.3 și nr.4
la Metode Numerice
Tema: Rezolvarea
numerică a sistemelor
de ecuații liniare

Varianta 7

A îndeplinit: st.gr. CR-221fr, Ciobanu Stanislav

A controlat: conf.univ., Seiciuc V.

Chişinău, 2023
Scopul lucrărilor
1) Să se rezolve sistemul de ecuații liniare Ax=b, utilizând:
 Metoda eliminării lui Gauss
 Metoda lui Cholesky (metoda rădăcinii pătrate)

 Metoda iterativă a lui Jacobi cu o eroare ε =10−3

 Metoda iterativă a lui Gauss-Seidel cu o eroare ε =10−3 şi ε =10−5

2) Să se determine numărul de iteraţii necesare pentru aproximarea soluţiei sistemului cu


eroarea dată ε și să se compare rezultatele.
Realizarea lucrărilor
Conform variantei mele, cu numărul 7, am următoarele probleme (sistem de ecuații
liniare) date spre rezolvare:

( )( )
6.1 −1.9 0.4 0.2 7.1
−1.9 14.3 1.8 1.4 10.2
A= b=
0.4 1.8 12.7 −0.6 −7.2
0.2 1.4 −0.6 13.1 8.6

În prima parte a sarcinii, care este mai mult teoretică, se cere de descris descris metodele
utilizate, astfel metodele numerice de rezolvare a sistemelor de ecuaţii lineare sunt de două tipuri:
metode directe şi metode iterative. Metodele directe constau în transformarea sistemului Ax=b
într-un sistem echivalent pentru care rezolvarea este cu mult mai simplă. În metodele directe soluţia
exactă se obţine după un număr finit de operaţii aritmetice elementare (adunare, scădere, înmulţire,
împărţire şi rădăcina pătrată) şi acest număr de operaţii este de ordinul n3 . Subliniem că soluţia exactă
se obţine în cazurile (ideale) în care erorile de rotunjire sunt absente. La fiecare operaţie elementară
efectuată de calculator avem o eroare de rotunjire şi prin urmare erorile directe în caz general
furnizează doar o soluţie aproximativă. Metodele directe se utilizează pentru rezolvarea sistemelor nu
prea “mari”, de dimensiune n=200.
Rezolvarea sistemelor de ecuaţii lineare printr-o metodă iterativă înseamnă construirea unui
şir de vectori x(k) , k =0 , 1, 2 , … (pornind de la un vector x(0) ales arbitrar) convergent către soluția
sistemului considerat. În metodele iterative, de obicei, o iterație necesită efectuarea unui număr de
ordinea n2 operații aritmetice. De aceea metodele iterative se utilizează pentru rezolvarea sistemelor
“mari”, de dimensiune n>100 (în cazul asigurării unei viteze sporite de convergenţă pentru o alegere
a aproximării iniţiale adecvate). Trunchierea şirului {x ( k ) } are loc la un indice m , astfel încât x (m )
constituie o aproximaţie satisfăcătoare a soluţiei căutate x ¿(de exemplu, |x (m )−x ¿|< ε , unde ε > 0 este
eroarea admisă).
Metoda eliminării a lui Gauss constă în a aduce sistemul iniţial la un sistem echivalent
avînd matricea coeficienţilor superior triunghiulară. Transformarea sistemului dat într-un sistem de
formă triunghiulară fără ca să se modifice soluţia sistemului se realizează cu ajutorul a trei operaţii de
bază. Prima este rearanjarea ecuaţiilor (schimbarea a două ecuaţii între ele), a doua este înmulţirea
unei ecuaţii cu o constantă (diferită de zero), iar a treia este scăderea unei ecuaţii din alta şi înlocuirea
celei de-a doua cu rezultatul scăderii. Fie dat sistemul nostru de ecuaţii lineare din condiție Ax=b,
unde A=( aij )n x, b ∈ R n, detA ≠ 0. Să presupunem că a 11 ≠ 0 ; dacă a 11 ≠ 0 se aduce elementul nenul
din prima coloană pe locul (1 , 1), permutând ecuațiile respective ale sistemului. Primul pas constă
în eliminarea necunoscutei x 1 din ecuaţiile sistemului începînd cu a doua, multiplicînd ecuaţia
αi1
întîia cu raportul μi 1= , i=2 , 3 , … , n şi scăzînd rezultatul obţinut din ecuaţia i pentru ∀ i≥ 2.
α 11
Obţinem în acest fel sistemul echivalent A(2) x=b(2) , cu coeficienții:
(2) (1)
α 1 j =α 1 j , j=1 , 2 ,… ,n ;
(2)
α i 1 =0 , i=2 , 3 , … , n;
(2) (1) ( 1)
α ij =α ij ∗μ i1∗α 1 j , i, j=2, 3 , … , n ;
(2) (1) (2) (1) (1 )
b 1 =b 1 ,b i =bi −μ i 1∗b1 , i=2 , 3 , … , n;
(1) (1)
Mai sus s-a notat α ij =a ij; i , j=1 ,2 , … , n și b i =b i; i=1 , 2 ,… , n . Prima ecuaţie a
sistemului echivalent coincide cu prima ecuaţie a sistemului dat inițial. În continuare se repetă
procedeul de mai sus pentru eliminarea necunoscutei x 2 din sistemul echivalent ş.a.m.d. La
pasul k se obţine sistemul A(k) x=b(k), unde:

( )( )
(1 ) (1 ) ( 1) (1 ) ( 1) (1 )
α 11 α 12 K α 1 , k−1 α 1k K α 1n b1
(2 ) ( 2) (2 ) (2 ) (2 )
0 α 22 K α 2 , k−1 α 2k K α2 n b2
(k) ( k−1 ) ( k−1) (k)
A = 0 0 α k−1 ,k−1 k−1
( )
¿ α k−1, k K α k−1 ,n b = bk−1(k−1 )
( k) (k ) (k )
0 0 0 ¿ α kk K α kn bk
0 0 0 ¿ α nk
(k )
K α nn
( k)
bn
(k )

Elementele α ij(k) ale lui A(k) și b i(k) ale lui b(k) se calculează recursiv prin formulele:

{
α ij(k−1) ,i ≤ k−1
(k)
α ij = 0 ,i ≥ k , k ≤ k −1
α ij(k−1)
−μi , k∗α k−1(k −1 ) , i≥ k , j≥ k

α i ,k−1(k−1)
unde μi , k−1= ,
α k−1 , k−1(k−1)

{
(k−1)
(k) bi , pentru ∀ i ≤ k−1
iar b i = (k−1) ( k−1)
b i −μi , k−1∗b k−1 , pentru ∀ i≥ k

După n paşi necunoscuta x n−1 va fi eliminată din ultima ecuaţie, obţinându-se un sistem cu
matricea superior triunghiulară:

{
(1) (1) (1 )
a 11 x 1+ a12 x 2 +…+ a1 k (1 ) x k +…+ a1 n(1) x n=b1
(2) ( 2) (2 ) (2)
a22 x 2+ …+a2 k x k +…+ a2 n x n=b 2
……………………… ………………………………………… ………
( ) ( ) (k)
akk k x k + …+a kn k x n=b k
……………………… ………………………………………… ………
(n)
a nn( n) x n =bn

Acest sistem se rezolvă începînd cu ultima ecuaţie cu ajutorul procesului de eliminare inversă
care se poate descrie astfel:
n

x n=
bn
( n)

; x n−1=
bn−1
( n−1 )
−an−1 , n
( n−1)
∗x n
;
b k( k )− ∑ akj( k )∗x j
;
j=k+1
α nn( n) α n−1, n−1(n−1) xk= (k )
α kk

Metoda lui Gauss prezentată mai sus presupune că elementele pivot trebuie să fie diferite de
zero. Dacă la efectuarea pasului k elementul a kk =0 atunci cel puţin unul din celelalte elemente din
coloana k şi din liniile k +1 , k +2 , … , n este nenul; în caz contrar matricea A ar fi singulară (detA =0
). Permutând ecuaţiile sistemului putem aduce pe locul (k , k ) elementul nenul şi, deci, este posibil să
reluăm eliminarea. Dacă un element pivot este exact egal cu zero, din motive de stabilitate numerică,
trebuie să efectuăm rearanjarea ecuaţiilor. Am realizat subrutina (subprogramul/funcția sau
procedura) cu numele GAUSS de calcul care realizează metoda realizării lui Gauss cu pivotarea
parţială: la pasul k pivotul se ia egal cu primul element maxim în modul din coloanak subdiagonală a
(k)
lui A , conform formulei
|ark |=max|aik |, k ≤ i≤ n. şi se permută liniile k şi r .
(k ) ( k)

Metoda lui Cholesky de rezolvare a sistemelor de ecuaţii liniare se mai numeşte


metoda rădăcinii pătrate şi constă în descompunerea sistemului Ax=b în sistemele
triunghiulare LT y=b și Lx= y . Matricea L se alege astfel, încît A=LT∗L . Elementele l ij ale
matricei inferior triunghiulare L pot fi calculate în felul următor, se determină prima coloană a
ai 1
matricei L care este L11= √ a11, l i 1= , i=2 , 3 , … , n. După ce s-au obţinut primele (k −1)
l 11
coloane ale matricei L, se calculează coloana k , conform formulelor:
k−1
(aik −∑ l ij∗l kj )

k−1
l kk = akk −∑ l kj2 ; l ik = j=1
; i=k +1 , … , n
j=1 l kk

În această metodă se presupune că matricea A este o matrice simetrică şi pozitiv definită.


Metodele iterative de rezolvare a sistemelor de ecuaţii liniare se construiesc utilizând
desfacerea matricei A definită prin A=S−T . Atunci sistemul Ax=b este bivalent cu sistemul
Sx=Tx+ b sau x=Qx+ d , unde Q=S−1∗T și d=S−1∗b . Prin urmare putem construi șirul {x (k) } ,
utilizând relația recurentă S∗x (k+1 )=T∗x (k )+ b, k =0 , 1 ,2 , … , sau x (k +1)=Q∗x (k )+ d , unde x (0 ) ∈ R n
este o aproximaţie iniţială a soluţiei x ¿. Pentru a reduce sistemul Ax=b la o formă Sx=Tx+ b
sau x=Qx+ d , potrivită pentru iteraţie, desfacerea matricei A trebuie să satisfacă două condiţii.
Prima este ca sistemul x (k +1)=Q∗x (k )+ d să aibă o soluţie unică x (k +1) şi se rezolvă uşor. De aceea
matricea S se alege de o formă simplă şi este inversabilă. Ea poate fi diagonală sau
(k) ∞
triunghiulară. Cea de-a doua condiție este că șirul {x } k=1 converge către soluția exactă x ¿
oricare ar fi x (0 ) ∈ R n. Presupunem că elementele diagonale a ii ≠ 0, i=1 , 2 ,… , n . Atunci în
calitate de matrice S se poate lua matricea diagonală ataşată matricei A , care este
−1 1 1 1
S=diag(α 11 , α 22 ,… , α nn) și respectiv avem S =diag ( , ,K, ). În acest caz sistemul
α 11 α 22 α nn
Sx=Tx+ b devine:
1
x i= ¿
aii

Procesul iterativ x (k +1)=Q∗x (k )+ d este definit prin:

(k+ 1) 1
xi = ¿
aii

Astfel obţinem o metodă de rezolvare a sistemului liniar Ax=b numită metoda lui Jacobi.
În metoda lui Jacobi este necesar de-a păstra în memoria calculatorului toate componentele
vectorului x(k) atît timp cît se calculează vectorul x(k +1). Putem modifica metoda lui Jacobi, astfel
încît la pasul (k + 1) să folosim în calculul componentei x i(k+ 1), valorile deja calculate la acelaşi
pas: x 1(k+1 ) , x 2(k+ 1) ,… , x i−1(k+1 ). Această modificare a metodei lui Jacobi se numeşte metoda
Gauss-Seidel, iar şirul iterativ anterior devine:
(k+ 1) 1
xi = ¿
aii

Am realizat subprogramele cu numele JACOBI și SEIDEL de calcul după metoda lui


Jacobi și metoda Gauss-Seidel corespunzător, care le v-om folosi în cadrul programului nostru.
Compararea rezultatelor

Rădăcina
Metoda Iterații Eroarea
X Y
x1=1.49235
x2=0,954102
Eliminării Gauss
x3=-0.725608
- 3 -
x4=0.498506
x1=1.49235 y1=1.49235
x2=0,954102 y2=0,954102
Cholesky
x3=-0.725608 y3=-0.725608
3 -
x4=0.498506 y4=0.498506
x1=1.49211
x2=0,953914
Jacobi
x3=-0.725478
- 6 0.001
x4=0.498605
x1=1.49233
x2=0,954096
x3=-0.725606
- 5 0.001
x4=0.498506
Gauss-Seidel
x1=1.49235
x2=0,954101
x3=-0.725608
- 7 0.00001
x4=0.498506
Concluzie
În cadrul acestei lucrări de laborator, care a avut un caracter deja mai mult practic, am
însușit patru metode numerice de rezolvare a sistemelor de ecuații liniare, algebrice și
transcendente neliniare, obținând aproximativ aceeleași soluții indiferent de metoda aleasă. La
general aceste metode au abordări diferite și pot prezenta avantaje sau dezavantaje în funcție de
caracteristicile sistemelor sau matricilor pe care le rezolvă. Astfel, de exemplu, metoda eliminării
lui Gauss poate fi mai eficientă pentru sisteme mici și medii, dar poate deveni costisitoare pentru
sisteme mari. În general, eficiența și numărul de iterații necesare depind de caracteristicile
matricei sistemului (simetrie, condiționare, dimensiune) și de condițiile de convergență ale
fiecărei metode. Nu există o metodă universală care să fie cea mai bună pentru orice tip de
problemă, iar alegerea depinde de specificul sistemului de ecuații liniare pe care dorim să-l
rezolvăm. Vreau să menționez că am studiat secvențele de cod date ca exemplu și le-am
convertat din limbajul de programare Pascal în C++, însă din motiv că personal m-am chiocnit cu
Pascal doar la lecțiile de informatică din gimnaziu, am decis totuși să realizez lucrarea în C++,
care îmi este un pic mai bine cunoscut și după părerea mea este mult mai modern și aplicabil în
context.
Vreau să menționez că deși am auzit de la colegi că au utilizat Wolfram Alpha pentru a se
verifica, eu totuși am decis să caut calculatoare specializate online pentru calculul sistemelor
liniare de ecuații. Astfel am găsit platforma atozmath.com, care prin intermediul plugin-ului
javascript MathJax, m-a ajutat să calculez soluțiile specifice fiecărei din cele 4 metode, ca
ulterior să le compar cu rezultatele obținute de programul meu. Dacă ar fi să fac o comparație, se
pare că luând în considerare numărul de iterații, cele mai eficiente ar fi metodele numerice
directe (eliminarea Gauss, metoda Cholesky) față de metodele iterative. Astfel, observăm că
ambele metode directe au efectuat un număr identic de iterații (adică 3). Metoda iterativă a lui
Jacobi la precizia ε =10−3 a efectuat 6 iterații pentru exemplul dat. Atragem atenția că la precizia
−3
ε =10 , metoda Gauss-Seidel a fost mai eficientă (5 iterații) față de cea a lui Jacobi, însă odată
cu creșterea preciziei până laε =10−5 , a crescut și numărul iterațiilor, devenind deja mai mare ca
la metoda lui Jacobi (7 iterații).
Din punct de vedere al programului vreau doar să menționez că la crearea unei interfețe
plăcute cu meniu de interacționare om-mașină, m-am ciocnit cu o singură dificultate banală.
Astfel obțineam eroare la încercarea de a executa instrucțiunea system(“cls”) din cadrul
limbajului de programare C++, care trebuia să curățe ecranul consolei de conținut. Problema era
că utilizam un compilator online GDB care lucra pe baza unui sistem pa bază de Linux, ceea ce
înseamnă că comanda dată trebuie înlocuită cu analogul ei system(“clear”), căci system(“cls”)
lucrează doar pe calculatoarele cu sistemele de operare (SO) de tip Windows. La fel îmi asum că
am comis o greșeală, ce ține de faptul că m-am lăsat condus de exemplele Pascal date în
materialele didactice... Acolo se utilizează instrucțiunea goto, utilizarea căreia este de dorit s-o
evităm defapt fiindcă duce la așa numitul “spaghetti-cod”.
Cursul de metode numerice face parte din disciplinele fundamentale de pregătire a
studenţilor din domeniul ingineriei, având ca scop prezentarea principiilor şi relaţiilor de calcul
matematic numeric care stau astăzi la baza costrucţiei programelor de calcul profesionale
utilizate în prezent de orice inginer. De aceea, cu siguranță voi căuta domenii de aplicare a
acestuia în sfera mea de activitate profesională.
Anexe
Anexa 1. Listing-ul programului C++
(cu screenshot-urile rezultatelor)

// Includem bibliotecile necesare

#include <iostream>

#include <math.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

using namespace std;

// Cream prototipurile functiilor

float deter(float A[4][4], int k);

void eliminSubDiag(int& ni);

void schimbLinii(int linia1, int linia2);

int isMatrPosDef();

int isMatrSim();

void factor(int& ni);

void trans();

void determinare();

void GAUSS();

void CHOLESKY();

void JACOBI();

void SEIDEL(float epsilon);

int isMatrDiagDom();

// Declaram variabila globala constanta a

// dimensiunii matricii (numarului liniilor)

const int lung=4;

// Initilizam matricea A cu dimensiunea 4x4

// si cu elementele reale din conditie

float A[lung][lung] = {

{6.1, -1.9, 0.4, 0.2},

{-1.9, 14.3, 1.8, 1.4},


{0.4, 1.8, 12.7, -0.6},

{0.2, 1.4, -0.6, 13.1}

};

// Initilizam matricea b (vectorul) cu

// dimensiunea 4 si cu elementele din conditie

float b[lung] = {7.1,10.2,-7.2,8.6};

// Declaram matricile intermediare necesare

float c[lung][lung],d[lung],l[lung][lung]={0};

// Functia programului principal

int main(){

system("clear");

int p,opt;

cout<<"Sistemul de ecuatii liniare Ax=b dat spre"<<endl;

cout<<"rezolvare este reprezentat de matricile:"<<endl;

cout<<"\nTabloul bidimensional A:"<<endl;

for(int i=0; i<lung; i++){

for(int j=0; j<lung; j++){

cout<<A[i][j]<<" ";

c[i][j]=A[i][j];

cout<<endl;

cout<<"\nTabloul bidimensional b:"<<endl;

for(int i=0; i<lung; i++){

cout<<b[i]<<" ";

d[i]=b[i];

cout<<endl;

cout<<"\
n------------------------------------------------------------------"<<endl;

cout<<"| Meniul cu lista metodelor de rezolvare:


|"<<endl;

cout<<"------------------------------------------------------------------\
n"<<endl;

cout<<"1. Metoda numerica directa de rezolvare prin eliminarea lui Gauss\n";

cout<<"2. Metoda decompozitiei lui Cholesky (metoda radacinii patrate)\n";

cout<<"3. Metoda iterativa a lui Jacobi cu o eroare epsilon=10^(-3)=0.001\


n";

cout<<"4. Metoda iterativa Gauss-Seidel cu o eroare 10^(-3) si 10^(-5)\n";

cout<<"0. Iesire din program\n"<<endl;

cout<<"Selectati optiunea: ";

cin>>opt;

switch(opt){

case 1:

system("clear");

cout<<"--------------------------------------------------------"<<endl;

cout<<"| Rezultatele metodei numerice directe de rezolvare |"<<endl;

cout<<"| prin eliminarea lui Gauss |"<<endl;

cout<<"--------------------------------------------------------\
n"<<endl;

GAUSS();

cout<<endl;

getchar();

exit(1);

break;

case 2:

system("clear");

cout<<"----------------------------------------------------"<<endl;

cout<<"| Rezultatele metodei decompozitiei lui Cholesky |"<<endl;

cout<<"| (metoda radacinii patrate) |"<<endl;

cout<<"----------------------------------------------------\n"<<endl;

CHOLESKY();

cout<<endl;

getchar();

system("clear");
main();

exit(1);

break;

case 3:

system("clear");

cout<<"------------------------------------------------"<<endl;

cout<<"| Rezultatele metodei iterative a lui Jacobi |"<<endl;

cout<<"| cu o eroare epsilon=0.001 |"<<endl;

cout<<"------------------------------------------------\n"<<endl;

JACOBI();

cout<<endl;

getchar();

system("clear");

main();

exit(1);

break;

case 4:

system("clear");

cout<<"------------------------------------------------"<<endl;

cout<<"| Rezultatele metodei iterative Gauss-Seidel |"<<endl;

cout<<"| cu o eroare epsilon=0.001 |"<<endl;

cout<<"------------------------------------------------\n"<<endl;

SEIDEL(0.001);

cout<<endl;

cout<<"------------------------------------------------"<<endl;

cout<<"| Rezultatele metodei iterative Gauss-Seidel |"<<endl;

cout<<"| cu o eroare epsilon=0.00001 |"<<endl;

cout<<"------------------------------------------------\n"<<endl;

SEIDEL(0.00001);

cout<<endl;

getchar();

system("clear");

main();

exit(1);

break;

default:
cout<<"Eroare! Ai ales o optiune gresita!";

break;

case 0:

return 0;

// Subprogramul metodei eliminarii lui Gauss

void GAUSS() {

// Declaram vectorul de solutii

float x[lung]={0};

// Initializam contorul de iteratii

int ni=0;

// Obtinerea matricii superior triunghiulare

eliminSubDiag(ni);

// Calculam solutiile din sistemul superior triunghiular

for(int i=lung-1; i>=0; i--) {

x[i]=b[i];

for(int j=i+1; j<lung; j++) {

x[i]-=A[i][j]*x[j];

x[i]/=A[i][i];

// Afisarea solutiilor si numarului total de iteratii

cout<<"\nRezultatele x:\n";

for(int i=0; i<lung; i++)

cout<<"x"<<i+1<<"="<<x[i]<<"\n";

cout<<"\nNumarul iteratiilor: "<<ni<<endl;

// Functia pentru schimbul a doua linii in

// matricea extinsa [A|b] (rearanjarea ecuatiilor)

void schimbLinii(int linia1, int linia2) {

// Declaram variabila auxiliara


float temp;

for(int j=0; j<lung; j++) {

temp=A[linia1][j];

A[linia1][j]=A[linia2][j];

A[linia2][j]=temp;

temp=b[linia1];

b[linia1]=b[linia2];

b[linia2]=temp;

// Functia pentru reducerea la zero a

// elementelor sub diagonala principala

void eliminSubDiag(int& ni) {

for(int k=0; k<lung-1; k++) {

if(A[k][k]==0) {

// Daca elementul de pe diagonala principala

// este zero, schimbam linia cu una care are

// un element nenul in acea coloana

for(int i=k+1; i<lung; i++) {

if(A[i][k]!=0) {

schimbLinii(k,i);

break;

for(int i=k+1; i<lung; i++) {

float m=A[i][k]/A[k][k];

for(int j=k; j<lung; j++) {

A[i][j]-=m*A[k][j];

b[i]-=m*b[k];

// Incrementam contorul iteratiilor

ni++;

}
}

// Subprogramul metodei decompozitiei lui Cholesky

void CHOLESKY(){

// Verificam daca matricea A este pozitiv definita

if(!isMatrPosDef()){

cout<<"\nMatricea A nu este pozitiv definita!\n";

getchar();

system("clear");

main();

exit(1);

goto E;

// Verificam daca matricea A este simetrica

if(!isMatrSim()){

cout<<"\nMatricea A nu este simetrica!\n";

getchar();

system("clear");

main();

exit(1);

// Rezolvarea sistemului liniar

// folosind factorizarea Cholesky

determinare();

getchar();

E:;

// Functia de calcul recursiv a determinantului

// matricei patratice A de dimensiunea (ordinul) k=i+1

float deter(float A[lung][lung],int k){

if(k==1)

return A[0][0];

if(k==2)

return A[0][0]*A[1][1]-A[0][1]*A[1][0];

float s=0;
float t[lung][lung]={0};

for(int i=0; i<k; i++){

int x=0;

for(int l=0; l<k; l++){

if(l!=i){

for(int m=1; m<k; m++)

t[x][m-1]=A[l][m];

x++;

if(i%2==0)

s+=A[i][0]*deter(t,k-1);

else

s-=A[i][0]*deter(t,k-1);

return s;

// Functia ce verifica daca matricea A este pozitiv definita

int isMatrPosDef(){

for(int i=0; i<lung; i++)

if(A[i][i]<=0 || deter(A,i+1)<=0)

return 0; // nu este

return 1; // este

// Functia ce verifica daca matricea A este simetrica

int isMatrSim(){

for(int i=0; i<lung; i++)

for(int j=0; j<lung; j++){

// Conditia de simetrie

if(A[i][j]!=A[j][i])

return 0; // nu este

return 1; // este

}
// Functia ce efectueaza factorizarea Cholesky a matricei A

void factor(int& ni){

l[0][0]=(float)sqrt(A[0][0]);

for(int i=0; i<lung; i++)

l[i][0]=A[i][0]/l[0][0];

for(int i=1; i<lung; i++){

float t=0;

for(int j=0; j<i; j++)

t+=l[i][j]*l[i][j];

l[i][i]=(float)sqrt(A[i][i]-t);

for(int j=i; j<lung; j++){

float t1=0;

for(int k=0; k<i; k++)

t1+=l[j][k]*l[i][k];

l[j][i]=(A[j][i]-t1)/l[i][i];

// Incrementam contorul iteratiilor

ni++;

// Functia de transpunere a matricii l

// obtinuta dupa factorizarea Cholesky

void trans(){

float t=0;

for(int i=0; i<lung; i++)

for(int j=0; j<i; j++){

t=l[i][j];

l[i][j]=l[j][i];

l[j][i]=t;

// Functia de rezolvare a sistemului liniar

// Ax=b folosind factorizarea Cholesky


void determinare(){

// Initializam contorul iteratiilor

int ni=0;

// Efectuam factorizarea Cholesky

factor(ni);

float y[lung],x[lung];

y[0]=b[0]/l[0][0];

for(int i=0; i<lung; i++){

float t=0;

for(int j=0; j<i; j++)

t+=l[i][j]*y[j];

y[i]=(b[i]-t)/l[i][i];

// Transpunerea matricii l obtinuta dupa factorizare

trans();

// Afisarea matricii triunghiulare inferioare transpuse

cout<<"Matricea triughiular superioara L(^T):\n"<<endl;

for(int i=0; i<lung; i++){

for(int j=0; j<lung; j++){

cout<<l[i][j]<<"\t";

cout<<endl;

x[lung-1]=y[lung-1]/l[lung-1][lung-1];

float t;

for(int i=lung-2; i>=0; i--){

t=0;

for(int j=i+1; j<lung; j++)

t+=l[i][j]*x[j];

x[i]=(y[i]-t)/l[i][i];

// Afisarea solutiilor si numarului total de iteratii

cout<<"\nRezultatele x:\n";

for(int i=0; i<lung; i++)

cout<<"x"<<i+1<<"="<<x[i]<<"\n";

cout<<"\nRezultatele y:\n";
for(int i=0; i<lung; i++)

cout<<"y"<<i+1<<"="<<y[i]<<"\n";

cout<<"\nNumarul iteratiilor: "<<ni<<endl;

// Implementam metoda iterativa a lui Jacobi

// pentru rezolvarea sistemului liniar Ax=b

void JACOBI(){

// Declaram variabila erorii epsilon=10^(-3)

float epsilon=0.001;

// Declaram variabilele necesare

float x[lung],x1[lung],q[lung][lung]={0},d[lung],t,max;

// Initializam contorul iteratiilor

int ni=0;

for(int i=0; i<lung; i++)

for(int j=0; j<lung; j++)

if(i!=j)

q[i][j]=-(A[i][j]/A[i][i]);

else

q[i][j]=0;

// Verificam daca matricea A este diagonal dominanta

if(!isMatrDiagDom()){

cout<<"Matricea A nu este diagonal dominanta!\n";

getchar();

system("clear");

main();

exit(1);

goto E;

for(int i=0; i<lung; i++)

d[i]=b[i]/A[i][i];

for(int i=0; i<lung; i++)

x[i]=d[i];

do {

for(int i=0; i<lung; i++)

x1[i]=x[i];
for(int i=0; i<lung; i++){

t=0;

for(int j=0; j<lung; j++){

// Procesul iterativ al sirului

// specific metodei lui Jacobi

t+=q[i][j]*x1[j];

x[i]=t+d[i];

max=(float)fabs(x[0]-x1[0]);

for(int i=1; i<lung; i++)

if((float)fabs(x[i]-x1[i])>max)

max=(float)fabs(x[i]-x1[i]);

// Incrementam contorul iteratiilor

ni++;

} while(max>epsilon);

// Afisarea solutiilor si numarului total de iteratii

cout<<"\nRezultatele x:\n";

for(int i=0; i<lung; i++)

cout<<"x"<<i+1<<"="<<x[i]<<endl;

cout<<"\nNumarul iteratiilor: "<<ni<<endl;

getchar();

E:;

// Functia ce verifica daca matricea A este diagonal dominanta

int isMatrDiagDom(){

float s;

for(int i=0; i<lung; i++){

s=0;

for(int j=0; j<lung; j++)

if(i!=j)

s+=A[i][j];

if(A[i][i]<s)

return 0; // nu este

if(A[i][i]==0)
return 0; // nu este

return 1; // este

// Implementam metoda iterativa Gauss-Seidel

// pentru rezolvarea sistemului liniar Ax=b

void SEIDEL(float epsilon){

// Declaram variabilele necesare

float x[lung],x1[lung],q[lung][lung]={0},d[lung],t,max;

// Initializam contorul iteratiilor

int ni=0;

for(int i=0; i<lung; i++)

for(int j=0; j<lung; j++)

if(i!=j)

q[i][j]=-(A[i][j]/A[i][i]);

else

q[i][j]=0;

if(!isMatrDiagDom()){

cout<<"Matricea A nu este diagonal dominanta!\n";

getchar();

system("clear");

main();

exit(1);

goto E;

for(int i=0; i<lung; i++)

d[i]=b[i]/A[i][i];

for(int i=0; i<lung; i++)

x[i]=d[i];

do {

for(int i=0; i<lung; i++)

x1[i]=x[i];

for(int i=0; i<lung; i++){

t=0;

for(int j=0; j<lung; j++){


// Modificarea metodei lui Jacobi in care folosim

// in calculul componentei sirului iterativ valorile

// deja calculate la acelasi pas (metoda Gauss-Seidel)

t+=q[i][j]*x[j];

x[i]=t+d[i];

max=(float)fabs(x[0]-x1[0]);

for(int i=1; i<lung; i++)

if((float)fabs(x[i]-x1[i])>max)

max=(float)fabs(x[i]-x1[i]);

ni++;

} while(max>epsilon);

// Afisarea solutiilor si numarului total de iteratii

cout<<"\nRezultatele x:\n";

for(int i=0; i<lung; i++)

cout<<"x"<<i+1<<"="<<x[i]<<endl;

cout<<"\nNumarul iteratiilor: "<<ni<<endl;

getchar();

E:;

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