Mnożenie macierzy

Aldonix

Jest to mój pierwszy artykuł ma 4programmers.net więc proszę mnie oszczędzić i przymrużyć oko na wszelkie błędy. Artykuł ten jest poświęcony mnożeniu macierzy. Algorytm taki był mi pilnie potrzebny, ale niegdzie nie mogłem go znaleźć. Przeszukałem całe forum na 4programmers.net i nic. Postanowiłem napisać go sam. Oto co uzyskałem.

Poniższy program mnoży dwie macierze dowolnych rozmiarów A i B do macierzy wynikowej C.
Rozmiary macierzy ustawiane są z poziomu kodu. Całość można oczywiście jeszcze bardziej udoskonalić łącznie z podawaniem ilości wierszy i kolumn macierzy oraz ich elementów.
Należy też pamiętać o tym, że podczas podawania rozmiarów macierzy liczba kolumn macierzy pierwszej (A) musi być równa liczbie wierszy macierzy drugiej (B) aby mnożenie mogło nastąpić. Program został przed tym błędem zabezpieczony i jak wartości te są różne wyświetla komunikat.

Na formę wrzuć komponent Memo1 i przycisk Button1. Kliknij dwukrotnie na przycisk i wstaw najpierw przed begin poniższy kod:

var
  A  : array of array of Real;
  B  : array of array of Real;
  C  : array of array of Real;  
  i,j,k,l : Integer;
  suma : Real;
  w1,k1,w2,k2 : Integer;

Teraz trochę komentarza. Zmienne A,B,C są typu tablicowego, są tablicami dwu wymiarowymi. Ich rozmiar jest podawany dynamicznie w czasie działania programu. Zmienne i,j,k,l to zmienne do indeksowania obu macierzy. Suma to zmienna zawierająca sumę iloczynów odpowiednich elementów. Natomiast zmienne w1,k1,w2,k2 to odpowiednie wiersze i kolumny macierzy pierwszej (A) i drugiej (B).

Między begin a end; umieśćcie poniższy kod:

w1 := 7;
k1 := 6;
w2 := 6;
k2 := 9;


setlength(A,w1); //wiersze A
for i:= Low(A) to High(A) do setlength(A[i],k1); //kolumny A

setlength(B,w2); //wiersze B
for i:= Low(B) to High(B) do setlength(B[i],k2); //kolumny B

setlength(C,w1); //wiersze C
for i:= Low(C) to High(C) do setlength(C[i],k2); //kolumny C




//WSTAWIANIE ELEMENTÓW

for i := Low(A) to High(A) do
   for j := Low(A[0]) to High(A[0]) do
      A[i,j] := i+j;

for i := Low(B) to High(B) do
   for j := Low(B[0]) to High(B[0]) do
      B[i,j] := i+j+100;

Memo1.Clear;



if k1 = w2 then //sprawdzanie warunku odnosnie rozmiaru
   begin
        //Mnorzenie macierzy
        i:=0;k:=0;l:=0;j:=0;
        for i := Low(A) to High(A) do
            begin
                 while l <= High(B[0]) do
                       begin
                            suma := 0;
                            k := 0;

                            for j:=Low(A[0]) to High(A[0]) do
                               begin
                                    suma := suma + A[i,j]*B[k,l];
                                    inc(k);
                               end;
                            C[i,l] := suma;
                            inc(l);
                       end;
                 l := 0;
            end;

   Memo1.Lines.Add('Macierz A');
   Memo1.Lines.Add('');

   for i:= Low(A) to High(A) do
       for j := Low(A[0]) to High(A[0]) do
           Memo1.Lines.Add('A[' + IntToStr(i+1) + ',' + IntToStr(j+1) + ']=' + FloatToStr(A[i,j]));

   Memo1.Lines.Add('');
   Memo1.Lines.Add('');
   Memo1.Lines.Add('');
   Memo1.Lines.Add('Macierz B');
   Memo1.Lines.Add('');

   for i:= Low(B) to High(B) do
       for j := Low(B[0]) to High(B[0]) do
           Memo1.Lines.Add('B[' + IntToStr(i+1) + ',' + IntToStr(j+1) + ']=' + FloatToStr(B[i,j]));

   Memo1.Lines.Add('');
   Memo1.Lines.Add('');
   Memo1.Lines.Add('');
   Memo1.Lines.Add('Macierz C=AxB');
   Memo1.Lines.Add('');

   for i:= Low(C) to High(C) do
       for j := Low(C[0]) to High(C[0]) do
           Memo1.Lines.Add('C[' + IntToStr(i+1) + ',' + IntToStr(j+1) + ']=' + FloatToStr(C[i,j]));
end
else Showmessage('Mnożenie macierzy nie jest wykonalne, liczba kolumn macierzy pierwszej musi być równa liczbie wierszy macierzy drugiej !!!');

Poniższy kod:

w1 := 7;
k1 := 6;
w2 := 6;
k2 := 9;

określa ilość wierszy i kolumn macierzy. Macierz A ma rozmiar 7x6 a B 6x9. Otrzymana macierz C będzie miała rozmiar 7x9.

setlength(A,w1); //wiersze A
for i:= Low(A) to High(A) do setlength(A[i],k1); //kolumny A

Polecenie setlength(A,w1); określa ilość wierszy naszej macierzy a następnie pętla for każdemu wierszowi nadaje również odpowiedni rozmiar równy ilości kolumn tworząc w ten sposób macierz o odpowiednich wymiartach.

Dalsza część to wstawianie elementów. Do macierzy wstawiane są elementy równe sumie indeksu i i j.

Kolejna część to już samo mnożenie macierzy. Mnożenie następuje element po elemencie, a wynik mnożenia cząstkowego jest dodawany do zawartości zmiennej suma. Otrzymana wartość jest wstawiana w odpowiednie miejsce w tablicy wyjściowej.

Ostatnia część kodu to tylko wyświetlenie otrzymanych tablic w komponencie Memo1.

To tyle odnośnie mnożenia. Zapraszam do odwiedzenia mojej strony WWW.

4 komentarzy

Rzucił mi się w oczy rażący błąd ortograficzny w komentarzu w kodzie:

//Mnorzenie macierzy

Ładnie i treściwie - piąteczka ;0

to chyba do gotowców raczej niż do artykułów

Spoko. Ładnie napisane jak na pierwszy tekst...