Gauss-Algorithmus < Matlab < Mathe-Software < Mathe < Vorhilfe
|
Status: |
(Frage) reagiert/warte auf Reaktion | Datum: | 11:22 So 31.12.2006 | Autor: | Froeschin |
Aufgabe | Schreibe in Matlab ein Programm für den Gauss-Algorithmus mit Zeilen-, Spalten- und vollständiger Pivotisierung. |
Ich verstehe den Gaussalgorithmus und habe mich auch vor einiger Zeit mit Matlab beschäftigt, jedoch muss man das Rad ja nicht immer wieder neu erfinden und deswegen möchte ich gerne wissen, ob jemand den Algorithmus mit den verschiedenen Pivotisierungen bereits in Matlab programmiert hat oder weiss, wo ich das Programm finden kann.
Herzlichen Dank!
Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.
|
|
|
|
Hallo,
wenn es dir nicht unbedingt darum geht, es selber zu programmieren, kannst du dir ja mal die Hilfe zur Funktion "lu" ansehen.
Man kann dann Ax = B lösen mit:
[L,U]=lu(A);
x = U\(L\b);
Gruß
Martin
|
|
|
|
|
Aufgabe | Programmiere den Gauss-Algorithmus in Matlab mit Zeilen-, Spalten- und vollständiger Pivotisierung. |
Danke Martin für deinen gut gemeinten Ratschlag, doch leider hilft er mir nicht weiter, denn ich muss den Algorithmus selbst (also ausführlich und nicht nur mit Kurzbefehl) programmieren.
Deswegen nochmal meine Frage:
Ich verstehe den Gaussalgorithmus und habe mich auch vor einiger Zeit mit Matlab beschäftigt, jedoch muss man das Rad ja nicht immer wieder neu erfinden und deswegen möchte ich gerne wissen, ob jemand den Algorithmus mit den verschiedenen Pivotisierungen bereits in Matlab programmiert hat oder weiss, wo ich das Programm finden kann.
Herzlichen Dank!
Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.
MfG Katrin
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 00:09 Mi 03.01.2007 | Autor: | leduart |
Hallo
Martin meinte doch, du sollst dir die Funktion lu ansehen! nicht einfach nur benutzen!
Gruss leduart
|
|
|
|
|
Aufgabe | Programmiere den Gauss-Algorithmus in Matlab mit Zeilen-, Spalten- und vollständiger Pivotisierung. |
Hallo Leduart, leider hilft mir die "Hilfe für die LU-Funktion" auch nicht weiter, dort wird nur knapp die Zerlegung in obere bzw. untere Dreiecksmatrix erläutert, ein Programm für den Gaussalgorithmus kann ich jedoch nicht entdecken...
Aber aller guten Dinge sind 3, deswegen nochmal:
Hat jemand bereits den Gaussalgorithmus in Matlab programmiert oder weiss, wo ich ihn im Netz finden kann?
Vielen Dank, Gruss, Katrin
(Ich habe diese Frage in keinem anderen Forum gestellt)
|
|
|
|
|
Hallo,
du bist ganz schön hartnäckig, denn mir wäre eine Frage à la "Kann mir jemand beim Programmieren helfen?" lieber.
Im Netz habe ich so etwas nicht gefunden, aber meine Lösung für eine zeilenpivotisierte Version sieht so aus (A ist hierbei unsere Matrix):
steps = min(size(A));
for index=1:steps,
[maxwert, pivotzeile] = max(abs(A(index:end,index)));
if maxwert == 0, continue; end;
A([index,index-1+pivotzeile],:) = A([index-1+pivotzeile,index],:);
diffMatrix = kron(A(index+1:end,index)/A(index,index),A(index,index:end));
A(index+1:end,index:end) = A(index+1:end,index:end) - diffMatrix;
end;
Es funktionierte mit mehreren Zufallsmatrizen. Ob es noch einige nicht abgefangene Ausnahmen gibt, bei denen es schiefgeht, weiß ich leider nicht.
Durch kleine Änderungen erreicht man auch eine Spaltenpivotisierung, durch größere Änderungen auch eine totale Pivotisierung.
Durch numerische Ungenauigkeiten kann es sein, dass an einigen Stellen statt 0 eine sehr kleine Zahl steht. Dies kann man notfalls durch ein nachgeschobenes
A = A.*(abs(A)>0.00000001);
beheben.
Gruß
Martin
|
|
|
|
|
Aufgabe | Programmiere den Gaussalgorithmus.
Offen gebliebene Fragen zu Zeilen- und totaler Pivotisierung, sowie zum Befehl zum Beenden des Programms |
Hallo Martin, danke nochmal für deine Mühe!!
Nein, mir ging es gerade nicht drum, dass mir jemand beim Programmieren hilft, sondern nur darum, wenn sich jemand schon mal die Mühe gemacht hat, den gesamten Algorithmus zu programmieren, dass ich mir dann die Arbeit sparen könnte. Leider war mir bei deinem Tipp auch einiges unklar und jetzt hab ich's eben doch mit nem Freund selbst programmiert, (vorläufig nur für Spaltenpivotisierung). Wen's interessiert siehe unten.
Wer Lust hat, kann mir gern noch nen Tip zur Zeilen- und totalen Pivotisierung geben.
MfG, Katrin
function GAUSSSPALTEN(A,b,n,l,x,z,p,ip,c)
% Gauss-Algorithmus zur Loesung Linearer Gleichungssysteme mit Spaltenpivotisierung
A = [3 2; 1 -2] % (vorläufig spezielle Matrix vorgegeben, geht aber für beliebige)
b = [1; 0];
n = 2;
l = zeros (n,n);
% Pivotsuche
for j = 1 : n
p=max(abs(A(j:n,j)))
% if p==0
% 'Matrix ist singulaer' (ausserdem soll in diesem Fall das Programm beendet werden, weiss jemand, wie der Befehl dafür lautet?)
% end
for i=j:n
if abs(A(i,j))==p
c=i; % Zeile, die das Pivotelement enthaelt, erhaelt Index c
end
end
% Zeilenvertauschung
for i=j:n
ip=A(j,i);
A(j,i)=A(c,i);
A(c,i)=ip;
end
ip=b(j);
b(j)=b(c);
b(c)=ip;
% Umformung in Dreiecksmatrix
for i = j+1 : n
l(i,j) = A(i,j) / A(j,j);
b(i) = b(i) - l(i,j)*b(j);
for k = j : n
A(i,k) = A(i,k) - l(i,j)*A(j,k);
end
end
end
% Loesung des LGS mit Hilfe der erhaltenen Dreiecksmatrix
for i = n : -1 : 1
z=0;
for j = i+1 : n
z = z+A(i,j)*x(j);
end
x(i) = (b(i)-z)/A(i,i);
end
% diese Schleife macht folgendes:
%x(n) = b(n) / A(n,n);
%x(n-1) = (b(n-1) - A(n-1,n)*x(n)) / A(n-1,n-1);
%x(n-2) = (b(n-2) - A(n-2,n-1)*x(n-1) - A(n-2,n)*x(n)) / A(n-2,n-2);
% usw.
% wobei jeweils der Zaehler mit z bezeichnet wird
A % gibt Dreiecksmatrix aus
x % gibt Loesungsvektor aus
|
|
|
|
|
Hallo,
> Tip zur Zeilen- und totalen Pivotisierung geben
Das geht prinzipiell ganz ähnlich.
Bei der Zeilenpivotisierung suchst du einfach statt in derselben Zeile einfach in derselben Spalte nach dem größten Element. Da muss man nur ein paar Indizes umfummeln. Der Spaltentausch geschieht analog zum Zeilentausch, nur dass man hier noch die Vertauschungen der Variablen mitführen muss, um am Ende die ursprüngliche Ordnung wiederherzustellen.
Bei der totalen Pivotisierung kannst du zuerst nach der Spalte mit dem größten Element suchen und dann herausfinden, in welcher Zeile es steht (oder andersrum). Dann führst du Zeilen- und Spaltenvertauschung nacheinander in beliebiger Reihefolge aus. Auch hier die Variablen, die vertauscht wurden merken.
Da man in Matlab ganz prima mit Matrizen arbeiten kann und sich so einige for-Schleifen erspart, poste ich hier noch meine Komplettlösung.
Wie du siehst, mache ich den Ausstieg im Fehlerfall mit error(...).
Der Aufruf ist gausspivot(A, b, typ), wobei Typ 'z', 's' oder 't' sein kann (für Zeilen-, Spalten- oder totale Pivotisierung).
Du kannst es ja mal ausprobieren...
Übrigens kannst du Zufallsgleichungssysteme erzeugen und lösen per:
A = rand(5); b = rand(5,1);
[L,U]=lu(A); lsg = U\(L\b);
Das ist nützlich zum Testen der Lösungen die das eigene Programm liefert.
Hier meine Komplettlösung:
function x = gausspivot(A, b, pivtyp)
%GAUSSPIVOT Löst lineare Gleichungssysteme
% A Koeffizientenmatrix, mit mehr Zeilen als Spalten (also auch überbestimmte LGS)
% b Vektor mit gleicher Zeilenzahl wie A
% pivtyp Pivotisierungstyp, kann die Werte 'z', 's' oder 't' für Zeilen-,
% Spalten- bzw. totale Pivotisierung
% Gibt bei Lösbarkeit einen Lösungsvektor zurück
varzahl = size(A, 2); %Anzahl der Variablen
if size(A,1) < varzahl, error('Keine eindeutige Lösung möglich!'); end; %mehr Variablen als Gleichungen -> Fehler
%oben: erweiterte KoeffMatrix, letzte Zeile: Variablenindizes (1..varzahl), helfen bei Spaltenvertauschungen
Abix = [A b; 1:varzahl 0];
tauschzeile = 1; tauschspalte = 1; %per Default auf 1, also Tausch mit sich selbst
for index=1:varzahl,
%Suche nach größtem Element, je nach Pivotisierungstyp
switch(pivtyp),
case 's', %Spaltenpiv.
[maxwert, tauschzeile] = max(abs(Abix(index:end-1, index)));
case 'z', %Zeilenpiv.
[maxwert, tauschspalte] = max(abs(Abix(index, index:end-1)));
otherwise, %totale Piv.
[maxwert,tauschspalte]=max(max(abs(Abix(index:end-1, index:end-1))));
[maxwert,tauschzeile]=max(abs(Abix(index:end-1, index-1+tauschspalte)));
end;
if maxwert, %Berechnung nur, falls größter Absolutwert nicht 0
Abix([index, index-1+tauschzeile], :) = Abix([index-1+tauschzeile, index], :); %Zeilentausch (immer, ggf. mit sich selbst)
Abix(:, [index, index-1+tauschspalte]) = Abix(:, [index-1+tauschspalte, index]); %Spaltentausch (immer, ggf. mit sich selbst), dabei auch Variablenumstellung
diffMatrix = kron(Abix(index+1:end-1, index) / Abix(index,index), Abix(index, index:end)); %Zeilensubtraktion wird in einer Matrix zusammengefasst
Abix(index+1:end-1, index:end) = Abix(index+1:end-1, index:end) - diffMatrix; %nur die Zeilen ab der aktuellen Zeile verändern, Indexzeile auslassen!
else
error('Keine eindeutige Lösung möglich!');
end;
end;
Abix(1:end-1,1:end-1) = Abix(1:end-1,1:end-1).*(abs(Abix(1:end-1,1:end-1))>0.0000001) %sehr kleine Wert als numerische Fehler auffassen, 0 setzen
diagA = diag(Abix(1:end-1,1:end-1));
if not(all(diagA)), error('Keine eindeutige Lösung möglich!'); end; %mindestens ein Diagonalelement ist 0 -> Fehler
if any(Abix(varzahl+1:end-1,varzahl+1:end)), error('Keine Lösung!'); end; %bei nichtquadratischer Matrix müssen alle überzähligen Zeilen komplett 0 sein, sonst Fehler
Ab_norm_kron = kron(1./diagA, Abix(1:varzahl, :)); %große Matrix, wird bei A1 und b1 wieder kleiner
A1 = Ab_norm_kron(1:varzahl+1:end, 1:end-1) .* (ones(varzahl) - eye(varzahl)); %A1 ist quadratisch, auch wenn A ggf. nichtquadratisch war
b1 = Ab_norm_kron(1:varzahl+1:end, end);
x=zeros(varzahl, 1); %Variablenvektor mit Nullen initialisieren
for i=varzahl:-1:1,
x = b1-A1*x; %iterativ Variablenbelegungen von der letzten bis zur ersten bestimmen
end;
[tmp, xindex] = sort(Abix(end, 1:end-1));
x=x(xindex); %Variablen umsortieren (wg. Spaltenvertauschungen)
Ach, ich hänge die Datei am besten mal an: gausspivot.m
Gruß
Martin
Dateianhänge: Anhang Nr. 1 (Typ: m) [nicht öffentlich]
|
|
|
|