AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Übergabe einer Matrix an Unterprogramm

Ein Thema von swarley · begonnen am 23. Aug 2011 · letzter Beitrag vom 25. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2      
swarley

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

Übergabe einer Matrix an Unterprogramm

  Alt 23. Aug 2011, 21:46
Hallo,
ich habe das Unterprogramm zur Berechnung der Inversen soweit hingekriegt (nehm ich an). Dummerweise mache ich wohl etwas bei der Übergabe der Ausgangsmatrix bzw Übergabe der Ergebnismatrix falsch. Dabei brauch ich noch einmal Hilfe.

Ich habe in meiner ButtonInverse.Onclick procedure zeilen-und spaltengröße, sowie meine Matrix, die ich invertieren möchte eingelesen. Daraufhin habe ich eine Matrix erzeugt, welche so aussieht, dass im vorderen Teil meine Ausgangsmatrix steht und die Einheitsmatrix sozusagen im hinteren Teil angehangen wird.
Bsp:
|1 2 3 1 0 0|
|4 5 6 0 1 0| =: matgauss
|7 8 9 0 0 1|

dann rufe ich mein Unterprogramm "Inverse" auf mit folgendem Befehl:
Inverse(0, zeilen, spaltengauss, matgauss); der Quelltext meines Unterprogramms sieht dabei so aus:
Delphi-Quellcode:
procedure Inverse(a,zeilen,spaltengauss:Integer;matgauss:TMatrixgauss);
var i,j,k : Integer;
begin
  if a < zeilen-1 then
  begin
      for i := a to spaltengauss - 1 do
       begin
         matgauss[a,i]:=matgauss[a,i]/matgauss[a,a];
       end;
      for j := a+1 to zeilen - 1 do
        begin
          for k := a to spaltengauss - 1 do
            begin
                matgauss[j,k]:=matgauss[j,k]-matgauss[j,a]*matgauss[a,k];
            end;
        end;
    Inverse(a+1,zeilen,spaltengauss,matgauss);
  end;
