Documente Academic
Documente Profesional
Documente Cultură
RAPORT
despre lucrare de laborator nr. 2
la Metode numerice
A efectuat:
st.gr.SI 141
A verificat:
Nemerenco Ecaterina
Marusic Galina
Chisinau 2015
Scopul lucrrii:
Indicaii teoretice
Rezolvarea sistemelor de ecuaii liniare constituie unul dintre subiectele larg abordate de
calculul numeric. n parte, acest fapt se datoreaz numeroaselor clase de fenomene care fie
au ca model matematic sisteme de ecuaii algebrice liniare, fie genereaz modele de acest
gen.
Metodele de rezolvare a sistemelor de ecuaii liniare se pot grupa, n principal, n trei mari
clase:
-
metode directe
metode iterative
Din punct de vedere numeric, metodele care utilizeaz calcul de determinani sunt improprii
procesrii automate, fapt care face ca algoritmii numerici s ocoleasc acest tip de
abordare. Celelalte dou clase de metode, ns, sunt utilizate n ponderi similare.
Metoda Gauss
Este cunoscut i sub numele de metoda eliminrii, fiind una dintre cele mai vechi i
mai utilizate metode n rezolvarea sistemelor de ecuaii liniare i n inversarea matricelor.
Metoda Gauss reduce sistemul de ordin n la forma superior triunghiular n n-1 pai.
A A0 aij0
Dac sistemul Ax=b se renoteaz A0x=b0, cu
, atunci la
Ak ( a ) bk (b b ... b )
k
ij
k
1
k
2
k T
n
a ijk 1 0
are primele k-1 coloane aduse la forma superior triunghiular, adic
pentru i>j i
j=1,2,...,k-1. La pasul k, pentru ik+1 se scade din ecuaia de rang i pe cea de rang k
1
nmulit cu factorul
aikk 1
t ik k 1
a kk
Algoritmul:
askk 1
askk 1
Se determin pivotul
dup relaia (5.2). Dac
( fiind precizia calculelor
spre exemplu 10-p dac se lucreaz cu p zecimale), atunci matricea sistemului este
singular i algoritmul este oprit.
Dac
sk
asj
, se intervertesc elementele
tik
3
aik
akk
akj k j n
i
bi bi tik bk
,
i respectiv bs i bk.
j k 1,...,n
. Pentru
se pune
Metoda Cholesky
n aceast metoda, fiind considerat matricea A c este pozitiv definit i simetric, putem
efectua
factorizarea Cholesky.
A L LT
unde L este o matrice inferior triunghiulara.
i atunci, sistemul se reduce la rezolvarea a dou sisteme mult mai simple:
L y b
LT x y
unde elementele lui L se determin n felul urmtor:
k 1
l kk a kk l kj2
.k 1, 2...
j 1
k 1
1
lik (aik lij l kj )
l kk
j 1
iar soluiile:
yi
i 1
1
(bi lik y k )
lii
k 1
xi
n
1
( y i l ki x k )
lii
k i 1
Metoda Jacobi
Considernd c sistemul e astfel structurat nct elementele diagonalei sunt dominante n
valoare
absolut, rearanjm sistemul eliminnd variabilele xi din termini care conin coeficienii a ii de
la
fiecare rnd n felul urmtor:
Continund acest proces iterativ obinem soluia care converge ctre soluia exact:
Metoda Gauss-Seidel
Practic nu se deosebete de metoda Jacobi descris anterior. Avantajul l const faptul
c nu trebuie s memorm vectorul soluiilor predente (k-1).
Formula iterativ de calcul este:
aij( k )
1
a
( k 1)
ii
aij( k 1) , eij( k )
a hj( k ) a hj( k 1)
) ( )
,
eij( k 1) , i 1, 2,...n
a hi( k 1) ( k 1)
a hi( k 1) ( k 1)
(k )
( k 1)
a
,
e
eij , h i, j 1, 2...n
ij
hj
hj
aii( k 1)
aii( k 1)
Ecuatiile 3.5
1
( k 1)
ii
5.8
6.4
b=
7.2
5.6
Anexa
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_IT 1000
typedef float** dMatrix;
dMatrix create_dMatrix(int n, int m);
void print_dMatrix(dMatrix dM, int n, int m);
dMatrix Copy_dMatrix(dMatrix M, int n, int m);
void delete_dMatrix(dMatrix *dM, int n, int m);
void print_vec(float* v, int n);
float* Solve_Gauss(dMatrix A, float b[], int n);
float* Solve_Cholesky(dMatrix A, float b[], int
n);
float* Solve_Jacobi(dMatrix A, float b[], int n,
float eps, int* iter);
float* Solve_GaussSeidel(dMatrix A, float b[],
int n, float eps, int* iter);
dMatrix Inverse_JordanGauss(dMatrix A, int n);
int main(void)
{
int n, i, j, iter;
printf("Introduce numarul de ecautii si
necunoscute: ");
scanf("%d", &n);
printf("Introduce matricea A:\n");
dMatrix A = create_dMatrix(n, n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
scanf("%f", &A[i][j]);
}
printf("Introduce vectorul b:\n");
float b[n];
for (i = 0; i < n; i++)
{
scanf("%f", &b[i]);
}
printf("Solutiile ecuatiilor prin metoda
Gauss:\n");
print_vec(Solve_Gauss(A, b, n), n);
printf("Solutiile ecuatiilor prin metoda
Cholesky:\n");
print_vec(Solve_Cholesky(A, b, n),n);
printf("Solutiile ecuatiilor prin metoda
Jacobi:\n");
print_vec(Solve_Jacobi(A, b, n, 1.0e-3, &iter),
n);
printf("Cu numarul de iteratii = %d\n", iter);
printf("Solutiile ecuatiilor prin metoda GaussSeidel:\n");
print_vec(Solve_Jacobi(A, b, n, 1.0e-6, &iter),
n);
printf("Cu numarul de iteratii = %d\n", iter);
printf("Matricea inversa determinata prin
metoda Jordan-Gauss:\n");
print_dMatrix(Inverse_JordanGauss(A, n), n,
n);
return 0;
}
dMatrix create_dMatrix(int n, int m)
{
dMatrix M =
(dMatrix)malloc(sizeof(float*)*n);
int i;
for (i = 0; i < n; i++)
M[i] = (float*)calloc(m, sizeof(float));
return M;
}
void print_dMatrix(dMatrix dM, int n, int m)
{
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
printf("%6.2f",dM[i][j]);
printf("\n");
}
}
M[j][k] = M[j][k] - ratio*M[i][k];
}
}
dMatrix copy_dMatrix(dMatrix M, int n, int m)
{
dMatrix C = create_dMatrix(n, m);
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
C[i][j] = M[i][j];
return C;
}
void delete_dMatrix(dMatrix *dM, int n, int m)
{
int i;
for (i = 0; i < n; i++)
free((*dM)[i]);
free(*dM);
*dM = NULL;
}
void print_vec(float* v, int n)
{
int i;
for (i = 0; i < n; i++)
printf("x%d = %5.6f\n", i+1, v[i]);
}
float* Solve_Gauss(dMatrix A, float b[], int n)
{
dMatrix M = copy_dMatrix(A, n, n);
float B[n];
int i, j ,k;
for (i = 0; i < n; i++)
B[i] = b[i];
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
{
float ratio = M[j][i]/M[i][i];
B[j] = B[j] - ratio*B[i];
for (k = i ; k < n; k++)
{
if (M[i][i] == 0) // rearanjare
{
int h;
}
float* sol = (float*)malloc(sizeof(float)*n);
sol[n-1] = B[n-1]/M[n-1][n-1];
for (i = n - 2; i >= 0; i--)
{
float t = 0;
for (j = n - 1; j > i; j--)
t += sol[j]*M[i][j];
sol[i] = (B[i] - t)/M[i][i];
}
delete_dMatrix(&M, n, n);
return sol;
}
float* Solve_Cholesky(dMatrix A, float b[], int n)
{
dMatrix L = create_dMatrix(n, n);
int i, j, k;
for (k = 0; k < n; k++) // Crearea matricei L
{
float t = 0;
for (j = 0; j < k; j++)
t += pow(L[k][j], 2);
L[k][k] = sqrt(A[k][k] - t);
for (i = k + 1; i < n; i++)
{
t = 0;
for (j = 0; j < k; j++)
t += L[i][j]*L[k][j];
L[i][k] = 1/L[k][k] * (A[i][k] - t);
}
}
float* x = (float*)malloc(sizeof(float)*n);
float* y = (float*)malloc(sizeof(float)*n);
for (i = 0; i < n; i++)
{
float t = 0;
for (k = 0; k < i ; k++)
t += L[i][k]*y[k];