Sei sulla pagina 1di 26

Soluo computacional de sistemas de

equaes lineares lineares por escalonamento


com base em linguagem C de programao
Gustavo Marques Hobold

gustavo@hobold.com

Universidade Federal de Santa Catarina


5 de maro de 2011

Resumo

Este trabalho tem o intuito de desenvolver um algoritmo para a resoluo de sistemas lineares de qualquer ordem atravs da manipulao
do sistema em forma matricial, at atingir a forma escalonada. Ser
mostrada a parte matemtica terica que rege a exatido dos resultados, como a demonstrao de teoremas que so, muitas vezes, engolidos
sem certeza de funcionamento. Para a resoluo, ser usado e comentado um algoritmo escrito em linguagem C. A proposta foi feita na
disciplina INE5231 (Computao Cientca I) no semestre 2010.2 da
Universidade Federal de Santa Catarina. O cdigo que ser mostrado
e analisado resposta feita por mim ao problema.
Para contato enviar um e-mail para gustavo@hobold.com
Boa leitura.

1 Sistemas lineares
Sistemas lineares so, com certeza, amplamente conhecidos e devem ter sido
objeto de estudo do leitor em algum ponto da matemtica. No entanto,
embora muitos tenham a viso mais intuitiva do que signica um sistema de
equaes lineares (ou at mesmo uma equao linear por si s), queremos,
aqui, introduzir uma viso mais matemtica para que depois possamos partir
para a tcnica de resoluo, que nos interessante no ponto computacional.
Comearemos denindo nossos objetos de estudo, ento.
1

Denio 1. Dados a1 , . . . , an , b R, uma equao dita ser linear quando


da forma

(1)

a1 x1 + a2 x2 + . . . + an xn = b
com n > 1 N e x1 , . . . , xn variveis em

R.

dita soluo para a equao linear a n-upla de nmeros reais (no


necessariamente distintos) (c1 , c2 , . . . , cn ) que satisfaz a igualdade

a1 c 1 + a2 c 2 + . . . + an c n = b
Os termos a1 , . . . , an so ditos coecientes da equao e b dito ser o
termo idenpendente.

Denio 2.

Sejam m, n N( 1) e dados a1 , . . . , an , b1 , . . . , bm
conjunto de m equaes lineares com n incgnitas da forma

a11 x1 + a12 x2 + . . . + a1n xn = b1

a21 x1 + a22 x2 + . . . + a2n xn = b2


..
..

.
.

a x + a x + ... + a x = b
m1 1

m2 2

mn n

R, um

(2)

tal que x1 , . . . , xn so incgnitas dito ser um sistema de equaes lineares


ou simplesmente sistema linear.
Uma soluo de sistema linear uma n-upla de nmeros reais (c1 , . . . , cn )
que satisfaz simultaneamente todas as equaes, ou seja

a11 c1 + a12 c2 + . . . + a1n cn = b1

a21 c1 + a22 c2 + . . . + a2n cn = b2


..
..

.
.

a c + a c + ... + a c = b
m1 1

m2 2

mn n

Denimos, aqui, os dois objetos mais importantes para nossa abordagem.


Estaremos tratando da resoluo de sistemas de equaes lineares (dado um
sistema linear, como encontrar a(s) n-upla(s) que satisfaz(em)?). Alguns
mtodos j devem vir a mente, como substituir variveis e mtodos de adio
e subtrao previamente vistos. No entanto, como deve ser possvel perceber,
os coecientes das equaes do sistema 2 possuem uma certa organizao
prpria em relao incgnita e equao que est associada. Para um bom
observador, fcil notar que eles podero assumir um carter matricial a
2

partir de agora (use aqui sua viso intuitiva de matriz), que justamente o
que ser feio.
Sistemas de equaes lineares so um dos campos de pesquisa da lgebra
linear e existem diversos mtodos de resoluo, no entanto no caber nesse
trabalho descrever todos, apenas um que nos interessa (que o mais utilizado
e fcil de ser utilizado em mtodos computacionais).
O que ser apresentado a seguir, poder (e provavelmente ser) bastante
cansativo para o leitor, no entanto de extrema importncia para o entendimento de como funciona o mtodo de escalonamento (novamente, utilize por
escalonamento o que j sabido, mas ser feita uma abordagem mais formal
posteriormente) e o porqu de funcionar. necessria a ateno do leitor
para perceber pequenas sutilezas que daro um entendimento maior.
Comearemos com um sistema linear simples para exemplo:

3x + 5y + z = 16
2x + 3y = 8

5x = 5
Esse sistema de simples soluo, pois podemos encontrar o valor de x
(que uma equao linear de apenas uma incgnita), substuir na segunda
equao, achar o valor de y e substituir novamente na primeira equao para
encontrar o valor de z (cabe ao leitor resolver esse sistema, dado como trivial).
No entanto, quando trabalhamos com sistemas lineares mais cimplicados e
maiores, o mtodo de substituio nem sempre bem vindo, pois o tempo
de processamento ou o trabalho manual no vale a pena, tendo que recorrer
a outros mtodos.

3x + 5y + z = 20
2x + 4y + z = 15

5x + 4x + 2z = 25
Essa equao j mostra mais diculdade para ser resolvida por mtodos
substitutivos, assim percebemos que, quanto maior a ordem, mais absurdo
esse mtodo ca, cabendo a ns desenvolver uma nova tcnica para resolver
mais facilmente esse tipo de problema.
Note que se tomarmos a primeira equao desse sistema e somarmos com
o oposto da segunda, teremos um resultado interessante.
3

primeira equao

