Newsgroup: it.comp.lang.pascal
Titolo: calcolo del determinante di una matrice

No, se puoi aiutarmi...
Grazie
---------------
    Si, e' possibile :-)
ed e' esattamente il procedimento che fai a mano
quando calcoli il determinante
mmmh ah questo punto la sai fare da solo ? :-)
--
Dreadnaut (dn)
drea...@liberoDALLASPAM.it
(Life would be easier if I had the source code)
---
Ciao a tutti,
chi sa dirmi come impostare un programma che calcoli ricorsivamente il
determinante di una matrice quadrata?
Cioč, č possibile impostare una funzione o procedura che calcoli, per
esempio, il determinante di una matrice di 4 ordine passando attraverso il
complemento algebrico (che sarebbe una matrice di 3 ordine) di ogni elemento
della prima riga?
Grazie e ripondetemi presto!

hiihihihi, *solo* per stavolta ok  :-)
 const
  MAXSIZE = 8;
 type
  matdata = array[1..MAXSIZE*MAXSIZE] of integer;
  pMatrice = ^Matrice;
  Matrice = record
             size : byte;
             data : ^matdata;
            end;
  procedure m_set(m: pMatrice; x,y,value: integer);
   begin
    m^.data^[x + (y-1)*m^.size] := value;
   end;
  function m_new(size: integer): pMatrice;
   var
    tmp : pMatrice;
    x,y : integer;
   begin
    New(tmp);
    GetMem(tmp^.data, size*size shl 1);
    { la dimensione e' n°elem * dim_integer (cioe' * 2 = shl 1) }
    tmp^.size := size;
    for y := 0 to size-1 do
     for x := 1 to size do
      tmp^.data^[x+y*size] := 0;
    m_new := tmp;
   end;
  function m_minore(z: pMatrice; x,y,size: integer): pMatrice;
   var
    tmp    : pMatrice;
    m,n,bx : integer;
   begin
    tmp := m_new(size);
    bx  := x;
    Dec(y);
    for m := 0 to size-1 do
     begin
       y := y mod z^.size;
       for n := 1 to size do
        begin
         if x > z^.size then x := 1;
         tmp^.data^[n+m*size] := z^.data^[x+y*z^.size];
         Inc(x);
        end;
      x := bx;
      Inc(y);
     end;
    m_minore := tmp;
   end;
  procedure m_print(z: pMatrice);
   var
    m,n : integer;
   begin
    writeln('- Size: ',z^.size);
    for m := 0 to z^.size-1 do
     begin
      for n := 1 to z^.size do
       write (z^.data^[n+m*z^.size]:5,' ');
      writeln;
     end;
   end;
 function m_det(m: pMatrice): integer;
  var
   min   : pMatrice;
   sign,
   tmp,n : integer;
  begin
   if m^.size = 2 then
    m_det := m^.data^[1] * m^.data^[4] - m^.data^[2] * m^.data^[3]
   else
    begin
     tmp := 0;
     sign := +1;
     for n := 1 to m^.size do
      begin
       writeln('-',n);
       min := m_minore(m,n+1,2,m^.size - 1);
       inc(tmp, sign * m^.data^[n] * m_det( min ));
       Dispose(min);
       sign := sign * -1;
      end;
     m_det := tmp;
    end;
  end;
 {  -- - giusto per test - -- }
 var
  a  : pMatrice;
 begin
{ facciamoci una bella matrice diagonale 4x4}
  a := m_new(4);
  m_set(a, 1, 1, 1);  { matrice, x, y, valore }
  m_set(a, 2, 2, 2);
  m_set(a, 3, 3, 3);
  m_set(a, 4, 4, 4);
  m_print(a); {scriviamola }
  writeln ('det:',m_det(a)); {e ora il determinante }
 end.
non e' il massimo ma mi sembra funzioni... cioe' non l'ho provata eccessive
volte e l'ho fatto un po' cosi' di fretta :-) e poi il fatto di creare nuove
matrici per i minori non e' molto esaltante e sarebbe evitabile...
Ovvio che funge solo per matrici quadrate...
se hai ancora dubbi sul prog al max per mail :-)
ciao
P.S. inizialmente volevo farlo ad oggetti... ma li puoi usare ?
       se si viene decisamente meglio :-)


mmmh non funzia  :-)


