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.
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...