segunda equao

}|
{
z
}|
{ z
3x + 5y + z (2x + 4y + z) = 20 + (15)
x+y =5
importante notar que esse passo que acabamos de tomar vlido, pois
estamos adicionando o mesmo valor para ambos os lados da primeira equao1 .
Outra operao que podemos realizar sem medo a de multiplicar uma
das equaes por uma escalar qualquer. Veja que se multiplicarmos a primeira equao por 1/3, o sistema linear obtido a partir disso continuar sendo
equivalente e teremos um novo sistema dado por:

1
20
5

x+ y+ z =
3
3
3
2x + 4y + z = 15

5x + 4x + 2z = 25
Outra operao que ser essencial para continuar o estudo entender que
trocar as linhas de posio no alterar o resultado (isso deve ser bvio para
qualquer um). Podemos trocar a primeira linha com a ltima sem problemas
e obter um novo sistema de equaes lineares equivalente.

5x + 4x + 2z = 25
2x + 4y + z = 15

x + 5 y + 1 z = 20
3
3
3
No entanto, podemos car realizando essas operaes o dia inteiro sem
chegar a lugar algum ou sequer perto de uma resposta, complicando ainda
mais o sistema linear. Como nosso objetivo resolver, temos de pensar
logicamente para chegar o mais rpido possvel a uma soluo. Com o sistema
linear dado acima, queremos, com as operaes mostradas, simplic-lo at
car como o abaixo,

x + 0y + 0z = 3
0x + y + 0z = 2

0x + 0y + z = 1
que nos daria a soluo (x, y, z) = (3, 2, 1).
1 Podemos

ver como isso vlido se tomarmos duas igualdades

a+c=b+d

a = b, c = d,

ento

Veja que, no sistema inicial, no temos o primeiro coeciente a11 = 1,


mas, no entanto, a resposta esperada necessariamente deve ter esse valor.
Com isso percebido, no difcil notar que, para um sistema linear, todos os
termos aii , i N, i m devem ter valor 1 e todos os outros aij com i 6= j
devem ser nulos am de encontrarmos uma nica soluo.
No entanto, no so todos os sistemas lineares que possuem uma nica
soluo ou, ainda, h sistemas lineares que sequer possuem soluo, e todas
essas possibilidades devem ser levadas em conta na criao de um algortimo
(computacional ou no). Sistemas como os abaixo possuem innitas solues
e nenhuma soluo, respectivamente

5x + 2y + z = 3
15x + 6y + 3z = 9
(3)

7x + 2y + z = 1

5x + 2y + z = 3
15x + 6y + 3z = 8
(4)

7x + 2y + z = 1
Caso j tenha estudado algo de lgebra linear, ser fcil perceber o porqu
do primeiro sistema acima possuir innitas solues: uma das equaes lineares que o compe combinao linear das outras duas, ou seja, existe
ao menos uma n-upla de reais no todas nulas que multiplicam as outras
equaes para obter a que dita ser linearmente dependente. Felizmente,
esse assunto mais facilmente tratado quando obtermos a viso matricial
dos sistemas lineares, que ser feito em breve.
O segundo sistema mostrado acima impossvel e tambm facil perceber
o porqu: a primeira parte da segunda equao que o compe igual primeira (multiplicada por uma escalar 3), no entanto, a igualdade diferente.
Sendo assim, no h soluo para este sistema.

2 Iniciando um algortmo manual


Como dito anteriormente, temos que desenvolver um algoritmo ecaz para
a resoluo de sistemas lineares atravs das trs operaes bsicas anteriormente citadas (mudana na posio da equao, multiplicao por escalar e
adio), pois poderamos perder a idade do universo calculando sem chegar
a lugar nenhum. Como nosso objetivo tomar um sistema linear e chegar
num outro equivalente da forma
5


x1 + 0x2 + . . . + 0xn

0x1 + x2 + . . . + 0xn

..

.
0x1 + 0x2 + . . . + xn

..

0x1 + 0x2 + . . . + 0xn

= c1
= c2
..
.
= cn
..
.

(5)

= cm

(note desde j que se bm 6= 0, o sistema no possui soluo), percebese que o primeiro passo de um algoritmo transformar aii = 1. Isso pode
ser facilmente feito multiplicando a i-sima equao do sistema linear pelo
inverso do seu elemento aii , ou seja, multiplicar por 1/aii (se aii 6= 0, o caso
aii = 0 ser tratado posteriormente). Note que realizar essa operao em
todas as linhas o mais rpido possvel no nos leva a lugar nenhum, j que
as linhas abaixo e acima dela tero que ser modicadas para zerar todos os
outros coecientes da mesma varivel xi .
Com esse pensamento em mente, devemos zerar todos os outros coecientes depois de transformar o elemento aii (que passaremos a chamar de piv)
em 1. Isso pode ser feito multiplicando e somando a i-sima equao com a
equao das outras linhas que devem ser zeradas. A escalar que multiplicar
a i-sima equao deve ser escolhida com cuidado, por exemplo, no sistema
linear

3x + 2y + z = 0
15x + 6y + 3z = 6
(6)

7x + 2y + z = 4
Se multiplicarmos a primeira equao por 15 e somarmos com a segunda
(deixando a equao resultante no lugar da mesma. Certique-se de que
esse mtodo realmente funciona com base nas operaes previamente vistas),
teremos o termo a21 zerado. Se zermos o mesmo para a terceira equao,
teremos o termo a31 zerado. E se repetirmos esse processo para todas os
pivs, facilmente encontramos a soluo do sistema linear na forma

x + 0y + 0z = 1
0x + y + 0z = 1
(7)

0x + 0y + z = 1
Como era esperado, obtendo o valor de cada incgnita. Mas claro que
ainda no cobrimos todos os casos e generalizar bastante trabalhoso (no
difcil, mas massante), ento deixaremos isso para quando trabalharmos com
6

matrizes. Note que caso algum piv assumir valor zero por motivo das operaes realizas (ou se o sistema foi apresentado de tal forma), deveremos mudar
a posio da linha para que o piv deixe de ser nulo  leve isso como simples
esttica, por enquanto, mas essa operao possui papel essencial no trabalho
matricial que faremos posteriormente, principalmente na interpretao do
computador, que facilitada quando introduzimos um piv no-nulo. Voc
pode comear pensando na primeira parte do algortmo, onde multiplicamos
a equao linear por 1/aii , no sendo possvel se aii = 0.

3 Trabalhando com matrizes


Para um bom observador, fcil perceber, como j foi dito anteriormente,
que os coecientes das equaes lineares podem ser escritos numa matriz, ou
seja, o sistema da forma, podemos tomar um sistema de equaes linear S

a11 x1 + a12 x2 + . . . + a1n xn = b1

a21 x1 + a22 x2 + . . . + a2n xn = b2


S:
(8)
..
..

.
.

a x + a x + ... + a x = b
m1 1

m2 2

mn n

e associar a uma equao matricial A X = B tal que

A=

a11
a21
..
.

a12
a22
..
.

am1 am2

. . . a1n
. . . a2n
..
..
.
.
. . . amn

, X =

x1
x2
..
.

, B =

xm

b1
b2
..
.

(9)

bm

tal que A dita ser a matriz dos coecientes de S.


No entanto, ainda no essa notao que gostaramos de usar. Temos
que encontrar uma matriz que envolva, tambm, os termos independentes
das equaes lineares do sistema S . Escreveremos a matriz expandida de S
da forma

a11 a12 . . . a1n b1


a21 a22 . . . a2n b2

M = ..
(10)
..
..
..
.
.
.
.
.
.
.

am1 am2 . . . amn bm


Note que a matriz expandida muito similar ao sistema original, no
entanto as incgnitas so omitidas e identicadas pela coluna na matriz. Por
7

exemplo: os coecientes que vinham a frente da incgnita x5 encontram-se


na linha 5 da matriz expandida associada ao sistema desejado. Vejamos um
exemplo de um sistema linear com sua matriz associada.

7 2 3 11
7x + 2y + 3z = 11
3x + 5y + 2z = 1 3 5 2 1
S:
(11)

8x + 3y + 3z = 8
8 3 3 8
E se multiplicarmos qualquer linha por uma escalar qualquer diferente
de zero, estaremos multiplicando tambm a linha correspondente da matriz
associada e isso vale para todas as outras operaes dadas ( simples vericar
voc mesmo, mas tenha certeza que entendeu antes de continuar!). No deve
ser difcil perceber que quando encontrarmos uma matriz equivalente do tipo

M =

1
0
..
.
0
..
.
0

0 c1
0 c2

..

1 cn

..

.
0 . . . 0 cm
0 ...
1 ...
.. . .
.
.
0 ...
.. . .
.
.

(12)

Aqui voc deve notar, novamente, que se cm 6= 0, ento o sistema


impossvel.
O processo de transformar uma matriz a outra equivalente da forma exibida acima dito ser escalonamento ou reduo linha-a-linha. Com uma
matriz escalonada, podemos estudar as diversas solues que um sistema linear pode assumir. Esse trabalho feito at agora foi para demonstrar que
todo sistema linear equivalente a um sistema escalonado.

4 Analisando um sistema escalonado e suas solues


Dado um sistema linear com sua matriz associada escalonada, podemos extrair dele diversas informaes sobre como suas solues se comportam, sendo
essas muitas vezes mais teis do que achar as prprias solues do sistema.
Comearemos com uma denio e depois trabalharemos em cima de trs
teoremas bsicos.

Denio 3.

dito ser o posto p de uma matriz escalonada o nmero de


linhas no-nulas da mesma.
8

Teorema 1

(Sistema impossvel). Se a matriz associada (no-expandida) a


um sistema linear escalonado de m equaes e n incgnitas tiver posto p < m
e a i-sima equao de coecientes nulos tiver termo independente ci 6= 0,
ento o sistema no possui soluo real e chamado de sistema impossvel

Demonstrao. Suponha que o sistema tenha soluo. Tome a i-sima linha


nula e sua equao linear associada

0x1 + 0x2 + . . . + 0xn = ci


Realizando a operao, teremos 0 = ci , o que um absurdo!, pois supomos
que ci 6= 0. Logo o sistema linear no possui soluo real e dado como
sistema impossvel.
Um exemplo simples de sistema impossvel:

1 0 0 3 0
0 1 0 0 0

0 0 1 1 0
0 0 0 0 1

(13)

Teorema 2

(Sistema possvel e indeterminado). Se a matriz associada expandida a um sistema linear escalonado de m equaes e n incgnitas tiver
posto p < m e no for impossvel, ento ele possui innitas solues.

Demonstrao. Note, primeiro, que a matriz escalonada associada expandida


possui n+1 colunas. Se o sistema possui ao menos uma linha completamente
nula (isto , p < n), havero pivs apenas para p variveis, sendo que sobraro
n p variveis livres, ou seja, o sistema possuir innitas solues reais e
ser dito sistema possvel e indeterminado.

Note que esse teorema pode ser adaptado facilmente para sistemas lineares que possuem menos equaes que incgnitas (m < n), visto que
possvel substituir a matriz associada por outra de ordem superior (n n),
adicionando n m linhas nulas sem perda de generalidade. Por exemplo:

1 0 0 3 2
1 0 0 3 2

0 1 0 0 3 0 1 0 0 3
(14)
0 0 1 1 8
0 0 1 1 8
0 0 0 0 0

Teorema 3 (Sistema possvel e determinado).

Se a matriz associada expandida a um sistema linear escalonado de m equaes e n incgnitas tiver posto
p = m e no for impossvel, ento ele possui apenas uma solues.
9

Demonstrao. Esta demonstrao facilmente deriavada da anterior, sendo

que poderia at ser colocada junta. Aqui tomaremos a idia de quando


p = m. Note, primeiro, que a matriz escalonada associada expandida possui
n + 1 colunas. Se o sistema possui no possui nenhuma linha completamente
nula (isto , p < n) e nem impossvel, havero pivs apenas para todas
asm = n = p linhas e colunas, ou seja, no haver qualquer varivel livre e
todas estaro muito bem denidas, logo o sistema possui soluo nica e
dito ser sistema possvel e determinado.
Um exemplo simples de um sistema possvel e determinado:

1 0 0 0 8
0 1 0 0 9

0 0 1 0 5
0 0 0 1 1

(15)

Voc pode tentar perceber (e provar por voc mesmo, com algum conhecimento de lgebra Linear) que quando temos m > n e um sistema possvel
e determinado, ento h algumas equaes (quantas?2 ) que so linearmente
dependentes das outras. Tambm possvel demonstrar facilmente a partir
do que foi dito que se um sistema linear possui innitas solues e tem m > p,
ento h m p equaes linearmente dependentes. Como o conceito de dependncia linear no ser apresentado nesse trabalho, ca ao leitor observar
e tentar demonstrar tais coisas.
Se ainda no foi notado, importante que isso seja percebido o mais
rpido possvel. O nmero de colunas usadas na matriz associada (noexpandida) justaente o nmero de incgnitas do sistema linear e o nmero
de linhas o nmero de equaes. Isso deve ser bvio para qualquer um a
partir de agora, j que a partir disso que trabalharemos no mtodo computacional.

5 Anlise computacional
Depois de discutirmos o algoritmo manual e as operaes bsicas para serem usadas numa sequncia lgica, comearemos aqui a discutir uma soluo
computacional para o problema de resolver sistemas de equaes lineares.
Fica claro aqui que estaremos usando a linguagem C de programao, embora sua sintaxe seja de fcil compreenso e permita ser convertida para
quase qualquer outra linguagem muito facilmente. O importante, acima da
2m n

10

sintaxe usada, entender a lgica sobre a qual estaremos trabalhando. O


leitor deve estar familiarizado com os conceitos de matriz e vetor (arrays ) na
programao antes de continuar.
Assim como qualquer outro programa de computador, o nosso algoritmo
ter trs partes bsicas: a entrada, o ncleo e a sada. Na entrada, como
o nome sugere, faremos a leitura dos dados enviados pelo usurio e guardaremos o que for necessrio em variveis ou matrizes. No ncleo, faremos
o processamento principal ( essa a parte mais difcil do trabalho, onde a
verdadeira lgica est envolvida); essa etapa dividiremos em mais duas: o
escalonamento e a anlise de resultados. Na sada, iremos tomar os dados
resultantes do processamento e mostr-lo ao usurio.
5.1

A entrada

A entrada de dados, apesar de parecer ser algo banal, deve ser analisada com
cuidado, pois necessrio criar uma interface amigvel para que o usurio
no se perca. Para nosso programa, so trs as coisas bsicas que devemos
perguntar: Quantas variveis? Quantas equaes? Quais os valores do coeciente?. Estando isso tudo denido, cabe a ns comear a escrever nosso
cdigo.

#include <stdlib.h>
#include <stdio.h>
#include <cmath>
main()
{
int Linhas, Colunas, s, o;
while (o!=0) {
system("cls");
printf("\t\t\tSOLUCIONADOR DE SISTEMAS LINEARES\n\n\n\n");
printf(" \4 Entre com o numero de incognitas ou 0 para ajuda: ");
scanf("%d", &Colunas);

11

Nesse primeiro momento, estamos introduzindo duas coisas: chamamos


duas das mais importantes variveis (uma que dita o nmero de linhas e outra
que dita o nmero de colunas) e outras duas auxiliares. Tambm comeamos
a criar nossa interface, dando o ttulo do programa e pedimos o nmero de
incgnitas. Note que aqui temos vrios tipos de entrada: invlida, ajuda e
vlida. A entrada ser invlida se o usurio digitar um nmero invlido de
incgnitas, sem ser o zero, ou seja, nos resta apenas os inteiros negativos.
No queremos que nosso programa pare de funcionar caso a entrada esteja
errada, ento precisamos pedir o nmero de colunas at o usurio entrar com
um nmero vlido.
Tambm interessante adicionar uma opo de ajuda, que auxiliar o
usurio enquanto faz uso do programa. Para isso usaremos a entrada 0.
A condio while (o!=0) ser explicado posteriormente. Veremos como
caro nossas condies:

while (Colunas<=0) {
if (Colunas==0) {
printf("Insira alguma ajuda aqui");
system("pause");
system("cls");
printf(" \4 Entre com o numero de incognitas ou 0 para ajuda: ");
scanf("%d", &Colunas);
}
if (Colunas<0) {
printf("Voce entrou com um numero invalido de incognitas
(deve ser um inteiro positivo)\n \4
Entre com o numero de incognitas ou 0 para ajuda: ");

scanf("%d", &Colunas);
}

Veja agora que realmente adicionamos as condies ditas inicialmente.


Caso a entrada for 0, redicionaremos para uma ajuda e perguntaremos, posteriormente, a mesma pergunta (Quantas incgnitas?). Caso o nmero de
incgnitas digitado for invlido, ento o programa dir que invlido e perguntar novamente.
12

Agora importante notar a estrutura com a qual foi feito esse sistema.
Caso no tivssemos colocado o while inicial e partssemos diretamente para
algo do tipo while (Colunas==0) e depois while (Colunas<0), teramos
problema, pois caso voc digitasse 0 duas vezes, o programa iria aceitar esse
resultado como nmero de colunas (incgnitas), deixando o cdigo vulnervel.

printf(" \4 Entre com o numero de equacoes: ");


scanf("%d", &Linhas);
while (Linhas<=0) {
printf("Voce entrou com um numero invalido de equacoes
(deve ser um inteiro positivo)\n \4
Entre com o numero de equacoes: ");
}

scanf("%d", &Linhas);

printf(" \4 Deseja visualizar passo-a-passo a resolucao


feita por escalonamento (1 - sim, 0 - nao)? ");
scanf("%d", &s);
while (s!=0 && s!=1) {
printf("%d",s);
printf("Voce fez uma entrada invalida\n \4
Deseja visualizar passo-a-passo a resolucao
feita por escalonamento? (1 - sim, 0 - nao)? ");
}

scanf("%d", &s);

Colunas++;
Essa parte apenas uma continuao da primeira: estamos pedindo o nmero de equaes presentes no sistema linear que ser avaliado e checaremos
se o nmero dado vlido. Mas aqui entra, tambm, um grande diferencial:
podemos mostrar ao usurio a matriz sendo escalonada e o melhor de tudo
que isso vir como um presente para ns, j que quase nada de cdigo extra
precisar ser feito, como ser visto quando estivermos analisando o ncleo do
13

cdigo (aqui tambm devemos checar se a entrada vlida ou no). Estamos aumentando o nmero da varivel Colunas pois temos que contabilizar
o termo independente do sistema e no apenas o nmero de incgnitas.

int i, j, c=0, l=0, x=0, m,n;


float Matriz[Linhas][Colunas], v, d[Linhas], e[Colunas];
for (i=0;i<=(Linhas-1);i++) {
for (j=0;j<=(Colunas-1);j++) {
Matriz[i][j]=0;
}
}
Nesse pequeno prximo trecho estramos introduzindo todo o resto de
variveis que sero usadas no decorrer do programa. Dentre elas est a mais
importante: a matriz Matriz[Linhas][Colunhas]. Nela sero armazeadas
todas os coecientes e termos independentes do sistema linear que dever
ser escalonado. Ela a entrada principal e tambm ser a sada principal
e nela que iremos mexer durante todo o processamento. Todas as outras
variveis sero usadas apenas em auxlio.

Veja que estamos usando Linhas-1 e Colunas-1. O 1 justicado


pelo fato do contador iniciar no zero e no no 1. Sendo assim, temos que
percorrer at um nmero antes do real. Esse conceito ser amplamente usado
no decorrer do cdigo, ento necessrio entender muito bem esse passo.
O loop feito serve justamente para zerar a matriz principal, j que ela
assume valores aleatrios quando chamada. Veremos logo em seguida que
essa operao importante para manter a beleza da interface no prximo
passo.

for (i=0;i<=(Linhas-1);i++) {
for (j=0;j<=(Colunas-1);j++) {
system("cls");
for (c=0;c<Colunas-1;c++) printf("
printf("\n\n");
for (l=0;l<Linhas;l++) {
printf("\n");
14

a[%d]", c+1);

for(c=0;c<Colunas;c++) {
printf("
%.2f", Matriz[l][c]);
}
}
if (j<Colunas-1) printf ("\n\n\n\nDefinicao da %da equacao:\n\n
\4 Entre com o coeficiente da %da incognita: ",i+1, j+1);
else printf ("\n\n\n\nDefinicao da %da equacao:\n\n
\4 Entre com o termo independente: ",i+1);

scanf("%f", &Matriz[i][j]);

Essa parte a qual realmente armazenaremos os coecientes e termos


das equaes lineares. Note que, antes de pedir o valor do termo, estamos
exibindo a matriz inteira, de forma que que claro os termos j digitados e
forme um ambiente mais agradvel para o leitor. O comando system("cls")
serve justamente para limpar a tela. Teremos uma interface mais ou menos
como a apresentada na gura abaixo:

Para deixar a interface organizada assim, preciso "visualizar"o cdigo,


de modo que voc veja onde os espaos devem ir para formar uma estrutura
agradvel. Muitas vezes so necessrias algumas tentativas, compilando o
cdigo diversas vezes at acertar. O cdigo ainda pode ser otimizado da
seguinte forma: note que caso a entrada tiver mais de um algarismo (seja ela
10, 8, 65241 e no 2, 3, 2, 3), a matriz comear a car desorganizada.
Isso pode ser resolvido com alguma lgica e usando cdigos. Pode-se contar
o tamanho da entrada e somar ou diminuir espaos de forma a termos uma
estrutura harmnica.
15

Em termos de cdigo, importante notar que estamos usando dois "grupos"de variveis para percorrer as linhas e colunas da matriz. As variveis i
e j serviro para o mesmo de antes: sero nossas principais para percorrer
as linhas e colunas. As variveis c e l sero usadas apenas para a exibio
da nova matriz.
Com isso feito, concluimos nalmente a parte de entrada de dados para
nosso programa. Agora iremos para a parte provavelmente mais difcil: o
ncleo de processamento, onde iremos trabalhar na matriz para obt-la escalonada. J devemos ter, nesse ponto, obtido todas as informaes necessrias
para o desenvolvimento dessa segunda parte.
5.2

O ncleo

Antes de continuar, temos que ter em mente que apenas trs variveis so
importantes para o funcionamento do processo. De fato, tudo que zemos na
parte anterior foi para armazenar dados nessas variveis. Elas so: Colunas,
Linhas e Matriz[Linhas][Colunas] (embora tenhamos guardado alguma
informao em outras variveis como a o e s, no so cruciais na execuo
do programa).
Essa segunda parte ainda se divide em mais duas. Na primeira trabalharemos em cima do escalonamento da matriz e, na segunda, a partir da matriz
escalonada, extrairemos dela os resultados para serem mostrados na prxima
seo, a sada.

5.2.1 O escalonamento
Essa parte do cdigo , provavelmente, a mais confusa, j que difcil dividir
de modo organizado, sendo que as partes esto todas interconectadas. No
entanto, tentaremos fazer isso funcionar.
O escalonamento, podemos dizer, o ncleo do ncleo do programa.
Veremos que, enquanto realizamos a operao de escalonar a matriz (que
est guardada na varivel Matriz[Linhas][Colunas]), teremos que despistar alguns problemas, como diviso por zero. Pensando como um computador, nosso primeiro objetivo transformar o piv, ou seja, a entrada
Matriz[i][i] em 1 e dividir o resto da linha pelo valor anterior do piv.
Mas, caso acontea desse nmero ser 0, no poderemos realizar nenhuma
diviso. Ento a primeira precauo que devemos tomar justamente essa:
mudar a linha caso o piv seja zero. Note que no teremos nenhuma ocor16

rncia de coluna completamente nula, pois isso invalidaria uma varivel e


teramos uma a menos na contagem.

for (i=0;i<Linhas;i++) {
l=0;
while (Matriz[i][i] == 0) {
if (l=Linhas) break;
for (j=0;j<Colunas;j++) {
e[j] = Matriz[i+l+1][j];
Matriz[i+l+1][j] = Matriz[i][j];
Matriz[i][j] = e[j];
}
l++;
}
Antes ainda de comear a anlise desse cdigo, importante tomar uma
nota mental que difcil de trabalhar, muitas vezes. Por intuio, acamos,
na maior parte do tempo, tomando como referncia a primeira linha, tendo
como piv o elemento Matriz[0][0]. No entanto, isso pode nos atrapalhar
bastante, j que esse o nico caso em que o pv justamente o primeiro
elemento da linha, sendo que os procedimentos para as linhas posteriores
podem parecer contra-intuitivos. Para isso, recomendo ter sempre em mente
um outro piv qualquer, como o da segunda linha (Matriz[1][1]).
Comeamos o cdigo j percorrendo as linhas com a varivel i. Logo em
seguida j entramos num loop que ir checar se o elemento piv zero (e, caso
for, mudar a linha por inteira). importante notar que estaremos fazendo
uso de um vetor auxiliar (um vetor nada mais que uma matriz unidimensional) que chamamos de e[Colunas] e servir para fazer a mudana de linha.
Digamos que queremos trocar a linha A pela linha B , faremos o seguinte
procedimento: A = e, B = A e, nalmente, B = e. como mudar duas
variveis comuns de valor, no entanto agora temos um vetor, requerendo um
novo loop para fazer a troca.
Depois que trocamos as linhas, ele checar novamente, a partir do while,
se o piv nulo. Caso for, a troca continuar at atingirmos a ltima linha
17

(para que no entremos num loop innito). Veja que desnecessrio corrermos para as linhas superiores, j que elas estaro organizadas (veja aqui a
importncia de considerar um piv diferente do a11 ).
Agora que temos certeza que o piv que trabalharemos denitivamente
no nulo, podemos continuar sem medo nossas divises.

if (Matriz[i][i] != 0) {
v = Matriz[i][i];
for (j=0;j<Colunas;j++) {
Matriz[i][j] /= v;
}
}
Usamos novamente uma condio para checar se o piv zero apenas por
garantia (no seria necessrio). Caso ele passe no teste (o que deve acontecer),
comearemos o processo de transformao do piv em 1 e, consequentemente,
dividiremos a linha inteira pelo valor que ser gravado na varivel v. O loop
em que usamos o for serve justamente para desse processo, indo de coluna
em coluna. Voc pode notar que poderamos comear o loop apenas em j=i e
no em j=0, pois as entradas anteriores a j=i j devem ser zero, no fazendo
diferena alguma a diviso.

for (l=0;l<Linhas;l++) {
d[l] = Matriz[l][x];
if (l!=i) {
for (c=0;c<Colunas;c++) {
if (c>=x) {
Matriz[l][c] = Matriz[l][c] - d[l]*Matriz[i][c];
//Aqui entrar uma outra parte que ser explicada posteriormente

}
x++;
}

18

Essa ser, provavelmente, a parte mais confusa de toda a leitura do cdigo


(como se o resto j no fosse confuso o suciente). Caso o leitor seja capaz
de ver, aqui que comearemos a zerar a coluna na qual o piv est presente.
Essa parte apresenta complicaes por alguns motivos que j devem estar
aparentes: estamos constantemente trabalhando com loops e percorrendo linhas e colunas em variveis distintas; isso causa grande confuso ao tentar
reproduzir mentalmente o cdigo, por isso importante tentar ir aos passos,
mentalizando uma de cada vez. Usar uma folha de papel para escrever uma
matriz pequena e ir seguindo o cdigo tambm ajuda. necessrio lembrar de alguns loops que zemos, j que estaremos recorrendo a alguns deles
frequentemente.
Note que j estamos percorrendo as linhas com a varivel i, no entanto,
ela usada, primariamente, para identicar o piv. No podemos sair mexendo com ela de qualquer jeito, pois o programa perder a noo de qual foi
a ltima linha que trabalhou; teremos que introduzir uma nova. Usaremos a
varivel l para essa tarefa.
Outra coisa que preciso perceber que, por mais fcil que seja zerar a
coluna, no se pode esquecer de tambm subtrair das outras linhas da coluna;
para essa tarefa, estaremos utilizando a varivel d[l], que armazenar os
coecientes que devero ser multiplicados para fazer a subtrao. Funcionar
da seguinte forma: seja a o valor da entrada na linha "fonte"e b o valor da
entrada na linha "destino", ambas na coluna j . O novo valor da entrada
destino c na coluna j + 1 ser cnovo = cantigo ab. Isso deve car claro.
Veja tambm que se tivermos l=i, ou seja, os dois "varredores"de linhas
na mesma linha, isso indica que estamos tentando zerar o piv e isso no
pode acontecer de forma alguma! Para isso, temos que criar um if que ir
checar se isso acontece ou no.
Agora preciso algo que nos faa no voltar s colunas que j esto
"escalonadas", para isso, estaremos usando uma varivel que far a contagem
de quantas linhas j esto prontas. Esse o papel do x; essa varivel ser
incrementada toda vez que o loop for (i=0;i<Linhas;i++) rodar, pois,
como estamos tratando primariamente dos pivs (que possuem simetria, no
caso, aii , tanto faz se rodarmos por um varredor "geral"de colunas ou linhas.
Unindo todos esses conceitos que acabamos de ver, deve ser mais fcil
atravs do cdigo. O primeiro passo recomear um loop varrendo as linhas,
depois temos que checar se essa no a linha do piv (caso for, iremos apenas
19

ignor-la). Depois disso, varreremos as colunas para ir fazendo a subtrao


(ou zer-las, caso seja a coluna do piv). Lembrando que temos que usar
o contador para no fazer a subtrao nas colunas anteriores, j que isso
desescalonaria a parte que j est pronta.
Agora entraremos na parte central que foi escondida na parte acima do
cdigo. Tecnicamente, acabamos aqui o escalonamento da matriz.

if (s==1) {
system("cls");
for (m=0;m<Colunas-1;m++) printf("
a[%d]", m+1);
printf("\n\n");
for (n=0;n<Linhas;n++) {
printf("\n");
for(m=0;m<Colunas;m++) {
printf("
%.2f", Matriz[n][m]);
}

}
printf("\n\n");
system("pause");

O leitor deve lembrar de quando foi dito, quando descrevamos a entrada,


que seria dado quase que de graa um mtodo para mostrar a matriz sendo
escalonada. aqui que entra essa possibilidade. Note que exatamente no
lugar que esse cdigo ser adicionado est a mudana nos valores da varivel
e, como estamos trabalhando em ciclos, todo o trabalho que o computador
est fazendo pode ser mostrado facilmente.
L no incio, armazenamos na varivel s se o usurio gostaria de visualizar o processo de escalonamento. Em caso armativo, o cdigo acima
ser executado. Esse pedao do programa no nada mais que uma cpia
da matriz que mostrvamos no incio, no processo de obteno das entradas
(com algumas modicaes, claro). Como estramos dentro de vrios loops,
teremos que usar novas variveis para imprimir a matriz (aqui eu usei m e n).
E isso tudo que muda. Simplesmente imprimimos a matriz, muito fcil.

20

5.2.2 Interpretao do escalonamento


Na parte anterior, escalonamos completamente o sistema linear de equaes
e o guardamos na matriz Matriz[Linhas][Colunas]. A partir de agora,
usaremos essa varivel para fazer a interpretao dos resultados em termos
de equaes lineares, como foi visto na primeira parte desse trabalho. Essa
a segunda parte do ncleo do programa. Essa anlise continuar, em parte,
na sada, onde iremos dizer ao usurio se o sistema possvel (e dar a(s)
resposta(s)) ou impossvel.
O que temos de checar, nessa ordem, :
1. H alguma linha cujo nico elemento no nulo o que est na ltima
coluna? Se sim, o sistema impossvel;
2. H alguma linha completamente nula?;
(a) Se houver, quantas so? (note que isso nos dar o nmero de
variveis livres, atravs do posto);
(b) Se no houver, o sistema possvel e determinado.
3. Ento o sistema possui uma nica soluo.
Para isso, iremos usar variveis para contar o nmero de linhas nulas e
alguma outra para checar se essas linhas nulas possuem o ltimo elemento
tambm nulo. O mtodo que usaremos aqui para descobrir se o ltimo elemento das linhas nulas realmente zero, ser somar o valor absoluto de todos
esses elementos numa varivel. Se o sistema for possvel, o valor dessa varivel ser obrigatoriamente zero e, caso seja diferente disso, indica que o
sistema realmente impossvel.

c=0; l=0;
for (i=1;i<Linhas;i++) d[i]=0;
for (i=0;i<Linhas;i++) {
v=0;
for (j=0;j<Colunas-1;j++) {
v += fabs(Matriz[i][j]);
}
if (v==0) {
if (Matriz[i][Colunas-1] != 0) c++;
else l++;
21

}
else {
d[i] = Matriz[i][Colunas-1];
}

Embora estejamos usando algumas das mesmas variveis de antes (c ser diferente de zero caso o sistema seja impossvel -, l - contar o nmero
de linhas completamente nulas -, v - far a soma de todos os elementos da
linha, com exceo do ltimo - e o vetor d - que ir armazenar o valor da
ltima coluna caso o sistema seja possvel), elas no tero a mesma funo
de antes.
Comeamos fazendo a soma na varivel v da linha inteira at uma casa
antes da ltima (disso vem o for (j=0;j<Colunas-1;j++) e importante
notar que temos que trabalhar com valores absolutos, por isso o uso da funo
fabs(), j que poderamos ter resultados do tipo 3+(3) = 0). Caso v ainda
tenha valor zero, isso quer dizer que a linha nula at ali, nos restando checar
se o ltimo elemento tambm . Caso no for, aumentamos o valor da varivel
c e, em caso positivo, da l.
Se ele no se encaixar em nenhuma das especicaes, ento o sistema
necessariamente possvel, ento os valores b1 , b2 , , bn da ltima coluna so
as respostas para o sistema linear, nessa ordem. Esses valores armazenaremos
no vetor d[i].
Aqui j temos toda a interpretao feita. Na prxima parte, a sada,
falaremos um pouco mais sobre essa anlise, quando formos dar o resultado
ao usurio. Mas o essencial est feito.
5.3

A sada

A sada, do mesmo modo que a entrada, um modo de interao com o


usurio e, por esse motivo, deve ser compreensvel e possuir uma interface de
fcil interao.
Nesse passo, precisamos mostrar ao usurio algumas coisas:
1. Se o sistema for impossvel, dizer que ele impossvel;
2. Se o sistema for possvel e indeterminado, mostrar isso e dar todas as
solues possveis;
22

3. Se o sistema for possvel e determinado, dar a soluo nica.

system("cls");
if (c!=0) printf("\n\nO sistema de equacoes lineares eh impossivel.\n\n");
else {
if (l==0 && Linhas == Colunas-1) {
printf("Resultado do sistema linear:\n\n");
for (i=0;i<Linhas;i++) {
printf("\nO valor da %da incognita eh:
a[%d] = %.2f", i+1,i+1, d[i]);
}
}
else {
printf("\n\nO sistema possui infinitas
solucoes. Suas solucoes resolvem
o sistema abaixo:\n\n");
Como vimos anteriormente, se o valor da varivel c for diferente de zero,
o sistema ser impossvel e pararemos por aqui.
Caso no seja nulo, teremos as outras duas possibilidades: ele certamente determinado, mas pode ter innitas solues ou apenas uma. Veja
que se uma matriz possui o nmero de incgnitas maior que o nmero de
equaes (como foi enunciado o teorema), o sistema associado, se no for
impossvel, necessariamente indeterminado. Sendo assim, s teremos uma
nica soluo se l for nulo e o nmero de incgnitas for exatamente igual ao
nmero de linhas no-nulas, ou seja, Linhas = Colunas 1 (estamos usando
o 1 pois eliminaremos a coluna dos termos independentes, j que no contam como incgnitas). Caso essas condies sejam encontradas, daremos,
nalmente, uma nica resposta ao sistema linear, que est armazenada no
vetor d[i].
Agora s nos resta a possibilidade do sistema ter innitas solues. Para
isso, teremos que encontrar um mtodo de listar todas as possveis n-uplas
de nmeros reais que satisfazem a equao. No muito difcil perceber que
a matriz escalonada forma um novo sistema totalmente equivalente, porm
mais simplicado. exatamente esse sistema que mostraremos ao usurio.

for (i=0;i<Linhas;i++) {
printf("\n");
23

}
} }

for (j=0;j<Colunas;j++) {
if (Matriz[i][j] != 0) {
if (j < Colunas-2 && Matriz[i][j]!=0)
printf("%.2f*a[%d] + ", Matriz[i][j],j+1);
else
if (j == Colunas-2)
if (Matriz[i][j]!=0) {
printf("%.2f*a[%d] = ", Matriz[i][j],j+1);
}
else {
printf("= ");
}
else
if (j == Colunas-1) printf("%.2f", Matriz[i][j]);
}
if (Matriz[i][j] == 0 && j==Colunas-1)
printf("%.2f", Matriz[i][j]);
}

Embora esse pedao de cdigo possa parecer extremamente complicado,


na verdade ele no . O que fazemos aqui simplesmente exibir as solues
do sistema linear da forma como mostra a gura abaixo:

Ou seja, no cdigo simplesmente transcrevemos a matriz em forma de


sistema de equaes lineares, escondendo os coecientes nulos. O cdigo
parece complicado pois temos que saber quando e onde incluir os sinais de
multiplicao e igualdade, assim como a varincia da incgnita.
A soluo est basicamente dada. Podemos ainda mostrar como ca a
matriz escalonada ao usurio, mas isso mera questo de desejo. O cdigo
pode ser copiado de outras impresses que zemos de matriz, com algumas
modicaes. Segue abaixo como z:
24

printf("\n\n\n\n\n\n\t\t\tMATRIZ ESCALONADA:\n\n\n\n\n\n");
for (c=0;c<Colunas-1;c++) printf("
a[%d]", c+1);
printf("\n\n");
for (l=0;l<Linhas;l++) {
printf("\n");
for(c=0;c<Colunas;c++) printf("
%.2f", Matriz[l][c]);
}
printf("\n\n\n\n");
system("pause");
printf("\n\n\n\n \4 Digite zero pra sair ou qualquer
outro numero para resolver outro sistema: ");
scanf("%d",&o);
}
}
Veja que l no incio do cdigo adicionamos um while (o!=0) e aqui seu
uso se justica. Caso o usurio deseje resolver outro sistema linear, ele pode
simplesmente digitar qualquer entrada. Caso queira sair, basta entrar com
0. importante essa ferramenta para sair do loop, visto que ciclos innitos
so extremamente mal vistos dum ponto de vista computacional.
Esse, nalmente, foi o ltimo passo e conclumos todo o trabalho computacional de resoluo de sistemas de equaes lineares.

6 Concluso
Conclumos, aqui, o estudo computacional, com um pouco do lado matemtico, dos sistemas de equaes lineares. Meu objetivo foi tentar expor da
forma mais clara possvel, embora possa no ter tido sucesso em alguns (ou
todos) momentos. Esse tipo de problema algo clssico na computao e
possui uma innidade de aplicaes em todos os campos do conhecimento,
como o leitor j deve estar ciente. Numa outra oportunidade, pretendo mostrar algumas dessas aplicaes, talvez editando este trabalho ou at mesmo
criando um novo.
Este trabalho serviu como aprendizado para mim (por ser algo quase
totalmente espontneo), ajudando a xar contedos vistos nas disciplinas de
25

Computao Cientca I e lgebra Linear, correlacionando-os. Espero que


tenha sido til tambm ao leitor.
Para contato, sugestes ou correes, favor enviar um e mail para gustavo@hobold.com.
Obrigado.

7 Referncias bibliogrcas
1. CALLIOLI, Carlos Alberto; COSTA, Roberto Celso Fabricio; DOMINGUES, Hygino H. (Hygino Hugueros). Algebra linear e aplicaes.
6. ed. reform. So Paulo (SP): Atual, 1990. 352p. ISBN 8570562977
2. LIMA, Elon Lages. INSTITUTO DE MATEMATICA PURA E APLICADA (BRASIL). Algebra linear. Rio de Janeiro: IMPA, c 1998.
(Matematica universitaria ) ISBN 8524401028
3. BOLDRINI, Jose Luiz . Algebra
Paulo: Harbra, c1986. 411p.

linear.

3.ed. amp. e rev. So

4. BEEZER, Robert A. UNIVERSITY OF PUGET SOUND.


Course in Linear Algebra. ver 2.22. 2010. 942p.

26

A First

Potrebbero piacerti anche