Beccati questo.
program determinante;
uses crt;
const eps=0.00001;
numrig=10;
numcol=10;
arr=3;
type matrice=array[1..numrig,1..numcol] of real;
var a:matrice;
i,j,n,m,s:integer;
err:boolean;
procedure leggimatrice(var mat:matrice;n:integer);
var i,j:integer;
begin
for i:=1 to n do
for j:=1 to n do
readln(mat[i,j]);
clrscr;
end;
procedure triangola(var a:matrice; n:integer; var imposs:boolean; var
scamb:integer);
var i,h,j,k,l:integer;
q:real;
begin
scamb:=1;
imposs:=false;
for i:=1 to (n-1) do
begin
     if (abs(a[i,i])) < eps then
     begin
          l:=i+1;
          while (l<=n) and ((abs(a[i,l])) < eps) do
          l:=l+1;
          if (l=n+1) then imposs:=true;
          for h:=1 to n do
          begin
               q:=a[h,i];
               a[h,i]:=a[h,l];
               a[h,l]:=q;
          end;
          scamb:=scamb*(-1);
          if imposs=false then writeln('scambia la colonna ',i,' con la
colonna ',l);
          end;
          if imposs=false then
          for k:=i+1 to n do
          begin
               q:=-a[k,i]/a[i,i];
               for j:=1 to n do
               a[k,j]:= a[k,j]+q*a[i,j];
           end;
     end;
if abs(a[n,n]) < eps then imposs:=true;
end;
function determ(a:matrice;err:boolean;n,segno:integer): real;
var i:integer;
d:real;
begin
if err then d:=0 else
begin
d:=1;
for i:=1 to n do
d:=d*a[i,i];
d:=d*segno;
end;
determ:=d;
end;
procedure scrivimatrice(var a:matrice; n:integer);
const ar=2;
var i,j:integer;
begin
for i:=1 to n do
begin
for j:=1 to n do
write(a[i,j]:8:ar,' ');
writeln;
end;
end;
begin
clrscr;
write('Inserisci l'' ordine del determinante (n<=10) ');readln(n);
writeln;
writeln('Ora inizia a soffrire mettendo i valori del determinante');
leggimatrice(a,n);
writeln;
writeln('Hai inserito questa matrice');
scrivimatrice(a,n);
writeln;
triangola(a,n,err,s);
if err then writeln('Non puo'' essere triangolata (arrangiati da solo)')
else
begin
writeln;
writeln('La matrice triangolata S');
scrivimatrice(a,n);
writeln;
end;
writeln('Determinante= ',determ(a,err,n,s):0:arr);
repeat until keypressed;
end.
Puoi anche metterne di ordine superiore.
Ciao

Grazie per avermi risposto, ma il programma dovrebbe funzionare con tutte le
matrici quadrate, senza necessariamente ridurle ad una triangolare.  La
parte più difficile per me è trovare il complemento algebrico di un
elemento, cioè il determinante della matrice trovata escludendo  gli
elementi della riga e della colonna a cui appartiene l'elemento cosiderato.
Se potete aiutarmi...
Grazie.
------
Ciao a tutti,
chi sa dirmi come impostare un programma che calcoli ricorsivamente il
determinante di una matrice quadrata?
Cioè, è possibile impostare una funzione o procedura che calcoli, per


 matrici quadrate
Il mio programma calcola i determinanti di matrici n*n di qualsiasi ordine.
Ho usato la triangolazione perchè mi è sembrato un metodo efficace e
semplice.Esiste una proprietà che dice che il determinante di una matrice
triangolata(dove sotto una diagonale i termini sono tutti 0) è dato dal
prodotto dei termini della diagonale.
Se però devi usare il "procedimento manuale" usando un algoritmo ricorsivo
allora la cosa si fa piu' complicata.
Ti posto la nuova versione che ho modificato un po':
program determinante;
uses crt;
type matrice=array[1..19,1..19] of real;
var mat:matrice; ordine,segno,f:byte; det:real;
procedure inserisci(var a:matrice;n:byte);
var i,j:byte;
begin
for i:=1 to n do
for j:=1 to n do
begin
write('Inserisci il dato di posto [',i,',',j,'] ');readln(a[i,j]);
end;
end;
procedure scambia(var d:matrice;pos,n:byte);
var r,c:byte;app:real;
begin
for r:=pos to n do begin
     app:=d[r,pos];
     d[r,pos]:=d[r,pos+1];
     d[r,pos+1]:=app;
end;
end;
procedure triangola(var a:matrice; n:byte);
var h,i,j,k:byte; divi:real;poss:boolean;
begin
for i:=1 to (n-1) do
begin(*1*)
     det:=det*a[i,i];
     poss:=true;
     if a[i,i]=0 then
     begin(*2*)
          for j:=i+1 to n do
          if a[i,j]<>0 then
          begin(*3*)
               scambia(a,i,n);
               segno:=segno+1;
               poss:=true;
               break;
          end(*3*)
          else
          poss:=false;
          if poss<>true then det:=0;
     end;(*2*)
     if poss=true then
     begin(*4*)
          for k:=i+1 to n do
          begin(*5*)
               divi:=-((a[k,i])/(a[i,i]));
               for h:=i to n do
               a[k,h]:=(a[i,h]*divi)+a[k,h];
          end;(*5*)
     end;(*4*)
   end;(*1*)
    det:=det*a[n,n];
if ((segno mod 2)<>0) then det:=-det;
end;
procedure scrivi(a:matrice;n:byte);
var i,j:byte;
begin
for i:=1 to n do
begin
for j:=1 to n do
begin
if i=j then textcolor(3) else textcolor(7);
write(a[i,j]:0:2,' ');
end;
writeln;
writeln;
end;
textcolor(7);
end;
begin
det:=1;
f:=2;
clrscr;
writeln('Questo programma calcola il valore dei determinanti');
repeat
write('Inserisci la dimensione ');readln(ordine);
until (ordine>0) and (ordine<=19);
inserisci(mat,ordine);
clrscr;
scrivi(mat,ordine);
triangola(mat,ordine);
writeln;
scrivi(mat,ordine);
if frac(det)=0 then f:=0;
writeln('Determinante= ',det:0:f);
repeat until keypressed;
end.

Beh no e' cosi' complesso:
crei una nuova matrice prendendo tutti gli elem.
della prima ma saltando una coppia di coordinate
dato un elemento <a,b>
xx,yy : integer;
xx := 1;
yy := 1;
for x := 1 to dimx do
 begin
   if x = a then continue;
   inc(xx);
   for y := 1 to dim y do
    begin
       if y = b then continue;
       inc(yy);
       nuovamat(xx,yy) := vecchiamat(x,y)
   end;
end;
direi... adesso non ho provato ma mi sembra funga
