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)

0 komentarzy