end;
so wenn ich das Programm starte, werden mir keine Fehler gemeldet. Wenn ich nun eine beliebige Matrix eingebe (angenommen, die obige, also
|1 2 3|
|4 5 6|
|7 8 9|,
dann wird mir leider nicht wie erhofft:
|1 0 0 x x x|
|0 1 0 x x x|
|0 0 1 x x x| (x steht hierbei für die invertierten werte)
ausgegeben, sondern:
|1 2 3 1 0 0|
|4 5 6 0 1 0|
|7 8 9 0 0 1|

also muss ich ja irgendwas bei der übergabe falsch gemacht haben, oder? Bitte schnellstens um Hilfe!

PS: eine Überprüfung und Korrektur, falls das erste Element in der matrix eine 0 sein sollte, habe ich vorgenommen und alle Fälle abgefangen(also sollte es nur eine zeile geben, weile im ersten element nicht 0 ist, bzw wenn alle elemente eine 0 enthalten usw)
es geht mir erst einmal nur allein darum, wenigstens eine korrekte ausgabe zu erhalten, sprich, dass mir ein stringgrid angezeigt wird in dem im vorderen teil die einheitsmatrix steht!
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Übergabe einer Matrix an Unterprogramm

  Alt 23. Aug 2011, 22:34
Die rechte Seite brauchst du nicht zu übergeben, das kann Inverse erledigen.

Delphi-Quellcode:

type
  TMat = array of array of double;


function Reziproke(const A: TMat): TMat;
var
  N, I, J, K, L: integer;
  Q: double;
  G, B: TMat;
begin
  N:= Length(A);
  SetLength(G, N, N);
  SetLength(B, N, N);
  SetLength(Result, N, N);
  // Umspeichern, Rechte Seite setzen
  for I:= 0 to N-1 do
  begin
    for J:= 0 to N-1 do
    begin
      G[I, J]:= A[I, J];
      B[I, J]:= 0;
    end;
    B[I, I]:= 1;
  end;
  // Gauss mit N Rechten Seiten
  ..
  ..
end;

procedure TForm1.Button7Click(Sender: TObject);
var
  A, R: TMat;
  N, I, J: integer;
begin
  N:= 3;
  SetLength(A, N, N); // Matrix
  A[0, 0]:= 1; A[0, 1]:= 2; A[0, 2]:= 0;
  A[1, 0]:= 2; A[1, 1]:= 3; A[1, 2]:= 0;
  A[2, 0]:= 3; A[2, 1]:= 4; A[2, 2]:= 1;
  R:= Reziproke(A);
  // for I:= 0 to N-1 do for J:= 0 to N-1 do ShowMessage (FloatToStr(R[I, J]));
  SetLength(A, 0); // Matrix
  SetLength(R, 0); // Reziproke
end;

Geändert von Bjoerk (23. Aug 2011 um 22:37 Uhr) Grund: Tippfehler
  Mit Zitat antworten Zitat
FredlFesl

Registriert seit: 19. Apr 2011
293 Beiträge
 
Delphi 2009 Enterprise
 
#3

AW: Übergabe einer Matrix an Unterprogramm

  Alt 24. Aug 2011, 07:47
Die letzten beiden SetLength'se kannste Dir sparen. Das macht Delphi schon von alleine.
Und wenn du dann noch aus einem 'TMat' z.B. ein 'TMatrix' machst, sieht das auch schon besser aus. Denn die Bezeichnung bzw. das Wort 'Mat' kenne ich einfach nicht.
Das Bild hängt schief.
  Mit Zitat antworten Zitat
swarley

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

AW: Übergabe einer Matrix an Unterprogramm

  Alt 24. Aug 2011, 18:45
so ich habe meinen algorithmus jetzt optimiert. und mein unterprogramm enthält folgenden Quelltext:
Delphi-Quellcode:
procedure Inverse(a,zeilen,spaltengauss:Integer;var matgauss:TMatrixgauss);
var i,j,k : Integer;
begin
  if a < zeilen-1 then
  begin
      for i := a to spaltengauss - 1 do
       begin
         matgauss[a,i]:=matgauss[a,i]/matgauss[a,a];
       end;
      for j := a+1 to zeilen - 1 do
        begin
          for k := a to spaltengauss - 1 do
            begin
              matgauss[j,k]:=matgauss[j,k]-matgauss[j,a]*matgauss[a,k];
            end;
        end;
    Inverse(a+1,zeilen,spaltengauss,matgauss);

    for j := a-1 downto 0 do
    matgauss[j,a]:=matgauss[j,a]-matgauss[j,a]*matgauss[a,a];
  end;
  for i := zeilen-1 to spaltengauss-1 do
    begin
       matgauss[zeilen-1,i]:=matgauss[zeilen-1,i]/matgauss[zeilen-1,zeilen-1];
        for j := a-1 downto 0 do
         matgauss[j,a]:=matgauss[j,a]-matgauss[j,a]*matgauss[a,a];
    end;
end;
mit der typdeklaration:
TMatrixgauss = array[0..5,0..10]of Double; in meiner ButtonInverse.onClick procedure erstelle ich die matrix matgauss, die vor der übergabe, wie folgt aussieht:
|8 4 5 1 0 0|
|4 7 3 0 1 0| =: matgauss
|7 3 2 0 0 1|

Ich habe mehrmals überprüft, dass auch wirklich diese matrix in "matgauss" steckt, daher verstehe ich nicht wieso ich nach meinem prozeduraufruf Inverse(0,zeilen,spaltengauss,matgauss); , wenn ich eine 3 x 3 matrix eingebe, in meinem Stringgrid folgendes Ergebnis erhalte(zeilen hat den wert 3, spaltengauss 6)
|1 0 0 1 0 0|
|0 1 0 0 1 0|
|0 0 1 0 0 1|


anstatt:
|1 0 0 -0.05 -0.08 0.25|
|0 1 0 -0.14 0.20 0.04|
|0 0 1 0.40 -0.04 -0.43|

(gut das ist wegen den gebrochenen Zahlen jetzt ein doofes Beispiel, aber darum geht es ja nicht)
Kann mir jemand erklären, wieso mein algorithmus im "vorderen Teil" der Matrix arbeitet und im "hinteren" nicht?
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 01:34
FredlFesl, TMat oder TMatrix, ist sowas von egal. Und die SetLength’s Null kann man sich nur bei lokalen Variablen schenken (ich schreib’s der Vollständigkeit halber gelegentlich dennoch hin).

swarley, wenn du die Variante möchtest, in der die Lösung auf der rechten Seite steht, dann kenn ich das so:

Delphi-Quellcode:
procedure Inverse(const N: integer; var A: TMatrixGauss);
var
  i,j,k : Integer;
begin
  for I:= 0 to N-1 do
    for J:= I+1 to N+N-1 do
    begin
      A[I, J]:= A[I, J] / A[I, I]; // Matrix singulär, falls A[I, I] = 0
      for K:= 0 to N-1 do
        if K <> I then A[K, J]:= A[K, J] - A[K, I] * A[I, J];
    end;
end;

procedure TForm1.Button11Click(Sender: TObject);
var
  A: TMatrixGauss;
  I, J, N: integer;
begin
  N:= 3;
  A[0, 0]:= 1; A[0, 1]:= 2; A[0, 2]:= 0; A[0, 3]:= 1; A[0, 4]:= 0; A[0, 5]:= 0;
  A[1, 0]:= 2; A[1, 1]:= 3; A[1, 2]:= 0; A[1, 3]:= 0; A[1, 4]:= 1; A[1, 5]:= 0;
  A[2, 0]:= 3; A[2, 1]:= 4; A[2, 2]:= 1; A[2, 3]:= 0; A[2, 4]:= 0; A[2, 5]:= 1;
  Inverse(N, A);
  for I:= 0 to N-1 do
    for J:= N to N+N-1 do ShowMessage (FloatToStr(A[I, J]));
end;
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#6

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 08:50
Delphi-Quellcode:
procedure Inverse(const N: integer; var A: TMatrixGauss);
//...
      A[I, J]:= A[I, J] / A[I, I]; // Matrix singulär, falls A[I, I] = 0
//...
end;
Der Kommentar ist falsch bzw. unsinnig/irreführend. Wenn A[I, I] gleich 0 ist, heißt das erstmal nur, daß man ohne Zeilenvertauschungen nicht weiter kommt. Selbstverständlich ist zB die folgende Matrix nicht singulär:
Code:
0 1
2 0
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#7

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 09:31
Kann mir jemand erklären, wieso mein algorithmus im "vorderen Teil" der Matrix arbeitet und im "hinteren" nicht?
Ohne auf die merkwürdigen Interna dieser rekursiven Lösung einzugehen, hier ein Hinweis, warum es nicht funktionieren kann:
Delphi-Quellcode:
for i := a to spaltengauss - 1 do begin
  matgauss[a,i]:=matgauss[a,i]/matgauss[a,a];
end;
Was soll das bezwecken? Was es bewirkt, ist doch folgendes: matgauss[a,a] wird auf 1 gesetzt, der Rest wird durch 1 geteilt, bleibt also gleich. Eventuell hilft ja hier
Delphi-Quellcode:
for i :=spaltengauss - 1 downto a begin
  matgauss[a,i]:=matgauss[a,i]/matgauss[a,a];
end;
und an der anderen Stelle.(Warum wird eigentlich a=zeilen-1 aus der Rekursion ausgespart?) Dies aber ohne Garantie. Wenn jemand unbedingt, etwas völlig Unorthodoxes programmieren will...
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 11:43
Der Kommentar ist falsch bzw. unsinnig/irreführend. Wenn A[I, I] gleich 0 ist, heißt das erstmal nur, daß man ohne Zeilenvertauschungen nicht weiter kommt. Selbstverständlich ist zB die folgende Matrix nicht singulär:
Code:
0 1
2 0
Sorry Kumpel, im Sinne des Gauß Algorithmus ist diese Matrix singulär.
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#9

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 12:40
Der Kommentar ist falsch bzw. unsinnig/irreführend. Wenn A[I, I] gleich 0 ist, heißt das erstmal nur, daß man ohne Zeilenvertauschungen nicht weiter kommt. Selbstverständlich ist zB die folgende Matrix nicht singulär:
Code:
0 1
2 0
Sorry Kumpel, im Sinne des Gauß Algorithmus ist diese Matrix singulär.
Entschuldigung, aber so eine hirnrissige Äußerung habe ich schon lange nicht mehr gelesen. Wenn Du wenigsten geschrieben hättest, im Sinne von Bjoerk ist diese Matrix singulär (vielleicht noch mit 'mem Smiley) hätte man es als harmlose Spinnerei nehmen können, so wie 42% schwanger.
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Übergabe einer Matrix an Unterprogramm

  Alt 25. Aug 2011, 17:52
Bleib mal locker, kein Grund unfreundlich zu werden. Eine Matrix ist dann singulär, wenn sie keine Inverse hat. Mag sein, daß deine Matrix eine Inverse hat, man kann Sie aber nicht mit dem Gauß des TE berechnen, das war alles, was ich sagen wollte...

Geändert von Bjoerk (25. Aug 2011 um 18:13 Uhr) Grund: Edit
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz