Mostrando postagens com marcador Sistemas Lineares. Mostrar todas as postagens
Mostrando postagens com marcador Sistemas Lineares. Mostrar todas as postagens

terça-feira, 12 de abril de 2011

Eliminação de Gauss com Pivoteamento Total - Resolução de Sistemas Lineares

O programa abaixo foi desenvolvido no compilador Dev-Pascal, e utiliza a Eliminação de Gauss para o Escalonamento (Triangularização Superior da Matriz Ampliada) e Pivoteamento Total, para evitar pivôs nulos, resolvendo o sistema equivalente por retrossubstituição.


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

http://www.4shared.com/file/TuoeSXKr/Eliminacao_Gauss_Pivot_Total.html

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


Código:


Program Gauss_pivoteamento_total;
 Uses crt;
 Var
 a : Array[1..100,1..100] Of Real; //se desejar uma matriz maior, basta criar arrays maiores//
 x, b : Array[1..100] Of Real;
 o:array[1..100] of integer;
 i, j, n, ji, k, h, posx, posl, posc : Integer;
 m, soma, auxb, aux, p : Real;
 resposta : char;
 nome : String;
 erro : Boolean;
 resultado : Text;

Begin

Repeat
 repeat
 Clrscr;
 Textcolor (White);
 Writeln ('Resolucao de sistemas de equacoes lineares utilizando o metodo da eliminacao');
 Writeln ('de Gauss (triangularizacao) com pivoteamento total.');
 Writeln;
 Write ('Digite a ordem do sistema (n), no maximo n=100: ');
 Readln (n);
 until n >= 2;
  //le os coeficientes da matriz A//
 for j:=1 to n do
 begin
 Repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da coluna ',j,' da matriz A (coeficientes de x',j,'):');
 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;

 //le os coeficientes da matriz B//
 repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da matriz B (termos independentes)');
 Writeln;
 for i:=1 to n do
 begin
 Write('b[',i,']= ');
 readln(b[i]);
 end;
 writeln;
 writeln;
 Write ('Confira os valores digitados, estao corretos? (digite s=sim, n=nao): ');
 Readln (resposta);
 Until (resposta = 'S') Or (resposta = 's');
 clrscr;

     for k:=1 to n do  //inicializa o vetor ordem das incognitas x//
          o[k]:=k;

     erro := False; //A variavel erro se tornara True caso haja erros de divisao por zero//

   //pivoteamento total//

    for h:=1 to n  do
    begin
      p:=abs(a[h,h]);
      posl:=h;
      posc:=h;
       for i:=h+1 to n do
       begin
       for j:=h+1 to n do
     begin
      if p<abs(a[i,j])
        then begin
        p:=abs(a[i,j]);
        posl:=i;    //guardam a posicao (linha e coluna) do maior pivo//
        posc:=j;
        end;
     end;
       end;
       if (posl>h) then  //troca linha h pela linha posl//
         begin
         for k:=1 to n do
          begin
          aux:=a[posl,k];
          a[posl,k]:=a[h,k];
          a[h,k]:=aux;
          end;
              auxb:=b[posl];
          b[posl]:=b[h];
          b[h]:=auxb;
         end;
         if (posc<>h) then  //troca coluna h pela coluna posc//
       begin
       for k:=1 to n do
         begin
         aux:=a[k,posc];
         a[k,posc]:=a[k,h];
         a[k,h]:=aux;
         end;
             posx:=o[h];
       o[h]:=o[posc];
       o[posc]:=posx; //vetor que guarda a ordem das incognitas x//
       end;
      
        //Metodo da eliminacao de Gauss (Triangularizacao)//
      
       If a[h,h] <> 0 Then   //Evita erros de divisao por zero//
        Begin
        for i:=h+1 to n do
         begin
         m := -1*(a[i,h]/a[h,h]);
         For ji:=1 To n Do
          a[i,ji] := a[i,ji] + (m*(a[h,ji]));
          b[i] := b[i] + m*b[h];
         end;
        End
         Else
         erro := True;
      
    end;
 
 If erro = True Then
 Begin
 Clrscr;
 Writeln ('Erro! Talvez este sistema linear nao tenha solucao (sistema impossivel)');
 End
 Else
 Begin
  
  
   //Metodo de resolucao de sistemas triangulares (Retrossubstituicao)// 

   If a[n,n] <> 0 Then
   x[n] := b[n] / a[n,n]
   Else                     
   x[n] := 0;
  
   For i := n-1 Downto 1 Do
    Begin
     soma := 0;
     For j := i+1 To n Do
      soma := soma + a[i,j]*x[j];
    
     If a[i,i] <> 0 Then
    x[i] := (1/a[i,i]) * (b[i] - soma)
    Else
    x[i] := (b[i] - soma);
   
    End;
 
   //Imprime na tela o resultado//

    clrscr;
    Writeln ('AX = B');
    Writeln;
     Textcolor (Lightcyan);
     For i := 1 To n Do
     Writeln ('x', o[i], ' = ', x[i]);
     writeln;

   //Grava o resultado em um arquivo de texto .txt//
 
  Writeln;
  Textcolor (White);
  Write ('Deseja salvar os resultados em um arquivo de texto? (digite s=sim, n=nao): ');  
   Readln (resposta);
   If (resposta = 's') Or (resposta = 'S') Then
   Begin
    Writeln;
    Write ('Digite o nome do arquivo a ser salvo: ');
    Readln (nome);
    nome := (nome + '.txt');
    Assign(resultado, nome);
    Rewrite (resultado);
    Writeln (resultado, 'valores de x (incognitas):');
    Writeln (resultado);
    For i:=1 To n Do  //Escreve X//  
    Writeln (resultado,'X',o[i], ' = ',x[i]);
   
    Close (resultado);
    Writeln;
    Writeln ('O arquivo foi salvo no mesmo diretorio do arquivo executavel!');
   End;
 End;

  Writeln;
  Textcolor (White);
  Write ('Deseja reiniciar o programa? (digite s=sim, n=nao): ');
  Readln (resposta);
Until (resposta <> 'S') And (resposta <> 's');   
End.


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

sexta-feira, 8 de abril de 2011

Eliminação de Gauss com Pivoteamento Parcial - Resolução de Sistemas Lineares

O programa abaixo foi desenvolvido no compilador Dev-Pascal, e utiliza a Eliminação de Gauss para o Escalonamento (Triangularização Superior da Matriz Ampliada) e Pivoteamento Parcial, para evitar pivôs nulos, resolvendo o sistema equivalente por retrossubstituição.


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

http://www.4shared.com/file/Fyh79JY1/Eliminacao_Gauss_Pivot_Parcial.html

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


Código:

Program Gauss_pivoteamento_parcial; Uses crt;
 Var
 a : Array[1..100,1..100] Of Real; //se desejar uma matriz maior, basta criar arrays maiores//
 x, b : Array[1..100] Of Real;
 i, j, n, ji, ii, ipivo, k : Integer;  // i's sao variaveis auxiliares//
 m, soma, pivo, baux, aux : Real;
 resposta : char;
 nome : String;
 erro : Boolean;
 resultado : Text;

Begin

Repeat
 repeat
 Clrscr;
 Textcolor (White);
 Writeln ('Resolucao de sistemas de equacoes lineares utilizando o metodo da eliminacao');
 Writeln ('de Gauss (triangularizacao) com pivoteamento parcial.');
 Writeln;
 Write ('Digite a ordem do sistema (n), no maximo n=100: ');
 Readln (n);
 until n >= 2;
  //le os coeficientes da matriz A//
 for j:=1 to n do
 begin
 Repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da coluna ',j,' da matriz A (coeficientes de x',j,'):');
 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;

 //le os coeficientes da matriz B//
 repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da matriz B (termos independentes)');
 Writeln;
 for i:=1 to n do
 begin
 Write('b[',i,']= ');
 readln(b[i]);
 end;
 writeln;
 writeln;
 Write ('Confira os valores digitados, estao corretos? (digite s=sim, n=nao): ');
 Readln (resposta);
 Until (resposta = 'S') Or (resposta = 's');


  //Metodo da eliminacao de Gauss (Triangularizacao)//
 
   k := 1; //Passo//
   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 := a[j,ji];
         a[j,ji] := a[ipivo,ji];
         a[ipivo,ji] := aux;
        End;
         baux := b[j];
         b[j] := b[ipivo];
         b[ipivo] := baux;
       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
          a[i,ji] := a[i,ji] + (m*(a[j,ji]));
          b[i] := b[i] + m*b[j];
         End
         Else
         erro := True;
        
     End;
     k := k + 1; 
   End;
 
 If erro = True Then
 Begin
 Clrscr;
 Writeln ('Erro! Talvez este sistema linear nao tenha solucao (sistema impossivel)');
 End
 Else
 Begin
  
  
   //Metodo de resolucao de sistemas triangulares (Retrossubstituicao)// 

   If a[n,n] <> 0 Then
   x[n] := b[n] / a[n,n]
   Else                     
   x[n] := 0;
  
   For i := n-1 Downto 1 Do
    Begin
     soma := 0;
     For j := i+1 To n Do
      soma := soma + a[i,j]*x[j];
    
     If a[i,i] <> 0 Then
    x[i] := (1/a[i,i]) * (b[i] - soma)
    Else
    x[i] := (b[i] - soma);
   
    End;
 
   //Imprime na tela o resultado//

    clrscr;
    Writeln ('AX = B');
    Writeln;
     Textcolor (Lightcyan);
     For i := 1 To n Do
     Writeln ('x', i, ' = ', x[i]);
     writeln;

   //Grava o resultado em um arquivo de texto .txt//
 
  Writeln;
  Textcolor (White);
  Write ('Deseja salvar os resultados em um arquivo de texto? (digite s=sim, n=nao): ');  
   Readln (resposta);
   If (resposta = 's') Or (resposta = 'S') Then
   Begin
    Writeln;
    Write ('Digite o nome do arquivo a ser salvo: ');
    Readln (nome);
    nome := (nome + '.txt');
    Assign(resultado, nome);
    Rewrite (resultado);
    Writeln (resultado, 'valores de x (incognitas):');
    Writeln (resultado);
    For i:=1 To n Do  //Escreve X//  
    Writeln (resultado,'X',i, ' = ',x[i]);
   
    Close (resultado);
    Writeln;
    Writeln ('O arquivo foi salvo no mesmo diretorio do arquivo executavel!');
   End;
 End;

  Writeln;
  Textcolor (White);
  Write ('Deseja reiniciar o programa? (digite s=sim, n=nao): ');
  Readln (resposta);
Until (resposta <> 'S') And (resposta <> 's');   
End.


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

domingo, 3 de abril de 2011

Métodos Iterativos de Jacobi e Gauss-Seidel - Resolução de Sistemas Lineares

O programa abaixo foi desenvolvido no compilador Dev-Pascal. Cuidado com os critérios de convergência! Pois esses métodos nem sempre convergem, gerando erros de "Overflow" quando utilizados para resolução de sistemas que não convergem.


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

http://www.4shared.com/file/BuIURAFH/Iterativo_Jacobi_Gauss_Seidel.html

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


Código:

Program iterativo_Jacobi_Gauss_Seidel;
//Programa para resolucao de sistemas de equacoes lineares por metodos iterativos de Jacobi e Gauss-Seidel//
Uses crt;
 Var
 a : Array[1..100,1..100] Of Real;
 x, x0, b, r, er, xg : Array[1..100] Of Real;
 i, j, n, m, k, ki, met, teste, convergencia : Integer;  //sao variaveis auxiliares//
 resposta : char;
 nome : String;
 erro, e, soma : Real;
 resultado: Text;

Begin
Repeat //Repeat utilizado para reiniciar o programa//
 repeat
 Clrscr;
 Textcolor (White);
 Writeln ('Resolucao de sistemas de equacoes lineares por metodos iterativos');
 Writeln;
 Write ('Digite a ordem do sistema (n), maximo 100: ');
 Readln (n);
 until n >= 2;

 //le os coeficientes da matriz A//
 for j:=1 to n do
 begin
 Repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da coluna ',j,' da matriz A (coeficientes de x',j,'):');
 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;

 //le os coeficientes da matriz B//
 repeat
 clrscr;
 Writeln ('AX = B');
 Writeln;
 Writeln ('Matriz ampliada do sistema');
 Writeln;
 Writeln ('Digite os elementos da matriz B (termos independentes)');
 Writeln;
 for i:=1 to n do
 begin
 Write('b[',i,']= ');
 readln(b[i]);
 end;
 writeln;
 writeln;
 Write ('Confira os valores digitados, estao corretos? (digite s=sim, n=nao): ');
 Readln (resposta);
 Until (resposta = 'S') Or (resposta = 's');

 Clrscr;
 teste:= 0;    //Zera as variaveis envolvidas no teste de convergencia//
 convergencia:= 0;

 For i:= 1 To n Do //Testa se existe elementos a[i,i] iguais a zero//
 Begin                
   If a[i,i] = 0 Then
    Begin
    Writeln('Erro:');
    Writeln;
    Writeln ('existem elementos da diagonal principal, a[i,i], iguais a zero (i=1,2...n).');
    Writeln;
    Writeln('a[i,i] diferente de zero para todo i e uma condicao necessaria');
    Writeln('para a aplicacao dos metodos iterativos de Jacobi e Gauss-Seidel.');
    Writeln('Reagrupe as equacoes para que essa condicao seja satisfeita.');
    Writeln;
    teste:= 1;
    Break;
    End;
 End;

  Soma:= 0;

 For i:= 1 To n Do //Testa o criterio de convergencia das linhas//
 Begin
   For j:= 1 To n Do
   soma := soma + ABS(a[i,j]);
 
   soma := soma - ABS(a[i,i]);
 
   If soma >= ABS(a[i,i]) Then
   Begin
     convergencia:= 1;
     Break;
   End;
   Soma:= 0;
 End;

  Soma:= 0;

 For j:= 1 To n Do //Testa o criterio de convergencia das colunas//
 Begin
   For i:= 1 To n Do
   soma := soma + ABS(a[i,j]);
 
   soma := soma - ABS(a[j,j]);
 
   If soma >= ABS(a[j,j]) Then
   Begin
     convergencia:= convergencia + 1;
     Break;
   End;
   Soma:= 0;
 End;

 If convergencia = 2 Then
 Begin
 Writeln ('O uso dos criterios das linhas e colunas detectou que talvez neo haja');
 Writeln ('convergencia. Se isso ocorrer tente utilizar metodos diretos, como o');
 Writeln ('de Gauss e Jordan com Retrosubstituicao.');
 Writeln;
  If teste <> 1 Then
   Begin
    Write ('Deseja continuar mesmo assim? (digite s=sim, n=nao): ');
    Readln (resposta);
    Clrscr;
     If (resposta = 'S') Or (resposta = 's') Then
       convergencia := 0;
   End;
 End;

 If (teste <> 1) AND (convergencia <> 2) Then //so faz os calculos se houver convergencia, se nao houver leva ate a pergunta para reinicializacao do programa//
                                             //convergencia = 0 ou = 1 significa que ira convergir, convergencia = 2 significa que nao ira//
 Begin                                      //teste = 1 significa que nao passou no teste da diagonal principal livre de a[i,i] = 0//

 Write ('Digite o valor do erro aceitavel: ');
 Readln (erro);
 Writeln;
 Write ('Digite o valor maximo de iteracoes (ate 999, digite 0 para ilimitada): ');
 Readln (m);
 Writeln;
 Write ('Gostaria de digitar uma solucao inicial? (digite s=sim, n=nao): ');
 Readln (resposta);

 If (resposta = 'S') Or (resposta = 's') Then
 Begin
 Writeln;
 Writeln ('Digite a solucao:');
 Writeln;
 For ki:= 1 To n Do
  Begin
   Write ('X',ki,' = ');
   Readln (x0[ki]);
  End;
 End;
 Writeln;

  Repeat
  Writeln ('Digite o numero do metodo iterativo a ser utilizado:');
  Writeln;
  Writeln ('1) Metodo de Jacobi');
  Writeln ('2) Metodo de Gauss-Seidel');
  Writeln;
  Write ('Metodo: ');
  Readln (met);
  Clrscr;
  Until (met=1) Or (met=2);

 Textcolor (White);


 i:= 0;
 j := 0;  //Zera para evitar valores anteriores//
 k:=0;

 Repeat

  //Iteracao Jacobi//

  If met=1 Then
  Begin
   For i:= 1 To n Do
   Begin
    For j:= 1 To n Do
     x[i] := x[i] + (-1* a[i,j] * x0[j]);
                                      
    x[i] := x[i] + (a[i,i]*x0[i]) + b[i];
    x[i] := x[i]/a[i,i];
   End;
  End;

  //Iteracao Gauss-Seidel//

  If met=2 Then
  Begin
  For ki:=1 To n Do
    xg[ki]:= x0[ki];
   For i:= 1 To n Do
   Begin
    For j:= 1 To n Do
     x[i] := x[i] + (-1* a[i,j] * xg[j]);
                                      
    x[i] := x[i] + (a[i,i]*xg[i]) + b[i];
    x[i] := x[i]/a[i,i];
    xg[i]:= x[i]
   End;
  End;
 

  //Testa o erro//

  teste:= 0;
  For ki:=1 To n Do
  Begin
   e:= Abs(x[ki] - x0[ki]); //Calcula o erro//
   er[ki] := e; //Guarda o erro para ser impresso//
   If e <= Abs(erro) Then
   teste := teste + 1; //Ou seja: uma condicao de parada e quando todos os erros forem menores ou iguais ao
  End;                //digitado pelo usuario. Isso se da quando teste = n (teste ganha +1 para cada erro aceitavel)
                     //n e o numero de variaveis do sistema, a sua ordem, logo serao calculados n erros, um para cada variavel.


  For ki:=1 To n Do  //Guarda os resultados da solucao do sistema//
  r[ki] := x[ki];

 //Prepara x0 e x para uma nova iteracao//

   For ki:=1 To n Do
    x0[ki]:= x[ki];
   For ki:=1 To n Do
    x[ki]:= 0;


  k:= k+1; //Conta o numeros de iteracoes//

   Textcolor (White);
   Writeln ('Resultados (com ', k, ' iteracoes):'); //Imprime os resultados na tela//
   Textcolor (Yellow);
   For ki:=1 To n Do                 
    Begin
    Writeln('X',ki, ' = ', r[ki], '  ','Erro = ',er[ki]);
    Writeln;
    End;

 Until (teste = n) Or (k = m) Or (k = 1000); //teste=n significa todos os erros aceitaveis, k=m que o maximo de iteracoes
                                            //que o usuario escolheu foi atingido e k=1000 uma parada de seguranca para evitar a nao convergencia

 Textcolor (White);

 If k = 1000 Then
 Writeln ('Sistema nao convergiu apos 1000 iteracoes!');
 Writeln;

 For ki:=1 To n Do   //Zera x0 para uma possivel reinicializacao do programa, evitando erros na proxima iteracao//
 x0[ki]:= 0;

                 
                 //Grava o resultado em um arquivo de texto//
 
  If k < 1000 Then
  Begin
   Write ('Deseja salvar os resultados em um arquivo de texto? (digite s=sim, n=nao): '); 
   Readln (resposta);
   If (resposta = 's') Or (resposta = 'S') Then
   Begin
   Writeln;
   Write ('Digite o nome do arquivo a ser salvo: ');
   Readln  (nome);
   nome := (nome + '.txt');
   Assign(resultado, nome);
   Rewrite (resultado);
   Writeln (resultado, 'valores de x (incognitas):');
   Writeln (resultado);
   //escreve os valores de x//
   For ki:=1 To n Do                 
   Writeln (resultado,'X',ki, ' = ', r[ki], '  ','Erro = ',er[ki]);
  
    //escreve os valores de b original e os calculados com as variaveis x encontradas//
     For i:= 1 To n Do
    Begin
     Writeln (resultado);
     Writeln (resultado, 'b[',i,'] original = ', b[i]);
     b[i]:=0;
     For j:= 1 To n Do
      Begin
      b[i]:= b[i] + (a[i,j]*r[j]); //Calcula os termos da matriz B com as variaveis encontradas//
     End;
     Writeln (resultado, 'b[',i,'] calculado = ', b[i]);
    End;
     Close (resultado);
     Writeln;
      Writeln ('Arquivo salvo!');
   End;
  End;

 Writeln;

 End; //End usado na condicao "If (teste <> 1) AND (convergencia <> 2)", que faz com que o programa pule os calculos se nao houver convergencia detectada//

 Write ('Deseja reiniciar o programa? (digite s=sim, n=nao): ');   //Reinicia o programa//
 Readln (resposta);


Until (resposta <> 's') And (resposta <> 'S');
End.


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