Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Matrix multiplikation, help (https://www.delphipraxis.net/168707-matrix-multiplikation-help.html)

Jonas Shinaniganz 5. Jun 2012 18:01

Matrix multiplikation, help
 
Mein Gehirn ist einfach zu klein um mein Projekt zum Abschluss zu bringen... bin ein bisschen deprimiert grade.

In meinem derzeitigen Programm soll der Benutzer 2 Matritzen eingeben, in Tabellen.
Die Tabellen sind in Spaltenanzahl und Zeilen Identisch und auch die Tabelle für sich hat immer genau so viele Spalten wie Zeilen.

Wenn der User die Eingaben erledigt hat wird jede Tabelle in ein 2D Array geschoben mit dem Ich dann weiter rechne.

Dann gibt es noch einen Ergebnis Array.

Also Ich habe folgendes Problem:

Array 1
10 3 5
3 3 5
8 7 9

Array 2
23 5 1
1 4 5
8 7 7

Ich brauche ne Schleife die jeden Wert aus meinen Array entsprechend der Gesetze der Matritzenmultiplikation berechnet. Wichtig: Ich möchte dass das ganez Skalier bar ist... d.h.
Es kann auch eine 1x1 oder 10x10 Matrix - Combo vorliegen und nicht nur dieses 3x3 Format.

Jetz muss man ja 10x23 + 3x1 + 8x8 ! 10x5 + 10x4 + 10x7 ! undsoweiter rechnet um dann zum Schluss:

Array Ergebnis
bla bla bla
bla bla bla
bla bla bla

Rauszubekommen... Ich hab mir das ganze versucht zu überlegen finde es aber derbe kompliziert grade...

Meine Schleife liefert nur einen Teil der Werte und sieht folgendermaßen aus:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender : TObject);
var
  I : Integer;
  I2: Integer;

  Ergebnis : Double;
  I3 : Integer;
begin
                       
  GridToArray(StringGrid1, MatrixData.ValueArray1);
  GridToArray(StringGrid2, MatrixData.ValueArray2);

  // einfach erstmal groß genug machen...
  SetLength(MatrixData.ResultArray, 20, 20);

  I := 0;
  while I <= High(MatrixData.ValueArray1) do
  begin
    I2 := 0;
    while I2 <= High(MatrixData.ValueArray1[I]) do
    begin

      Ergebnis := 0;
      for I3 := 0 to High(MatrixData.ValueArray2[I]) do
      begin
        Ergebnis := Ergebnis + (MatrixData.ValueArray1[I2, I3] * MatrixData.ValueArray2[I3, I2]);
      end;

      MatrixData.ResultArray[I, I2] := Ergebnis;
      inc(I2);
    end;
  inc(I);
  end;


end;
Würde mich auch freuen wenn jemand beschreiben könnte wie Ich mich solchen Problemen Gedanklich annähern kann, bin erst 22Jahre Alt also noch nicht alles verloren hoffe ich, gruß

jfheins 5. Jun 2012 19:47

AW: Matrix multiplikation, help
 
Ich würde das ganze in eine Funktion auslagern.
Dann für alles drei for Schleifen benutzen.
Zudem sind die Bezeichner i, i2, i3 ... unkonventionell. Normalerweise nimmt man i, j, k, ...
aber hier kann man auch row und col verwenden, dann ist das auch besser lesbar ;-)

Also mit den Änderungen:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender : TObject);
var
   I : Integer;
   I2: Integer;

   Ergebnis : Double;
   I3 : Integer;
begin
                       
   GridToArray(StringGrid1, MatrixData.ValueArray1);
   GridToArray(StringGrid2, MatrixData.ValueArray2);

   // TODO: Prüfen ob Multiplikation möglich
   
   // Größe berechnen
   Rows := Length(MatrixData.ValueArray1);
   Cols := Length(MatrixData.ValueArray2[0]);
   
   // einfach erstmal groß genug machen...
   // Nö, lieber direkt "richtig machen"
   SetLength(MatrixData.ResultArray, Rows, Cols);

   for row := 0 to Rows-1 do
   begin
    for col := 0 to Cols-1 do
     begin
       Ergebnis := 0;
       for i := 0 to High(MatrixData.ValueArray2) do // Grenze verändert
       begin
         Ergebnis := Ergebnis + (MatrixData.ValueArray1[col, i] * MatrixData.ValueArray2[i, col]); // Siehst du den Fehler?
       end;
       MatrixData.ResultArray[row, col] := Ergebnis;
     end;
   end;
end;
Der fehler sollte jetzt einfacher zu erkennen sein ;-)

Aphton 5. Jun 2012 20:47

AW: Matrix multiplikation, help
 
Siehe Codeschnipsel von mir

Memnarch 6. Jun 2012 21:47

AW: Matrix multiplikation, help
 
Sofern nichts dagegen spricht, würde ich klassen draus machen. HAbe für meinen softwarerenderer Klassen für 4DMatritzen, 3d und 4D arrays. Entsprechende methoden inbegriffen.
Machts um einiges einfacher wenn man damit öfters hantieren muss.

MFG
Memnarch

jaenicke 7. Jun 2012 06:07

AW: Matrix multiplikation, help
 
Noch sinnvoller sind bei solchen Typen auch vor allem Records. Dann kann man die Operatoren auch direkt überladen und dann einfach direkt mit den entsprechenden Variablen rechnen. Das macht insbesondere komplexe Berechnungen sehr viel übersichtlicher. ;-)
Beispiel:
Delphi-Quellcode:
var
  Value1, Value2, MultResult: TMatrix;
begin
  Value1 := '((1, 2, 3), (4, 5, 4), (6, 1, 2))';
  Value2 := '(2, 3, 9)';
  MultResult := Value1 * Value2;
Mit:
Delphi-Quellcode:
  TMatrix = record
  private
    type
      TMatrixArray = array of array of Integer;
      PMatrixArray = ^TMatrixArray;
    var
      FWidth: Integer;
      FHeight: Integer;
      FData: TMatrixArray;
    function GetData: PMatrixArray;
  public
    constructor Create(const AWidth, AHeight: Integer);
    class operator implicit(const AValue: string): TMatrix;
    class operator implicit(const AValue: TMatrix): string;
    class operator Add(const AValue1, AValue2: TMatrix): TMatrix;
    class operator Multiply(const AValue1, AValue2: TMatrix): TMatrix;
    class operator Multiply(const AValue: TMatrix; const AScalar: Integer): TMatrix;
    property Data: PMatrixArray read GetData;
    property Width: Integer read FWidth;
    property Height: Integer read FHeight;
  end;

...


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