domingo, 3 de abril de 2011

Cálculo do Determinante e Inversa de uma Matriz

O programa abaixo foi desenvolvido no compilador Dev-Pascal, e calcula o Determinante e a Inversa de uma Matriz (até Ordem 10).


Download do Código em Pascal e Executável do Programa:  

http://www.4shared.com/file/6gXDxoBC/Determinante_Inversa.html

Download do Compilador Dev-Pascal: http://www.bloodshed.net/devpascal.html



Código:

Program Matriz_inversa;
 uses crt;
 Var
 a, inversa : Array[1..10,1..10] Of Real; //se desejar uma matriz maior, basta criar arrays maiores//
 aux : Array[1..10] Of Real;
 i, j, n, yi, ji, gi, ii, ipivo, k, sinaldet : Integer;  // i's sao variaveis auxiliares//
 m, pivo, det : Real;
 resposta : String[1];
 erro : Boolean;

Begin

Repeat
 Repeat
 Clrscr;
 Textcolor (White);
 Writeln ('Calculo do Determinante e Inversa de uma Matriz A');
 Writeln;
 Write ('Digite a ordem do sistema (n), no maximo n=10: ');
 Readln (n);
 until n >= 2;
  //le os coeficientes da matriz A//
 for j:=1 to n do
 begin
 Repeat
 clrscr;
 Writeln ('Matriz A');
 Writeln;
 Writeln ('Digite os elementos da coluna ',j,' da matriz A:');
 Writeln;
 for i:=1 to n do
 begin
 Write('a[',i,'x',j,']= ');
 readln(a[i,j]);
 end;
 writeln;
 writeln;
  Textcolor (White);
  Write ('Confira os valores digitados, estao corretos? (digite s=sim, n=nao): ');
  Readln (resposta);
 Until (resposta = 'S') Or (resposta = 's');
 end;

 Clrscr;
 For i:=1 To n Do   //Para calcular a Inversa, esta Matriz inicia como uma Matriz Identidade//
 Begin             //e depois sofrera as mesmas operacoes elementares que a Matriz inicial//
   For j:=1 To n Do
   inversa[i,j] := 0;                    

   inversa[i,i] := 1;
 End; 

 Clrscr;
 
  //Metodo da eliminacao de Gauss (Triangularizacao)//
 
   k := 1; //Passo//
   sinaldet := 1; //A variavel sianaldet servira para guardar o sinal original do determinante da matriz inicial//
   erro := False; //A variavel erro se tornara True caso haja erros de divisao por zero//
  
  For j:=1 To n Do  
   Begin
     For i:=k+1 To n Do
     Begin
     
        pivo := Abs(a[j,k]);     //Pivoteamento Parcial//
       ipivo := j;              //Encontra em qual linha da coluna k esta o maior elemento//    
        For ii:=j to n Do
        Begin
         If Abs(a[ii,k]) > pivo Then
          Begin
           pivo := a[ii,k];
           ipivo := ii;
          End;
        End;
       
        If ipivo <> j Then //Se ipivo = j e porque o maior elemento ja esta na linha do pivo, e a permutacao nao e necessaria// 
        Begin
         For ji:=1 to n Do     //Permuta as linhas necessarias para o pivoteamento parcial//
         Begin
    aux[ji] := a[j,ji];
    a[j,ji] := a[ipivo,ji];
    a[ipivo,ji] := aux[ji];
    aux[ji] := inversa[j,ji];
    inversa[j,ji] := inversa[ipivo,ji];
    inversa[ipivo,ji] := aux[ji];
 End;

         If ((ipivo-j) MOD 2) <> 0 Then
         Begin sinaldet := sinaldet*(-1); End; //A cada troca de linha o sinal do determinante da matriz triangularizada inverte o sinal//
  End;
   
        If a[j,j] <> 0 Then   //Evita erros de divisao por zero//
        Begin
         m := -1*(a[i,j]/a[j,j]);
         For ji:=1 To n Do
         Begin
          a[i,ji] := a[i,ji] + (m*(a[j,ji]));
          inversa[i,ji] := inversa[i,ji] + (m*(inversa[j,ji]));
          End;
         End
         Else
         erro := True; //Se erro = True, o determinante e igual a zero//  
        
     End;
     k := k + 1; 
   End;
  
  
    //Calculo do Determinante//
   
    If erro = True Then
    det := 0
    Else
    Begin
     det := a[1,1];
   
     For ii:=2 To n Do      //Multiplica os outros elementos da diagonal principal da matriz triangularizada//
     det := det*a[ii,ii];
   
     det := det*sinaldet;  //Determina o sinal do determinante//
     If det = 0 Then //Evita a impressao do absurdo 'menos zero'//
      det := 0;
    End;
   
   
    //Calculo da Inversa//
   
   
  If det <> 0 Then  //Se o determinante for igual a zero a Matriz nao possui Inversa//
  Begin
      erro := False;
      k := n-1;
    
    //Metodo de Gauss-Jordan aplicado para o calculo da Inversa da Matriz//

     For j:=n Downto 2 Do
     Begin
       For i:=k Downto 1 Do
       Begin
       If a[j,j] <> 0 Then   //Evita erros de divisao por zero//
         Begin
          m := -1*(a[i,j]/a[j,j]);
          For ji:=1 To n Do
          Begin
           a[i,ji] := a[i,ji] + (m*(a[j,ji]));
           inversa[i,ji] := inversa[i,ji] + (m*(inversa[j,ji]));
           End;
          End
          Else
          erro := True; //Se erro = True, haveria erro de divisao por zero no metodo de Gauss-Jordan//
       End;
       k := k-1;
    End;
   
    For i:=1 To n Do
    Begin
     For j:=1 To n Do
      inversa[i,j] := inversa[i,j] / a[i,i];
   
     a[i,i] := 1; //O equivalente a atribuir a[i,i]/a[i,i]//
    End;
   
  End;


 
   //Imprime na tela o resultado//
  
   Textcolor (White);
   Writeln ('Determinante da Matriz = ', det:0:4);
   Writeln;
  
   If erro = False Then  //se erro = False e porque a Inversa foi calculada//
   Begin
    Gotoxy (1,4);
    Textcolor (White);
    Writeln ('Matriz Inversa:');

    Gotoxy (1,6);
    For gi:= 1 To (2*n)-1 Do //Desenha a grade esquerda da matriz Inversa//
    Writeln (#179:2);

    yi := 6;
    For i := 1 To n Do
     Begin
      Gotoxy (4, yi);
      For j := 1 To n Do
       Begin
       Textcolor (Yellow);
        Write (inversa[i,j]:0:4, ' '); //Escreve os coeficientes da matriz Inversa na tela//
       End;
        yi := yi + 2;
     End;
   End;
  Textcolor (White);
  Writeln;
  Writeln;
  Writeln;
  Write ('Deseja reiniciar o programa? (S/N): ');
  Read (resposta);
Until (resposta <> 'S') And (resposta <> 's');   
End.


Se desejarem fazer qualquer melhoria, correção de algum eventual erro, fiquem a vontade! ; )

Nenhum comentário:

Postar um comentário