Wyznaczniki macierzy
Adam.Pilorz
Jako, że pojawił się na forum temat z pytaniem o rozwiązanie problemu związanego z macierzami postanowiłem wkleić tutaj dość prostą bibliotekę liczącą wyznaczniki dowolnej macierzy kwadratowej o rozmiarze >= 2. Oczywiście dałoby się to uprościć do korzystania z macierzy konkretnego roziaru, by nie być zmuszonym do użycia dynamicznych tablic (dostępnych o ile mi wiadomo dopiero od 4 albo 5 wersji Delphi) ani list jednokierunkowych opartych na wskaźnikach, których użycie tutaj jeszcze bardziej zagmatwałoby sprawę.
Mam nadzieję, że kod się sprawdzi i przyda komuś.
unit Wyznaczniki;
interface
type
TWektor = array of Real;
TMacierz = array of TWektor;
procedure WyswietlMacierz(Macierz: TMacierz);
function CzyMacierzKwadratowa(Macierz: TMacierz): Boolean;
function PodMacierz(Macierz: TMacierz; i, j: Integer): TMacierz;
function Wyznacznik(Macierz: TMacierz; var W: Real): Boolean;
implementation
procedure WyswietlMacierz(Macierz: TMacierz);
var
I, J: Integer;
begin
For I:=0 to Length(Macierz)-1 do for J:=0 to Length(Macierz[I])-1 do begin
If J=0 then write('|');
Write(' '+FloatToStr(Macierz[I][J]));
If J=Length(Macierz[I])-1 then WriteLn(' |');
end;
end;
function CzyMacierzKwadratowa(Macierz: TMacierz): Boolean;
//Funkcja sprawdza, czy macierz podana w argumencie jest macierzą kwadratową.
var
i, rozm: Integer;
begin
Result:=True;
rozm:=Length(Macierz);
if rozm<2 then Result:=False;
for i:=0 to rozm-1 do if Length(Macierz[i])<>rozm then Result:=False;
end;
function PodMacierz(Macierz: TMacierz; i, j: Integer): TMacierz;
//Funkcja zwraca macierz po "usunięciu" i-tego wiersza i j-tej kolumny
var
k, l, rozm: Integer;
begin
rozm:=Length(Macierz)-1;
SetLength(Result, rozm);
For k:=0 to rozm-1 do begin
SetLength(Result[k], rozm);
For l:=0 to rozm-1 do begin
if (k<i) and (l<j) then Result[k][l]:=Macierz[k][l]
else if (k<i) then Result[k][l]:=Macierz[k][l+1]
else if (l<j) then Result[k][l]:=Macierz[k+1][l]
else Result[k][l]:=Macierz[k+1][l+1];
end;
end;
end;
function Wyznacznik(Macierz: TMacierz; var W: Real): Boolean;
//Funkcja oblicza wyznacznik macierzy. W rezultacie jest True, jesli wyznacznik uda sie policzyc, False, jesli cos jest zle
var
i: Integer;
TmpW: Real;
rozm: Integer;
begin
if CzyMacierzKwadratowa(Macierz) then begin
rozm:=Length(Macierz);
If rozm=2 then begin
W:=Macierz[0][0]*Macierz[1][1]-Macierz[1][0]*Macierz[0][1];
Result:=True;
end
else if rozm=3 then begin
W:=((Macierz[0][0]*Macierz[1][1]*Macierz[2][2])+
(Macierz[0][1]*Macierz[1][2]*Macierz[2][0])+
(Macierz[0][2]*Macierz[1][0]*Macierz[2][1]))-
((Macierz[2][0]*Macierz[1][1]*Macierz[0][2])+
(Macierz[2][1]*Macierz[1][2]*Macierz[0][0])+
(Macierz[2][2]*Macierz[1][0]*Macierz[0][1]));
Result:=True;
end
else begin
W:=0;
Result:=True;
For i:=0 to rozm-1 do begin
If not Wyznacznik(PodMacierz(Macierz,0,i),TmpW) then Result:=False
else if (i mod 2)=0 then W:=W+TmpW*Macierz[0][i]
else W:=W-TmpW*Macierz[0][i];
end;
end;
end
else Result:=False;
end;
end.
Funkcje w skrócie mają wyjaśnienie, co robią, jak coś będzie niejasne, albo nie będzie działać, to piszcie :]
//Update: 17.11.2005 18:55
Okazało się, że coś się chrzaniło w funkcji PodMacierz. Przepisałem jąod nowa i wygląda, ze działa. Dodałem też procedurkę do wyświetlania macierzy, może się przydać przy testach (do użycia normalnego trzebaby ją trochę podrasować, bo nie zwraca uwagi na długość liczb)