Technika obliczeniowa i symulacyjna laboratorium
|
|
Wydział : Telekomunikacja i Elektotechnika
|
Imie i Nazwisko:
|
Kierunek : Telekomunikacja i Elektronika
|
|
grupa : 3
|
|
Data: 2010-11-30 |
Ocena: |
1 Cel ćwiczenia:
Badanie wpływu złego uwarunkowania numerycznego macierzy na wyniki obliczeń w procesie rozwiązywania układów liniowych równań algebraicznych o postaci
2 Zadanie :
Rozwiązanie układu równań liniowych
3 Implementacja:
Clasa Equationsolver:
class equationsolver { // Clasa główna w której wykonywane są wszelkie obliczenia do metody gaussa //********************************************************************************** public static double[] solveByGaussEliminations (double[][]a, double[]b) { int n=b.length; // zm n przypisanie dł. tablicy b double []x=new double [n]; int []p=new int [n];
//Znalezienie macierzy dolno i gorno-trojkatnej (l) oraz macierzy permutacji decomposePA(a, p); //Rozwiązanie macierzy l*z=p*b, wyniki zapisane w b for (int k=0; k<n-1; k++) { for (int i=k+1; i<n; i++) { // przypisanie b[p[i]]=b[p[i]]-a[p[i]][k]*b[p[k]];
} } //rozwiazanie ukladu gornotrojkatnego u double suma=0; for(int i=n-1; i>=0; i--) { suma=0; for(int j=i;j<n;j++) suma=suma+a[p[i]][j]*x[j]; x[i]=(b[p[i]]-suma)/a[p[i]][i]; } wynik(x); return x; } //************************************************************************************
private static void decomposePA(double[][]a, int[]p) { double []S=new double [a.length]; double z=0;
for (int i=0; i<a.length; i++) { p[i]=i;
for (int j=0; j<a[i].length; j++) { if(S[i]<Math.abs(a[i][j])) { S[i]=Math.abs(a[i][j]);
} }
} for (int k=0; k<a.length-1; k++) { double max=0; int u=0; for (int i=k; i<a.length; i++) { if (Math.abs(a[p[i]][k])/S[p[i]]>max) { max=Math.abs(a[p[i]][k])/S[p[i]]; u=i; } } int zamienna= p[k]; p[k]=p[u]; p[u]=zamienna; for (int i=k+1;i<a.length ;i++) { z=a[p[i]][k]/a[p[k]][k]; a[p[i]][k]=z; for(int w=k+1; w<a.length; w++) { a[p[i]][w]=a[p[i]][w]-z*a[p[k]][w]; } } } } //************************************************************************************
//Wydrukowanie wyników dla metody Gaussa public static void wynik(double[]x) { System.out.println("Metoda Gaussa"); for (int i=0; i<x.length; i++) { System.out.println("x["+i+"] "+x[i]);
} System.out.println("----------------------------------------------------"); } //************************************************************************************
// Implementacja metody Gaussa-Seidla public static double[] solveByGaussSeidelEliminations (double[][]a, double[]b) { int n = b.length; double []x= new double[n]; double [][] L = new double [n][n]; double [][] D1 = new double [n][n]; double [][] U = new double [n][n]; double [] D1b = new double [n]; double [][] D1L = new double [n][n]; double [][] D1U = new double [n][n];
//Tworzenie tablic L, D1, U for(int i=0; i<n; i++) { D1[i][i]=1/a[i][i]; D1b[i]=D1[i][i]*b[i];
for(int j=i+1; j<n; j++) { U[i][j]=a[i][j]; L[j][i]=a[j][i]; } for(int j=0; j<n; j++) { for (int k=0;k<n;k++) { D1L[i][j]+=D1[i][k]*L[k][j]; D1U[i][j]+=D1[i][k]*U[k][j]; } } } //************************************************************************************ //Otrzymanie wyniku
double q=0; for (int j=0;j < 10000;j++) { for ( int z=0; z<n; z++) { q=D1b[z]; for ( int h=0; h<n; h++) { q=q - D1L[z][h] * x[h]- D1U[z][h] * x[h]; } x[z]=q; } } wyniks(x); return x;
}
//************************************************************************************
public static void wyniks(double[]x) { System.out.println("Metoda Gaussa-Seidla"); for (int i=0; i<x.length; i++) { System.out.println("x["+i+"] "+x[i]);
} System.out.println("---------------------------------------------------");
}
}
|
Clasa main główna klasa wykonywalna:
public class gausse {
/** * @param args */ public static void main(String[] args) { double [][]a={{6,-2,2,4},{12,-8,6,10},{3,-13,9,3},{-6,4,1,-18}}; double []b={12,34,27,-38}; equationsolver.solveByGaussSeidelEliminations(a, b); equationsolver.solveByGaussEliminations(a,b);
}
} |
4 Otrzymane wyniki Alfgorytmu:
Metoda Gaussa-Seidla
x[0] 0.9999999999999809
x[1] -2.999999999999958
x[2] -1.9999999999999392
x[3] 1.0000000000000195
Metoda Gaussa
x[0] 1.0000000000000002
x[1] -3.0000000000000013
x[2] -2.0000000000000013
x[3] 0.9999999999999996
5 Wnioski:
Jak odrazu widać jedna i druga metoda jest metodą prawidłową i dość dokładną. Jednak, że 2 metoda jest odrobine mniej dokładna w stosunku do metody 1. Nie są to różnice wielce odbiegające od marginesu błędu obliczeniowego. Po przeprowadzeniu danego doświadczenia odrazu można dojśc do głównego wniosku: przy macierzy np dochodzącej do kilku tysięcy czy milionów punktów o wiele bardziej skuteczna i bardziej stabilna okazuje się metoda Gaussa - Seidela która wykazuje się mniejszym błędem obliczeniowym co w konsekwencji przełoży się na dokładniejszy wynik.