![]() |
Übergabe einer Matrix an Unterprogramm
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:
Delphi-Quellcode:
der Quelltext meines Unterprogramms sieht dabei so aus:
Inverse(0, zeilen, spaltengauss, matgauss);
Delphi-Quellcode:
so wenn ich das Programm starte, werden mir keine Fehler gemeldet. Wenn ich nun eine beliebige Matrix eingebe (angenommen, die obige, also
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; |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! |
AW: Übergabe einer Matrix an Unterprogramm
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; |
AW: Übergabe einer Matrix an Unterprogramm
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. |
AW: Übergabe einer Matrix an Unterprogramm
so ich habe meinen algorithmus jetzt optimiert. und mein unterprogramm enthält folgenden Quelltext:
Delphi-Quellcode:
mit der typdeklaration:
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;
Delphi-Quellcode:
in meiner ButtonInverse.onClick procedure erstelle ich die matrix matgauss, die vor der übergabe, wie folgt aussieht:
TMatrixgauss = array[0..5,0..10]of Double;
|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
Delphi-Quellcode:
, wenn ich eine 3 x 3 matrix eingebe, in meinem Stringgrid folgendes Ergebnis erhalte(zeilen hat den wert 3, spaltengauss 6)
Inverse(0,zeilen,spaltengauss,matgauss);
|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? |
AW: Übergabe einer Matrix an Unterprogramm
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; |
AW: Übergabe einer Matrix an Unterprogramm
Zitat:
Code:
0 1
2 0 |
AW: Übergabe einer Matrix an Unterprogramm
Zitat:
Zitat:
Delphi-Quellcode:
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...
for i :=spaltengauss - 1 downto a begin
matgauss[a,i]:=matgauss[a,i]/matgauss[a,a]; end; |
AW: Übergabe einer Matrix an Unterprogramm
Zitat:
|
AW: Übergabe einer Matrix an Unterprogramm
Zitat:
|
AW: Übergabe einer Matrix an Unterprogramm
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...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz