Você está na página 1de 10

Ttulo: Projeto de clculo Numrico

Thomas Gardi , Nicanor Gomes , Sheila Silva , Edinilson De Castro , Heris Leonel
Alunos da disciplina Clculo Numrico, turma T5.

Resumo: Programa que calcula uma soluo para um sistema de equaes lineares.

1. Introduo
O problema: Resolver um sistema linear com n equaes e n incgnitas. Para solucion-lo foi criado um algoritmo que utiliza alguns mtodos diretos e outros iterativos cujo programa fonte est contido nos anexos deste relatrio.

2. Desenvolvimento
Para se desenvolver o algoritmo usado no programa foram utilizadas as lgicas de funcionamento dos mtodos utilizados, e so eles: 1 Mtodo de Gauss - A base deste mtodo o uso de uma propriedade elementar de Sistemas de Equaes Lineares que estabelece o seguinte: A soluo de um sistema Ax = b no se altera se o submetermos a uma sequncia de operaes do tipo: multiplicao de uma equao (linha) por uma constante no nula. Soma do mltiplo de uma equao a outra. Troca de posio de duas ou mais equaes. Uma sequncia conveniente de operaes deste tipo pode gerar um sistema equivalente de forma triangular. Um sistema de equaes lineares pode ser representado usando a notao matricial. Nesse caso, devemos lembrar que uma matriz pode ser triangular superior ou triangular inferior. Uma matriz triangular superior quando todos os elementos abaixo da diagonal principal so iguais a zero. Uma matriz triangular inferior quando todos os elementos acima da diagonal principal so iguais a zero. Um sistema triangular superior trivialmente resolvido usando substituio reprocessa (ou retro substituio). 2 O mtodo de Gauss com Pivotao parcial: A tcnica de pivotamento parcial consiste em mover as linhas da matriz de modo a manter o piv (elemento da matriz diagonal da linha em questo), o maior possvel. Para realizar esta tcnica basta analisar qual a linha que contem o primeiro elemento com o maior mdulo, e trocar a posio dela com a primeira linha, aps isso faz se o mesmo com as linhas seguintes sem mover novamente as linhas acima, pois isso deslocaria novamente os pivores. A tcnica de pivotao parcial serve para aumentar a preciso dos clculos numricos realizados pelo computador e para garantir que o maior elemento da linha esteja sempre na posio equivalente a diagonal da matriz. 3 - O mtodo de Jacobi um algoritmo de lgebra linear que permite determinar a soluo de sistemas de equaes lineares em que o valor dominante de todas as linhas e colunas o elemento da diagonal. Esta a condio necessria e suficiente para a convergncia das sucessivas aproximaes soluo do sistema de equaes. assim procurada a soluo para um sistema de equaes lineares, escrita em forma matricial em que A a matriz dos coeficientes, x o vector coluna das N variveis e b o vector coluna das variveis independentes.

4 - O mtodo de Gauss-Seidel : Por fim o mtodo de Gauss-Seidel trata-se apenas de uma variao do mtodo de Jacobi, onde utilizamos os novos valores logo depois de obt-los o que nos d uma convergncia ainda mais rpida do que a apresentada pelo mtodo de Jacobi.

3 O Programa
O programa mostra passo a passo o que o operador deve fazer, basta seguir as instrues mostradas na tela. O programa primeiro vai querer saber a dimenso da matriz que deve ser um valor entre 1 e 50. Aps isso ele vai pedir pelos valores que compem a matriz seguindo uma ordem horizontal como segue o exemplo abaixo:
A1 + A2 A3 = B1 A4 + A5 +A6 = B2 A7 + A8 + A9 = B3

Vale salientar que os valores (Bn) localizados aps a igualdade devem ser preenchidos por ltimo, caso contrrio o programa no funcionar direito. A seguir podemos ver um exemplo do programa funcionando.

Figura 1 Programa em ao

Uma vez tendo confirmado que a matriz est correta o programa passar para a etapa seguinte onde ele vai perguntar com quais mtodos o operador deseja executar o programa conforme mostra a figura 2.

Figura 2 Programa mostrando resultados

Aps todos os dados confirmados o programa executa uma srie de clculos internos enquanto pergunta, quais mtodos o operador deseja utilizar. Note que os mtodos iterativos no podero ser utilizados se a matriz de entrada no atender ao critrio da matriz com a diagonal estritamente dominante. Contudo ainda se faz necessrio validar o programa, para isso foi selecionada uma questo cuja resposta ja era conhecida para avaliar o desempenho do programa e obtivemos o seguinte: Questo:

10 x1 +

2 x2

3 x3 + 3 x3

2 x4 =

32

2 x1 15 x2 + 1 x1 2 x1 +

2 x4 = -59 2 x4 = -38

3 x2 + 20 x3 + 2 x2

1 x3 + 30 x4 = 160

A resposta dela:

x1 = 1,00 x2 = 3,00

x3 = -2,00

x4 = 5,00

agora utilizando o programa para calcular tal questo obtivemos o seguinte resultado mostrado na figura 3. Cujo resultado x1 = 1,00 x2 = 3,00 x3 = -2,00 x4 = 5,00 batendo exatamente com o valor

esperado.

Figura 3 soluo pelo mtodo de Gauss com pivotao parcial

Portanto pode-se dizer que o programa est validado e confivel.

3. Limitaes
O programa apesar de muito bom possui suas limitaes tais quais se pode citar: 1 - Ele s trabalha com matrizes quadradas, ou seja, matrizes da Forma Ann para 0<n<50. 2 Os mtodos iterativos s funcionam para alguns casos especficos.

4. Concluses
O programa funcionou dentro das especificaes e apresentou um bom desempenho para o problema proposto como foi mostrado. Foi constatado tambm que Gauss-Seidel apresenta de fato convergncia mais rpida, e que ambos os mtodos iterativos encontram o mesmo resultado que os mtodos diretos, quando possvel usar todos claro.

Referncias
http://algos.inesc-id.pt/~jcm/cpd/papers/4a6/Grupo6-4a-Metodo_Jacobi.pdf acessado em 22/10/2011

Programa Fonte
Program SistemasLineares;

var Matriz,Matriz2: array[1..50,1..51] of real; vetor,vetoraux: array[1..51] of real; m,soma,x,y,erro,E1,E2: real; IT,k,i,j,o,passo, tamanho, aux1,contador: integer; piv,continua,Gauss,jac,critlinha,critcoluna,li m,lim2,GS,aprox,resp: char; procedure pivotacao; begin for k := 0 to (tamanho-2) do begin x:=0; for i := (passo+k) to tamanho do begin y:= abs(matriz[i,passo]); if (y > x) then begin x:=y; o:=i; end; end; for j:= 1 to aux1 do begin if k <> (tamanho-passo) then begin vetoraux[j]:= matriz[(passo+k),j]; matriz[(passo+k),j]:= matriz[o,j]; matriz[o,j]:= vetoraux[j];

end; if k = (tamanho-passo) then break; end; if k = (tamanho-passo) then break; end; end; {Programa comea aqui} begin continua :=('s'); while continua = ('s') do begin resp:= 'n'; {Esta primeira parte a parte da entrada de dados onde se entra com o tamanho da matriz desejada e com o valor dela.} while resp = 'n' do begin writeln('Digite o tamanho da matriz'); readln(tamanho); while (tamanho >50) or (tamanho <1)do begin writeln('Digite um valor entre 1 e 50 para o tamanho da matriz'); readln(tamanho); end; writeln ('Entre com a matriz problema na seguinte forma:'); writeln ('Entre com os valores seguindo as linhas, primeira linha depois segunda etc');

Writeln ('Primeiro valor'); for i:= 1 to tamanho do Begin writeln('linha',i); for j:= 1 to tamanho do Begin readln(matriz[i,j]); writeln('proximo valor'); end; end; aux1:= tamanho +1; Writeln('Agora entre com o vetor solucao'); for i:= 1 to tamanho do Begin readln(matriz[i,aux1]); writeln('proximo valor'); end; for i:= 1 to tamanho do Begin writeln(); for j:= 1 to aux1 do Begin write(' ',Matriz[i,j]:8:8); end; end; readln; for i:= 1 to tamanho do begin for j := 1 to aux1 do begin matriz2[i,j]:=matriz[i,j]; end; end; writeln; writeln('Esta e a matriz desejada?'); readln(resp); while (resp <> 's') and (resp <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(resp); end; end; {Criterio da diagonal dominante} critlinha:='v'; critcoluna:='v'; for i := 1 to tamanho do

begin soma:=0; for j:= 1 to tamanho do begin if i<>j then begin soma:=soma+abs(matriz[i,j]); end; end; if soma > matriz[i,i] then begin critlinha :='f'; end; end; critcoluna:='v'; for j := 1 to tamanho do begin soma:=0; for i:= 1 to tamanho do begin if i<>j then begin soma:=soma+abs(matriz[i,j]); end; end; if soma > matriz[i,i] then begin critcoluna :='f'; end; end; writeln('Deseja utilizar o metodo de eliminacao Gauss para esse problema?'); readln(gauss); while (gauss <> 's') and (gauss <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(gauss); end; if gauss = ('s') then begin writeln('Deseja utilizar pivotao parcial?'); readln(piv); while (piv <> 's') and (piv <> 'n')do begin Write ('Escreva s para sim ou n para nao'); readln(piv); end; end;

if gauss = ('s') then begin {Escalonamento da matriz via Gauss} For passo := 1 to (tamanho) do begin if piv = 's' then begin pivotacao end; for i := passo to tamanho do begin m:= matriz[i,passo]; m:= matriz[i,passo]; if m <> 0 then begin for j := passo to aux1 do begin matriz[i,j]:= matriz[i,j]/m; end; end; end; for j:= 1 to aux1 do begin vetor[j]:= matriz[passo,j]; end; for i := (passo+1) to tamanho do begin if matriz[i,passo] <>0 then begin for j:= 1 to aux1 do begin matriz[i,j]:= matriz[i,j]-vetor[j]; end; end; end; end;

while i >0 do Begin soma:=0; for j:=1 to tamanho do begin soma:=soma + (matriz[i,j]*vetor[j]); end; vetor[i]:= (matriz[i,aux1]-soma); i:=i-1; end; writeln('O vetor solucao e o seguinte:'); for i:=1 to tamanho do begin writeln(vetor[i]:8:8); end; end; for i:= 1 to tamanho do begin for j := 1 to aux1 do begin matriz[i,j]:=matriz2[i,j]; end; end; if (critlinha = 'f') and (critcoluna = 'f') then writeln('Os metodos iterativos nao podem ser utilizados para resolver esse problema'); if (critlinha = 'v') or (critcoluna = 'v') then begin writeln('Deseja utilizar o mtodo de jacobi para esse problema?'); readln(jac); while (jac <> 's') and (jac <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(jac); end; for k:=1 to tamanho do begin vetor[k]:= 0; vetoraux[k]:=0; end;

{Montando o vetor soluo} vetor[tamanho]:=matriz[tamanho,aux1]; i:= tamanho-1;

if jac = 's' then begin erro:=0.000001;

writeln ('deseja colocar alguma limitacao de erro?'); readln(lim); while (lim <> 's') and (lim <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim); end; end; if lim = 's' then begin write ('Entre com o valor do erro'); readln(erro); while (erro < 0) and (erro > 1) do begin Write ('Escreva um valor para o erro entre 0 e 1'); readln(erro); end; end; if jac = 's' then begin for i:= 1 to tamanho do begin vetoraux[i]:=0; vetor[i]:=0.0001; end; writeln ('deseja escolher uma aproximacao inicial?'); readln(aprox); while (aprox <> 's') and (aprox <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim); end; if aprox = 's' then begin writeln ('Entre com os valores do vetor aproximacao inicial'); for i:= 1 to tamanho do begin writeln('valor',i); readln(vetor[i]); while vetor[i] = 0 do begin writeln ('para evitar erros no programa nao use 0 em suas aproximacoes iniciais');

readln(vetor[i]); end; end; end; IT:=1000; writeln ('deseja escolher um limite de iteracoes para o programa?'); readln(lim2); while (lim2 <> 's') and (lim2 <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim2); end; if lim2 = 's' then begin writeln ('Entre com o limite desejado.'); readln(IT); while (IT < 1) or (IT > 1000) do begin writeln ('Escolha um valor entre 1 e 1000'); readln(IT); end; end;

contador:=1; repeat begin if contador >IT then begin break end; for i:= 1 to tamanho do begin for j:= 1 to tamanho do begin if i<>j then begin vetoraux[i] := (vetoraux[i] + (matriz[i,j]*vetor[j])); end; end; vetoraux[i]:=((matriz[i,aux1]vetoraux[i])/matriz[i,i]); E1:= (abs(vetoraux[i]vetor[i])/abs(vetor[i])); if E1>E2 then begin

E2:= E1; end;

end; for k:=1 to tamanho do begin vetor[k]:= vetoraux[k]; vetoraux[k]:=0; end; contador:= contador +1; end; until E1 < erro end;

writeln ('deseja colocar alguma limitacao de erro?'); readln(lim); while (lim <> 's') and (lim <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim); end; end; if lim = 's' then begin write ('Entre com o valor do erro'); readln(erro); while (erro < 0) and (erro > 1) do begin Write ('Escreva um valor para o erro entre 0 e 1'); readln(erro); end; end; writeln ('deseja escolher uma aproximacao inicial?'); readln(aprox); while (aprox <> 's') and (aprox <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim); end; if aprox = 's' then begin writeln ('Entre com os valores do vetor aproximacao inicial'); for i:= 1 to tamanho do begin writeln('valor',i); readln(vetor[i]); while vetor[i] = 0 do begin writeln ('para evitar erros no programa nao use 0 em suas aproximacoes iniciais'); readln(vetor[i]); end; end; end; IT:=1000; writeln ('deseja escolher um limite de iteracoes para o programa?');

{Montando o vetor soluo para jacobi} writeln('apos',contador-1,'iteracoes o metodo de jacobi se encerrou e de acordo com ele o vetor solucao vale:'); for i:= 1 to tamanho do Begin writeln(vetor[i]:8:8); end; for i:= 1 to tamanho do begin for j := 1 to aux1 do begin matriz[i,j]:=matriz2[i,j]; end; end;

{O mtodo de Gauss-Seidel} writeln('Deseja utilizar o mtodo de GaussSeidel para esse problema?'); readln(gs); while (gs <> 's') and (gs <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(gs); end; if gs = 's' then erro:=0.000001; begin

readln(lim2); while (lim2 <> 's') and (lim2 <> 'n') do begin Write ('Escreva s para sim ou n para nao'); readln(lim2); end; if lim2 = 's' then begin writeln ('Entre com o limite desejado.'); readln(IT); while (IT < 1) or (IT > 1000) do begin writeln ('Escolha um valor entre 1 e 1000'); readln(IT); end; end;

E1:= (abs(vetoraux[i]vetor[i])/abs(vetor[i])); if E1>E2 then begin E2:= E1; end; vetor[i]:= vetoraux[i]; vetoraux[i]:=0; end; contador:= contador +1; end; until E1 < erro end; {Montando o vetor soluo para GaussSeidel} writeln('apos',contador-1,'iteracoes o metodo de Gauss-Seidel se encerrou e de acordo com ele o vetor solucao vale:'); for i:= 1 to tamanho do Begin writeln(vetor[i]:8:8); end; end; write ('Deseja calcular outra matriz?'); readln(continua); while (continua <> 's') and (continua <>'n') do begin Write ('Escreva s para sim ou n para nao'); readln(continua); end; readln; end; end.

if gs = 's' then begin for i:= 1 to tamanho do begin vetoraux[i]:=0; vetor[i]:=0.01; end; contador:=1; repeat begin if contador >IT then begin break end; for i:= 1 to tamanho do begin for j:= 1 to tamanho do begin if i<>j then begin vetoraux[i] := (vetoraux[i] + (matriz[i,j]*vetor[j])); end; end; vetoraux[i]:=((matriz[i,aux1]vetoraux[i])/matriz[i,i]);

Você também pode gostar