Thema: Delphi Inverse einer matrix

Einzelnen Beitrag anzeigen

swarley

Registriert seit: 17. Aug 2011
6 Beiträge
 
#6

AW: Inverse einer matrix

  Alt 18. Aug 2011, 17:01
okay, ich war etwas übereilig. ihr könnt ja gar nicht wissen, was ich da noch alles fabriziert habe
Aufgabe ist es ein Unit namens "MyUnitMatrix" zu schreiben, in der mittels Unterprogrammen 2 Matrizen zu addieren, subtrahieren und multiplizieren sind. Zusätlich soll die Inverse ermittelt werden, und am besten das ganze auch nochmal überprüft werden (inverse mit ausgangsmatrix multiplizieren soll einheitsmatrix ergeben sozusagen). Soweit sogut.
ich hatte ein "urfassung" aus der entstammt auch der quelltext. Leider hat meiner Professorin das ganze optisch nicht gepasst (mal abgesehen davon, dass es nicht richtig funktioniert hat[was an dieser stelle heißt: programm wurde ausgeführt, inverse lieferte allerdings nicht das richtige ergebnis, die erste spalte war richtig, die restlichen enthielten werte, nicht die richtigen])
In dieser "urfassung" muss der Benutzer zu erst den rang seiner beiden Matrizen eingeben. anschließend mit dem button weiter erscheinen die Stringgrids der entsprechenden Größe, die angegeben wurde. Anschließend werden diese mit Zahlen gefüllt und je nach Button ("+", "-", "*") wurde überprüft ob die matrizen den bedingungen entsprechen, ansonsten müssen werte geändert werden. Unter einem der Stringgrids befand sich dann der button "inverse" dazu nun der quelltext aus der "hauptunit" sozusagen

Delphi-Quellcode:
procedure TForm2.ButtonInversClick(Sender: TObject);
var
  i, j, zeilen, spalten: Integer;
begin
  zeilen := StrToInt(Zeilenedit1.Text);
  spalten := StrToInt(Spaltenedit1.Text);
  if zeilen = spalten then
  begin
    for i := 0 to zeilen - 1 do
      for j := 0 to spalten - 1 do
      begin
        mat1[i, j] := StrToFloat(StringGridMatrix1.Cells[j, i]);
      end;
  end
  else
  begin
    ShowMessage('Zeilen-und Spaltenanzahl muss gleich groß sein!');
    exit;
  end;

  setlength(mathilf, zeilen);
  for i := 0 to zeilen - 1 do
  begin
    setlength(mathilf[i], 2 * spalten);
  end;

  invers(zeilen); // da spalten=zeilen reicht es aus, eins davon zu übergeben

  setlength(matinv, zeilen);
  for i := 0 to zeilen - 1 do
  begin
    setlength(matinv[i], zeilen);
  end;

  for i := 0 to zeilen - 1 do
  begin
    for j := 0 to zeilen - 1 do
    begin
      matinv[i, j] := mathilf[i, j + zeilen];
    end;
  end;

  StringGridMatrix3.Visible := true;
  labelergebnis.Visible := true;

  for i := 0 to zeilen - 1 do
  begin
    for j := 0 to zeilen - 1 do
    begin
      StringGridMatrix3.Cells[j, i] := FloatToStr(matinv[i, j]);
    end;
  end;
end;

end;
so, die matrizen, die eingegeben wurden also "mat1" und "mat2" habe ich global deklariert (was leider aufgabentechnisch auch falsch war). Ich hätte es lokal deklarieren und in das unterprogramm mit übergeben sollen. Das muss ich auch erneut überarbeiten.
naja und dann in meiner Unit "myunitmatrix" sozusagen, habe ich das unterprogramm deklariert, das is sozusagen der Quelltext oben. ich poste ihn trotzdem nochmal.
Delphi-Quellcode:
procedure invers(zeilen: Integer);
var
  i, j, k, pivotzeile: Integer;
  mateinheit: array of array of double;
  pivotelement, faktor, hilf: double;
begin
  setlength(mateinheit, zeilen);
  for i := 0 to zeilen - 1 do
  begin
    setlength(mateinheit[i], zeilen);
    mateinheit[i, i] := 1;
  end;

  for i := 0 to zeilen - 1 do
  begin
    for j := 0 to zeilen - 1 do
    begin
      mathilf[i, j] := mat1[i, j];
    end;
  end;

  for i := 0 to zeilen - 1 do
  begin
    for j := 0 to zeilen - 1 do
    begin
      mathilf[i, j + zeilen] := mateinheit[i, j];
    end;
  end;

  for k := 0 to zeilen - 2 do
  begin
    pivotelement := 0;
    pivotzeile := k;
    for i := k to zeilen - 1 do
    begin
      if abs(mathilf[i, k]) > pivotelement then
      begin
        pivotelement := abs(mathilf[i, k]);
        pivotzeile := i;
      end;
      if k <> pivotzeile then
      begin
        for j := k to zeilen do
        begin
          hilf := mathilf[k, j];
          mathilf[k, j] := mathilf[i, j];
          mathilf[i, j] := hilf;
        end;
      end;
    end;
    if mathilf[k, k] = 0 then
      exit;
    for i := k + 1 to zeilen - 1 do
    begin
      faktor := mathilf[i, k] / mathilf[k, k];
      for j := k to zeilen do
      begin
        mathilf[i, j] := mathilf[i, j] - faktor * mathilf[k, j];
      end;
    end;
  end;

  for k := zeilen - 1 downto 0 do
  begin
    if mathilf[k, k] = 0 then
      exit;
    for i := k - 1 downto 0 do
    begin
      faktor := mathilf[i, k] / mathilf[k, k];
      for j := zeilen downto i do
      begin
        mathilf[i, j] := mathilf[i, j] - faktor * mathilf[k, j];
      end;
    end;
    for j := zeilen to 2 * zeilen - 1 do
    begin
      mathilf[k, j] := mathilf[k, j] / mathilf[k, k];
    end;
  end;
end;
ich weiß dieser beitrag ist mittlerweile schon überlang, aber ich komm echt nicht mehr klar. ich bräuchte irgendwie einen funktionierenden algorithmus für diese gauß jordan geschichte. Ich habe dummerweiße (glaub ich) auch noch nicht den fall abgegriffen, was geschieht wenn das erste element der ersten zeile eine 0 ist.
ich wäre auch über neue denkanstöße oder hilfelinks sehr dankbar, denn da ich selber nicht mehr checke was ich da hin implementiert habe, besstehe ich nicht auf das gedöns ^^
vielen dank an alle die sich die zeit nehmen das anzusehen

PS: ich habe die beschriebenen dateien mal als zip angehängt falls ich in meiner ausführung zu ungenau oder schlusig war.
Angehängte Dateien
Dateityp: zip endprojekt.zip (492,6 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat