Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Determinanten Berechnung (https://www.delphipraxis.net/95086-determinanten-berechnung.html)

krutho 30. Jun 2007 15:43


Determinanten Berechnung
 
Hallo erst einmal. Hab grad mal versucht ein Programm zu schreiben, was die Determinante einer beliebigen Matrix berechnet. Bekomme allerdings eine Fehlermeldung, Fehler liegt augenscheinich an der markierten Stelle. Bin grad zu blöd den Fehler zu entdecken. Könnt ihr mir vielleicht helfen?. Mal so nebenbei ... Kann mann Stringgrids irgendwie umstellen, so dass man ganz normal wie in editfelder schreiben kann?

Delphi-Quellcode:
procedure TForm4.ButtonDetOnClick(Sender:Tobject);
var i,j,n:integer;
    matrixA:T2DMatrix;

Begin
  n:=SG1.ColCount;
  SetLength(matrixA,n,n);
    for i:= 0 to n-1 do
      for j:= 0 to n-1 do
        begin
          matrixA[i,j]:=StrtoFloat(SG1.Cells[j,i]);
        end;
EditDet.text:=FloatToStr(matrixdet(matrixA,n));
end;

function TForm4.MatrixDet(matrixN:T2DMatrix;n:integer):double;
var matrizen:array of T2Dmatrix;
  i,j,k,l:integer;
Begin
  if n =2 then
  begin
    result:= (matrixn[0,0]*matrixn[1,1])-(matrixn[1,0]*matrixn[0,1]);
  end
  else
  begin
  setlength(matrizen,n);
  for i:= 0 to n-1 do
  begin
  l:=0;
    for k:= 0 to n-1 do
      begin
        if i = k
          then

          else
             begin
              for
                j:= 1 to n-1 do
                  begin
                    [color=#0000ff]matrizen[i,j,k]:= matrixN[j,l];[/color]
                  end;
              end;
              l:=l+1;
        end;
    end;
  result:=0;
  for i:= 0 to n-1 do
      begin
        result:=result + (intpower(-1,i)* matrixn[1,i]* matrixdet(matrizen[i],n-1));
      end;
  end;
end;

Relicted 30. Jun 2007 16:01

Re: Determinanten Berechnung
 
huhu!

Zitat:

Kann mann Stringgrids irgendwie umstellen, so dass man ganz normal wie in editfelder schreiben kann?
was meinst du damit? theoretisch kannst du dir vom stringgrid eine eigene klasse ableiten und dir (was auch immer du meinst) selbst bauen.

wenn ich dir einen kleinen tipp geben darf: ich persönlich finde deinen quelltext reichlich unübersichtlich. ein paar kommentare könnten auch nützlich sein :-)

gruß
reli


edit: mal quellcode etwas verleserlicht

Delphi-Quellcode:
procedure TForm4.ButtonDetOnClick(Sender:Tobject);
var
   i,j,n:integer;
   matrixA:T2DMatrix;
begin
  n:=SG1.ColCount;
  SetLength(matrixA,n,n);

  for i:= 0 to n-1 do
  begin
    for j:= 0 to n-1 do
    begin
      matrixA[i,j]:=StrtoFloat(SG1.Cells[j,i]);
    end;
  end;

  EditDet.text:=FloatToStr(matrixdet(matrixA,n));
end;

function TForm4.MatrixDet(matrixN:T2DMatrix;n:integer):double;
var
  matrizen:array of T2Dmatrix;
  i,j,k,l:integer;
Begin
  if n =2 then
  begin
    result:= (matrixn[0,0]*matrixn[1,1])-(matrixn[1,0]*matrixn[0,1]);
  end
  else
  begin
    setlength(matrizen,n);

    for i:= 0 to n-1 do
    begin
      l:=0;
      for k:= 0 to n-1 do
      begin
        if i <> k then
        begin
          for j:= 1 to n-1 do
          begin
            matrizen[i,j,k]:= matrixN[j,l];
          end;
        end;
        inc(l);
      end;
    end;

    result:=0;
    for i:= 0 to n-1 do
    begin
      result:=result + (intpower(-1,i)* matrixn[1,i]* matrixdet(matrizen[i],n-1));
    end;
  end;
end;

krutho 30. Jun 2007 16:05

Re: Determinanten Berechnung
 
Was ich damit meine ist folgendes: Wen man auf ein EditFeld klickt, wird der Cursor darin platziert und man sofort den Inhalt des Editfeldes ändern. Beim einem Stringgrid hingegen wird
nur das angeklickte Feld markiert. Mann kann den Inhalt der Zelle nicht ändern. Liegt das an meiner Version oder warum ist dass so doof?

Zum Quelltext: Ja ist unüresichtlich, geb ich zu. Ist aber auch viel was man bescheiben müsste.

Relicted 30. Jun 2007 16:09

Re: Determinanten Berechnung
 
dafür gibts eine option:

Options -> goAlwaysShowEditor = true (objektinspektor)

und dazu brauchste noch:

Options -> goEditing = true (objektinspektor)


Zitat:

Ist aber auch viel was man bescheiben müsste.
Wenn eine funktion sehr umfangreich zu beschreiben ist dann solltest gerade bei der funktion damit anfangen alles zu beschreiben. spreche da aus erfahrung. weil wenn du dir das projekt nen jahr später nochmal anschaust denkst du dir nur "häääää?! - ok in einer stunde versteh ich wieder was ich getan habe"

krutho 30. Jun 2007 16:47

Re: Determinanten Berechnung
 
Ok, hab den Quelltext jetzt mit ein paar Beschreibungen versehen. Hab vergessen zu erwähnen, dass die Determinante mit Hilfe der Entwicklung nach der ersten Zeile erfolgen soll.
Hoffe ihr habt jetzt etwas mehr Durchblick. falls ihr noch fragen habt oder mehr Hinweise benötigt sagt bescheid.

Delphi-Quellcode:
procedure TForm4.ButtonDetOnClick(Sender:Tobject);
var i,j,n:integer;
    matrixA:T2DMatrix;

Begin {Liest zu berechnende Matrix ein und startet ersten Funktionsaufruf}
  n:=SG1.ColCount;
  SetLength(matrixA,n,n);
    for i:= 0 to n-1 do
      for j:= 0 to n-1 do
        begin
          matrixA[i,j]:=StrtoFloat(SG1.Cells[j,i]);
        end;
EditDet.text:=FloatToStr(matrixdet(matrixA,n));
end;

function TForm4.MatrixDet(matrixN:T2DMatrix;n:integer):double; {Berechnet Determinante einer Matrix mit Entwicklung nach erster Zeile }
var matrizen:array of T2DMatrix; {Array enthält Hilfsmatrizen}
  i,j,k,l:integer;
Begin
  if n =2 then {wenn 2x2 Matrix, dann einfaches Berechnen, ansonsten rekursiver aufruf}
  begin
    result:= (matrixn[0,0]*matrixn[1,1])-(matrixn[1,0]*matrixn[0,1]);
  end
  else
  begin
  setlength(matrizen,n); {Dimension der MAtrix betimmt gleichzeitig Anzahl der
  Hilfsmatrizen}
  {Zuerst müsen Hilfsmatrizen eingelesen werden}
  for i:= 0 to n-1 do    {i= Index der Hilfsmatrix}
  begin
  l:=0;                  {l= zeilenindex der Hilfsmatrizen}

      for k:= 0 to n-1 do {k= Spaltenindex der zu berechnenden Matrix (MatrixN)}
      begin
        if i <> k then
        begin
          for j:= 1 to n-1 do
          begin
            matrizen[i,j,k]:= matrixN[j,l]; {Nacheinander sollen alle Elemente
            einer Spalte k (außer dem ersten) der zu berechnenden Matrix MatrixN in die Spalte l der i ten Hilfsmatrix eingelesen werden}
          end;
        end;
        inc(l); {nach dem einlesen der Splate soll die nächste Spalte der
        Hilfsmatrix betrachtet werden (l wird um eins erhöht)}
      end;
    end;
  result:=0;
  for i:= 0 to n-1 do
      begin
        result:=result + (intpower(-1,i)* matrixn[1,i]* matrixdet(matrizen[i],n-1));
         {Die Determinante einer Matrix ist die Summe der Elemetne der ersten
         Zeile multipliziert mit den Hilfsmatrizen und multipliziert mit
         (-1) hoch i(alternierend)}
      end;
  end;
end;

krutho 1. Jul 2007 13:42

Re: Determinanten Berechnung
 
Hallo nochmal. Habt jetzt selbst ein paar Fehler gefunden und korrigieren können. Die Berechnung an sich läuft jetzt auch, jedoch ist das Ergebnis immer 0, was natürlich nicht sein kann. Nach einigem rumprobieren habe ich herausgefunden, dass der Fehler an den Hilfsmatrizen liegt. Deswegen habe ich eingefügt, dass die erste der Hilfsmatrizen ins ein zweites Stringgrid eingefügt werden soll um zu überpfüfen, was dort drin steht. Dies jedoch funktioniert nicht. Der Compiler meldet einen Fehler beim Lesen der Adresse 00000.... . Was bedeutet dass und was kann man dagegen tun ?
Delphi-Quellcode:
procedure TForm4.ButtonDetOnClick(Sender:Tobject);
var i,j,n:integer;
    matrixA:T2DMatrix;

Begin {Liest zu berechnende Matrix ein und startet ersten Funktionsaufruf}
  n:=SG1.ColCount;
  SetLength(matrixA,n,n);
    for i:= 0 to n-1 do
      for j:= 0 to n-1 do
        begin
          matrixA[i,j]:=StrtoFloat(SG1.Cells[j,i]);
        end;
EditDet.text:=FloatToStr(matrixdet(matrixA,n));
end;

function TForm4.MatrixDet(matrixN:T2DMatrix;n:integer):double; {Berechnet Determinante einer Matrix mit Entwicklung nach erster Zeile }
var matrizen:array of T2DMatrix; {Array enthält Hilfsmatrizen}
  i,j,k,l:integer;
Begin
   result:=0;
  if n =2 then {wenn 2x2 Matrix, dann einfaches Berechnen, ansonsten rekursiver aufruf}
  begin
    result:= (matrixn[0,0]*matrixn[1,1])-(matrixn[1,0]*matrixn[0,1]);
  end
  else
  begin
  setlength(matrizen,n,n-1,n-1); {Dimension der MAtrix betimmt gleichzeitig Anzahl der
  Hilfsmatrizen}
  {Zuerst müsen Hilfsmatrizen eingelesen werden}
  for i:= 0 to n-1 do    {i= Index der Hilfsmatrix}
  begin
  l:=0;                  {l= zeilenindex der Hilfsmatrizen}

      for k:= 0 to n-1 do {k= Spaltenindex der zu berechnenden Matrix (MatrixN)}
        if i <> k then
        begin

          for j:= 1 to n-1 do
          begin
            matrizen[i,j-1,l]:= matrixN[j,k]; {Nacheinander sollen alle Elemente
            einer Spalte k (außer dem ersten) der zu berechnenden Matrix MatrixN in die Spalte l der i ten Hilfsmatrix eingelesen werden}
          end;
            inc(l); {nach dem einlesen der Spalte soll die nächste Spalte der
        Hilfsmatrix betrachtet werden (l wird um eins erhöht)}
        end;
    end;
  for i:= 0 to n-1 do
      begin
        result:=result + (intpower(-1,i)* matrixn[1,i]* matrixdet(matrizen[i],n-1));
         {Die Determinante einer Matrix ist die Summe der Elemente der ersten
         Zeile multipliziert mit den Hilfsmatrizen und multipliziert mit
         (-1) hoch i(alternierend)}

      end;
  end;
 for i:= 0 to n-2 do
  for j:= 0 to n-2 do
    begin
      SG2.Cells[j,i]:=FloatToStr(matrizen[0,i,j]);
    end;
 end;
Vielen Dank für eure Hilfe schon mal im Vorraus.

Relicted 1. Jul 2007 14:20

Re: Determinanten Berechnung
 
Delphi-Quellcode:
var matrizen:array of T2DMatrix; {Array enthält Hilfsmatrizen}
ich gehe mal davon aus das T2DMatrix eine klasse ist?

Delphi-Quellcode:
  setlength(matrizen,n,n-1,n-1); {Dimension der MAtrix betimmt gleichzeitig Anzahl der Hilfsmatrizen}
du setzt zwar die größe des arrays, jedoch hast du noch keine objekte ins array geschoben... was auch die zugriffsverletzung erklären würde :-)
ich versteh zwar den aufruf der setlength nicht.. ich kenne nur setlength( array, größe ).. deins hat wohl ein paar mehr parameter... aber ka hab auch nix überladenes ad hoc gefunden...

hier jedenfalls die lösung falls deine T2DMatrix eine klasse und kein array ist:
Delphi-Quellcode:
for i := 0 to n-1 do
  matrizen[i] := T2DMatrix.Create;
gruß
reli

krutho 1. Jul 2007 14:54

Re: Determinanten Berechnung
 
Ja richtig, T2DMatrix ist eine selbstdefinierte Klasse
Delphi-Quellcode:
 T2DMatrix = array of array of double;
Hab den Fehler jetzt aber schon selbst gefunden, wen es interessiert, er befindet sich
hier:

Delphi-Quellcode:
for i:= 0 to n-1 do
      begin
        result:=result + (intpower(-1,i)* matrixn[0,i]* matrixdet(matrizen[i],n-1));
      end;
statt
Delphi-Quellcode:
for i:= 0 to n-1 do
      begin
        result:=result + (intpower(-1,i)* matrixn[1,i]* matrixdet(matrizen[i],n-1));
      end;
Vielen dank für eure Hilfe :thumb:
Da die Berechnung jetzt klappt ist mir das mit dem Überfprüfen der Hilfsmatrizen egal, die müssen ja stimmen.

Auch richtig: Der SetLength Aufruf bestimmt zuerst die Anzahl der Elemente des ersten Arrays, dann die des zweiten und so weiter. "Matrizen" ist ja ein Array von Zweidimensionalen Arrays.

Relicted 1. Jul 2007 14:55

Re: Determinanten Berechnung
 
ah okay wieder was dazugelernt :-) hab das glück selten mit mehrdimensionalen arrays zu arbeiten :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:03 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