You are on page 1of 26

Solução computacional de sistemas de

equações lineares lineares por escalonamento
com base em linguagem C de programação
Gustavo Marques Hobold

gustavo@hobold.com

Universidade Federal de Santa Catarina
5 de março de 2011

Resumo

Este trabalho tem o intuito de desenvolver um algoritmo para a resolução de sistemas lineares de qualquer ordem através da manipulação
do sistema em forma matricial, até atingir a forma escalonada. Será
mostrada a parte matemática teórica que rege a exatidão dos resultados, como a demonstração de teoremas que são, muitas vezes, engolidos
sem certeza de funcionamento. Para a resolução, será usado e comentado um algoritmo escrito em linguagem C. A proposta foi feita na
disciplina INE5231 (Computação Cientíca I) no semestre 2010.2 da
Universidade Federal de Santa Catarina. O código 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 são, com certeza, amplamente conhecidos e devem ter sido
objeto de estudo do leitor em algum ponto da matemática. No entanto,
embora muitos tenham a visão mais intuitiva do que signica um sistema de
equações lineares (ou até mesmo uma equação linear por si só), queremos,
aqui, introduzir uma visão mais matemática para que depois possamos partir
para a técnica de resolução, que nos é interessante no ponto computacional.
Começaremos denindo nossos objetos de estudo, então.
1

Denição 1. Dados a1 , . . . , an , b ∈ R, uma equação é dita ser linear quando
é da forma

(1)

a1 x1 + a2 x2 + . . . + an xn = b
com n > 1 ∈ N e x1 , . . . , xn variáveis em

R.

É dita solução para a equação linear a n-upla de números reais (não
necessariamente distintos) (c1 , c2 , . . . , cn ) que satisfaz a igualdade

a1 c 1 + a2 c 2 + . . . + an c n = b
Os termos a1 , . . . , an são ditos coecientes da equação e b é dito ser o
termo idenpendente.

Denição 2.

Sejam m, n ∈ N(≥ 1) e dados a1 , . . . , an , b1 , . . . , bm ∈
conjunto de m equações lineares com n incógnitas 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)

m

tal que x1 , . . . , xn são incógnitas é dito ser um sistema de equações lineares
ou simplesmente sistema linear.
Uma solução de sistema linear é uma n-upla de números reais (c1 , . . . , cn )
que satisfaz simultaneamente todas as equações, 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

m

Denimos, aqui, os dois objetos mais importantes para nossa abordagem.
Estaremos tratando da resolução de sistemas de equações lineares (dado um
sistema linear, como encontrar a(s) n-upla(s) que satisfaz(em)?). Alguns
métodos já devem vir a mente, como substituir variáveis e métodos de adição
e subtração previamente vistos. No entanto, como deve ser possível perceber,
os coecientes das equações do sistema 2 possuem uma certa organização
própria em relação à incógnita e à equação que está associada. Para um bom
observador, é fácil notar que eles poderão assumir um caráter matricial a
2

O que será apresentado a seguir. utilize por escalonamento o que já é sabido. Começaremos com um sistema linear simples para exemplo:   3x + 5y + z = 16 2x + 3y = 8  5x = 5 Esse sistema é de simples solução. poderá (e provavelmente será) bastante cansativo para o leitor. substuir na segunda equação. tendo que recorrer a outros métodos.   3x + 5y + z = 20 2x + 4y + z = 15  5x + 4x + 2z = 25 Essa equação já mostra mais diculdade para ser resolvida por métodos substitutivos. apenas um que nos interessa (que é o mais utilizado e fácil de ser utilizado em métodos computacionais). o método de substituição nem sempre é bem vindo. pois podemos encontrar o valor de x (que é uma equação linear de apenas uma incógnita). no entanto não caberá nesse trabalho descrever todos. 3 . mais absurdo esse método ca. cabendo a nós desenvolver uma nova técnica para resolver mais facilmente esse tipo de problema. dado como trivial). teremos um resultado interessante. Note que se tomarmos a primeira equação desse sistema e somarmos com o oposto da segunda. mas será feita uma abordagem mais formal posteriormente) e o porquê de funcionar. pois o tempo de processamento ou o trabalho manual não vale a pena. quando trabalhamos com sistemas lineares mais cimplicados e maiores. É necessária a atenção do leitor para perceber pequenas sutilezas que darão um entendimento maior. No entanto.partir de agora (use aqui sua visão intuitiva de matriz). no entanto é de extrema importância para o entendimento de como funciona o método de escalonamento (novamente. assim percebemos que. Sistemas de equações lineares são um dos campos de pesquisa da álgebra linear e existem diversos métodos de resolução. quanto maior a ordem. que é justamente o que será feio. achar o valor de y e substituir novamente na primeira equação para encontrar o valor de z (cabe ao leitor resolver esse sistema.

temos de pensar logicamente para chegar o mais rápido possível a uma solução. pois estamos adicionando o mesmo valor para ambos os lados da primeira equação1 . complicando ainda mais o sistema linear. Outra operação que podemos realizar sem medo é a de multiplicar uma das equações por uma escalar qualquer. c = d. 1). podemos car realizando essas operações o dia inteiro sem chegar a lugar algum ou sequer perto de uma resposta. Com o sistema linear dado acima.primeira equação segunda equação }| { z }| { z 3x + 5y + z − (2x + 4y + z) = 20 + (−15) x+y =5 É importante notar que esse passo que acabamos de tomar é válido. 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 operação que será essencial para continuar o estudo é entender que trocar as linhas de posição não alterará o resultado (isso deve ser óbvio para qualquer um). 2.    5x + 4x + 2z = 25 2x + 4y + z = 15   x + 5 y + 1 z = 20 3 3 3 No entanto. queremos. y.   x + 0y + 0z = 3 0x + y + 0z = 2  0x + 0y + z = 1 que nos daria a solução (x. com as operações mostradas. Como nosso objetivo é resolver. Podemos trocar a primeira linha com a última sem problemas e obter um novo sistema de equações lineares equivalente. z) = (3. Veja que se multiplicarmos a primeira equação por 1/3. simplicá-lo até car como o abaixo. 1 Podemos ver como isso é válido se tomarmos duas igualdades a+c=b+d 4 a = b. então .

não é difícil notar que. O segundo sistema mostrado acima é impossível e também é facil perceber o porquê: a primeira parte da segunda equação que o compõe é igual à primeira (multiplicada por uma escalar 3). no entanto. no entanto. não há solução para este sistema. Sendo assim. ou seja. todos os termos aii . pois poderíamos perder a idade do universo calculando sem chegar a lugar nenhum. que será feito em breve. para um sistema linear. ainda. há sistemas lineares que sequer possuem solução. Sistemas como os abaixo possuem innitas soluções e nenhuma solução. Felizmente. i ∈ N. será fácil perceber o porquê do primeiro sistema acima possuir innitas soluções: uma das equações lineares que o compõe é combinação linear das outras duas. 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. esse assunto é mais facilmente tratado quando obtermos a visão matricial dos sistemas lineares. mas. 2 Iniciando um algorítmo manual Como dito anteriormente. no sistema inicial. i ≤ m devem ter valor 1 e todos os outros aij com i 6= j devem ser nulos am de encontrarmos uma única solução. a igualdade é diferente. Com isso percebido. temos que desenvolver um algoritmo ecaz para a resolução de sistemas lineares através das três operações básicas anteriormente citadas (mudança na posição da equação.Veja que. multiplicação por escalar e adição). a resposta esperada necessariamente deve ter esse valor. e todas essas possibilidades devem ser levadas em conta na criação de um algorítimo (computacional ou não). não são todos os sistemas lineares que possuem uma única solução ou. não temos o primeiro coeciente a11 = 1. existe ao menos uma n-upla de reais não todas nulas que multiplicam as outras equações para obter a que é dita ser linearmente dependente. No entanto. Como nosso objetivo é tomar um sistema linear e chegar num outro equivalente da forma 5 .

 x1 + 0x2 + .. (5) = cm (note desde já que se bm 6= 0. obtendo o valor de cada incógnita. Isso pode ser feito multiplicando e somando a i-ésima equação com a equação das outras linhas que devem ser zeradas.   0x1 + 0x2 + . . devemos zerar todos os outros coecientes depois de transformar o elemento aii (que passaremos a chamar de pivô) em 1. então deixaremos isso para quando trabalharmos com 6 . Note que realizar essa operação em todas as linhas o mais rápido possível não nos leva a lugar nenhum. .  . ou seja.. + xn     . multiplicar por 1/aii (se aii 6= 0. mas massante). . Mas é claro que ainda não cobrimos todos os casos e generalizar é bastante trabalhoso (não é difícil. = cn .   . . Isso pode ser facilmente feito multiplicando a i-ésima equação do sistema linear pelo inverso do seu elemento aii . . o sistema não possui solução). no sistema linear   3x + 2y + z = 0 15x + 6y + 3z = −6 (6)  7x + 2y + z = −4 Se multiplicarmos a primeira equação por −15 e somarmos com a segunda (deixando a equação resultante no lugar da mesma. teremos o termo a31 zerado. Se zermos o mesmo para a terceira equação. percebese que o primeiro passo de um algoritmo é transformar aii = 1. Certique-se de que esse método realmente funciona com base nas operações previamente vistas). E se repetirmos esse processo para todas os pivôs. A escalar que multiplicará a i-ésima equação deve ser escolhida com cuidado. facilmente encontramos a solução do sistema linear na forma   x + 0y + 0z = −1 0x + y + 0z = 1 (7)  0x + 0y + z = 1 Como era esperado.. teremos o termo a21 zerado. Com esse pensamento em mente. . + 0xn     0x1 + x2 + .. o caso aii = 0 será tratado posteriormente). . por exemplo. 0x1 + 0x2 + . já que as linhas abaixo e acima dela terão que ser modicadas para zerar todos os outros coecientes da mesma variável xi . + 0xn = c1 = c2 . . . . + 0xn    .

am1 am2 . Por 7 . . podemos tomar um sistema de equações linear S   a11 x1 + a12 x2 + . No entanto.  . não sendo possível se aii = 0. Você pode começar pensando na primeira parte do algorítmo. . ... a12 a22 . a1n b1  a21 a22 . que é facilitada quando introduzimos um pivô não-nulo. . . . . 3 Trabalhando com matrizes Para um bom observador. os termos independentes das equações lineares do sistema S .. + a x = b m1 1 m2 2 mn n m e associar a uma equação matricial A · X = B tal que    A=  a11 a21 . que os coecientes das equações lineares podem ser escritos numa matriz. a2n .. .      (9) bm tal que A é dita ser a matriz dos coecientes de S. . . .. mas essa operação possui papel essencial no trabalho matricial que faremos posteriormente. ..       . . + a1n xn = b1    a21 x1 + a22 x2 + . .. . ainda não é essa notação que gostaríamos de usar. também. ou seja. amn bm Note que a matriz expandida é muito similar ao sistema original. . principalmente na interpretação do computador. am1 am2 . como já foi dito anteriormente. ... .. . . Escreveremos a matriz expandida de S da forma   a11 a12 . + a2n xn = b2 S: (8) . amn       . . B =    xm b1 b2 . o sistema da forma.    a x + a x + . .  . X =    x1 x2 . é fácil perceber.  . Note que caso algum pivô assumir valor zero por motivo das operações realizas (ou se o sistema foi apresentado de tal forma).matrizes.. a2n b2    M =  . a1n . . . no entanto as incógnitas são omitidas e identicadas pela coluna na matriz. . . . (10) . por enquanto. onde multiplicamos a equação linear por 1/aii . .  . deveremos mudar a posição da linha para que o pivô deixe de ser nulo  leve isso como simples estética... Temos que encontrar uma matriz que envolva. . .. . .

 .. podemos estudar as diversas soluções que um sistema linear pode assumir. 0 . que se cm 6= 0. . . 0  0 c1 0 c2   . (12) Aqui você deve notar. . sendo essas muitas vezes mais úteis do que achar as próprias soluções do sistema. . Vejamos um exemplo de um sistema linear com sua matriz associada.exemplo: os coecientes que vinham a frente da incógnita x5 encontram-se na linha 5 da matriz expandida associada ao sistema desejado... estaremos multiplicando também a linha correspondente da matriz associada e isso vale para todas as outras operações dadas (é simples vericar você mesmo. O processo de transformar uma matriz a outra equivalente da forma exibida acima é dito ser escalonamento ou redução linha-a-linha. . . 4 Analisando um sistema escalonado e suas soluções Dado um sistema linear com sua matriz associada escalonada. .    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. Esse trabalho feito até agora foi para demonstrar que todo sistema linear é equivalente a um sistema escalonado. Denição 3. . 1 .. Não deve ser difícil perceber que quando encontrarmos uma matriz equivalente do tipo      M =    1 0 .. podemos extrair dele diversas informações sobre como suas soluções se comportam. 8 .. . novamente.  . mas tenha certeza que entendeu antes de continuar!). . 0 .   1 cn   . 0 cm 0 .. . então o sistema é impossível. 0 . É dito ser o posto p de uma matriz escalonada o número de linhas não-nulas da mesma. .. .. Com uma matriz escalonada.. .. Começaremos com uma denição e depois trabalharemos em cima de três teoremas básicos..

. Suponha que o sistema tenha solução. teremos 0 = ci . o que é um absurdo!. haverão pivôs apenas para p variáveis. Demonstração. o sistema possuirá innitas soluções reais e será dito sistema possível e indeterminado. Se a matriz associada (não-expandida) a um sistema linear escalonado de m equações e n incógnitas tiver posto p < m e a i-ésima equação de coecientes nulos tiver termo independente ci 6= 0. . Se a matriz associada expandida a um sistema linear escalonado de m equações e n incógnitas tiver posto p < m e não for impossível. Se a matriz associada expandida a um sistema linear escalonado de m equações e n incógnitas tiver posto p = m e não for impossível. 9 . Logo o sistema linear não possui solução real e é dado como sistema impossível.Teorema 1 (Sistema impossível). Um exemplo simples de sistema impossível:   1 0 0 3 0  0 1 0 0 0     0 0 1 1 0  0 0 0 0 1 (13) Teorema 2 (Sistema possível e indeterminado). que a matriz escalonada associada expandida possui n+1 colunas. + 0xn = ci Realizando a operação. Note. sendo que sobrarão n − p variáveis livres. então ele possui apenas uma soluções. visto que é possível substituir a matriz associada por outra de ordem superior (n × n). 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 possível e determinado). adicionando n − m linhas nulas sem perda de generalidade. pois supomos que ci 6= 0. ou seja. Se o sistema possui ao menos uma linha completamente nula (isto é. Tome a i-ésima linha nula e sua equação linear associada 0x1 + 0x2 + . Note que esse teorema pode ser adaptado facilmente para sistemas lineares que possuem menos equações que incógnitas (m < n). então o sistema não possui solução real e é chamado de sistema impossível Demonstração. primeiro. p < n). então ele possui innitas soluções.

p < n) e nem é impossível. então há m − p equações linearmente dependentes. Também é possível demonstrar facilmente a partir do que foi dito que se um sistema linear possui innitas soluções e tem m > p. Se ainda não foi notado. é importante que isso seja percebido o mais rápido possível. Como o conceito de dependência linear não será apresentado nesse trabalho. O importante. embora sua sintaxe seja de fácil compreensão e permita ser convertida para quase qualquer outra linguagem muito facilmente. que a matriz escalonada associada expandida possui n + 1 colunas. ca ao leitor observar e tentar demonstrar tais coisas. começaremos aqui a discutir uma solução computacional para o problema de resolver sistemas de equações lineares. sendo que poderia até ser colocada junta. então há algumas equações (quantas?2 ) que são linearmente dependentes das outras. Aqui tomaremos a idéia de quando p = m. Um exemplo simples de um sistema possível 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. Isso deve ser óbvio para qualquer um a partir de agora. com algum conhecimento de Álgebra Linear) que quando temos m > n e um sistema possível e determinado. não haverá qualquer variável livre e todas estarão muito bem denidas. Fica claro aqui que estaremos usando a linguagem C de programação. 5 Análise computacional Depois de discutirmos o algoritmo manual e as operações básicas para serem usadas numa sequência lógica. acima da 2m − n 10 . Se o sistema possui não possui nenhuma linha completamente nula (isto é. haverão pivôs apenas para todas asm = n = p linhas e colunas. primeiro. Note. Esta demonstração é facilmente deriavada da anterior. logo o sistema possui solução única e é dito ser sistema possível e determinado. ou seja.Demonstração. já que é a partir disso que trabalharemos no método computacional. O número de colunas usadas na matriz associada (nãoexpandida) é justaente o número de incógnitas do sistema linear e o número de linhas é o número de equações.

é entender a lógica sobre a qual estaremos trabalhando. while (o!=0) { system("cls"). O leitor deve estar familiarizado com os conceitos de matriz e vetor (arrays ) na programação antes de continuar. faremos a leitura dos dados enviados pelo usuário e guardaremos o que for necessário em variáveis ou matrizes. &Colunas). s. faremos o processamento principal (é essa a parte mais difícil do trabalho. #include <stdlib.1 A entrada A entrada de dados. No núcleo.sintaxe usada. 11 . são três as coisas básicas que devemos perguntar: Quantas variáveis? Quantas equações? Quais os valores do coeciente?. Assim como qualquer outro programa de computador. onde a verdadeira lógica está envolvida). Na saída. scanf("%d". cabe a nós começar a escrever nosso código. o nosso algoritmo terá três partes básicas: a entrada. pois é necessário criar uma interface amigável para que o usuário não se perca. apesar de parecer ser algo banal. como o nome sugere. iremos tomar os dados resultantes do processamento e mostrá-lo ao usuário. Para nosso programa. essa etapa dividiremos em mais duas: o escalonamento e a análise de resultados. printf(" \4 Entre com o numero de incognitas ou 0 para ajuda: "). 5.h> #include <cmath> main() { int Linhas. Estando isso tudo denido. deve ser analisada com cuidado. Na entrada. o. o núcleo e a saída. printf("\t\t\tSOLUCIONADOR DE SISTEMAS LINEARES\n\n\n\n").h> #include <stdio. Colunas.

system("cls"). &Colunas). que auxiliará o usuário enquanto faz uso do programa. Veremos como carão nossas condições: while (Colunas<=0) { if (Colunas==0) { printf("Insira alguma ajuda aqui"). scanf("%d". Não queremos que nosso programa pare de funcionar caso a entrada esteja errada. ou seja. Caso a entrada for 0. &Colunas). 12 . posteriormente. a mesma pergunta (Quantas incógnitas?). então o programa dirá que é inválido e perguntará novamente. sem ser o zero. Note que aqui temos vários tipos de entrada: inválida. } 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: "). printf(" \4 Entre com o numero de incognitas ou 0 para ajuda: "). ajuda e válida. Para isso usaremos a entrada 0. A condição while (o!=0) será explicado posteriormente. } Veja agora que realmente adicionamos as condições ditas inicialmente. A entrada será inválida se o usuário digitar um número inválido de incógnitas. redicionaremos para uma ajuda e perguntaremos. então precisamos pedir o número de colunas até o usuário entrar com um número válido. Também começamos a criar nossa interface.Nesse primeiro momento. Também é interessante adicionar uma opção de ajuda. system("pause"). estamos introduzindo duas coisas: chamamos duas das mais importantes variáveis (uma que dita o número de linhas e outra que dita o número de colunas) e outras duas auxiliares. nos resta apenas os inteiros negativos. } scanf("%d". Caso o número de incógnitas digitado for inválido. dando o título do programa e pedimos o número de incógnitas.

scanf("%d". &s). Colunas++. um grande diferencial: podemos mostrar ao usuário a matriz sendo escalonada e o melhor de tudo é que isso virá como um presente para nós. printf("Voce fez uma entrada invalida\n \4 Deseja visualizar passo-a-passo a resolucao feita por escalonamento? (1 . 0 . Caso não tivéssemos colocado o while inicial e partíssemos diretamente para algo do tipo while (Colunas==0) e depois while (Colunas<0). teríamos problema.Agora é importante notar a estrutura com a qual foi feito esse sistema. while (s!=0 && s!=1) { printf("%d". &Linhas). deixando o código vulnerável.sim.nao)? "). 0 . Essa parte é apenas uma continuação da primeira: estamos pedindo o número de equações presentes no sistema linear que será avaliado e checaremos se o número dado é válido.nao)? "). já que quase nada de código extra precisará ser feito. scanf("%d". como será visto quando estivermos analisando o núcleo do 13 . o programa iria aceitar esse resultado como número de colunas (incógnitas). pois caso você digitasse 0 duas vezes. printf(" \4 Deseja visualizar passo-a-passo a resolucao feita por escalonamento (1 .sim. &s).s). 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: "). também. &Linhas). } scanf("%d". Mas aqui entra. } scanf("%d". printf(" \4 Entre com o numero de equacoes: ").

i++) { for (j=0.i++) { for (j=0. m.j<=(Colunas-1). c=0. 14 a[%d]".n. for (c=0.j++) { system("cls"). então é necessário entender muito bem esse passo. temos que percorrer até um número antes do real.j<=(Colunas-1). já que ela assume valores aleatórios quando é chamada.l<Linhas. float Matriz[Linhas][Colunas]. .c++) printf(" printf("\n\n"). O −1 é justicado pelo fato do contador iniciar no zero e não no 1.c<Colunas-1. l=0.l++) { printf("\n"). Nela serão armazeadas todas os coecientes e termos independentes do sistema linear que deverá ser escalonado. Sendo assim. j. v. Todas as outras variáveis serão usadas apenas em auxílio.código (aqui também devemos checar se a entrada é válida ou não). Estamos aumentando o número da variável Colunas pois temos que contabilizar o termo independente do sistema e não apenas o número de incógnitas.i<=(Linhas-1). int i. } } Nesse pequeno próximo trecho estramos introduzindo todo o resto de variáveis que serão usadas no decorrer do programa. c+1). Veja que estamos usando Linhas-1 e Colunas-1. d[Linhas]. Esse conceito será amplamente usado no decorrer do código.j++) { Matriz[i][j]=0. Ela é a entrada principal e também será a saída principal e é nela que iremos mexer durante todo o processamento. e[Colunas].i<=(Linhas-1). x=0. O loop feito serve justamente para zerar a matriz principal. for (l=0. for (i=0. Dentre elas está a mais importante: a matriz Matriz[Linhas][Colunhas]. Veremos logo em seguida que essa operação é importante para manter a beleza da interface no próximo passo. for (i=0.

O código ainda pode ser otimizado da seguinte forma: note que caso a entrada tiver mais de um algarismo (seja ela 10. Note que.for(c=0. compilando o código diversas vezes até acertar. Isso pode ser resolvido com alguma lógica e usando códigos. } } if (j<Colunas-1) printf ("\n\n\n\nDefinicao da %da equacao:\n\n \4 Entre com o coeficiente da %da incognita: ". 3). else printf ("\n\n\n\nDefinicao da %da equacao:\n\n \4 Entre com o termo independente: ". Teremos uma interface mais ou menos como a apresentada na gura abaixo: Para deixar a interface organizada assim. &Matriz[i][j]). 3. antes de pedir o valor do termo.i+1). é preciso "visualizar"o código. 2. } } scanf("%f". O comando system("cls") serve justamente para limpar a tela.i+1. Essa parte é a qual realmente armazenaremos os coecientes e termos das equações lineares.c<Colunas. de modo que você veja onde os espaços devem ir para formar uma estrutura agradável. a matriz começará a car desorganizada. 15 . Matriz[l][c]). Pode-se contar o tamanho da entrada e somar ou diminuir espaços de forma a termos uma estrutura harmônica.2f".c++) { printf(" %. −8. j+1). estamos exibindo a matriz inteira. de forma que que claro os termos já digitados e forme um ambiente mais agradável para o leitor. Muitas vezes são necessárias algumas tentativas. 65241 e não 2.

obtido todas as informações necessárias para o desenvolvimento dessa segunda parte. Elas são: Colunas. a mais confusa. Pensando como um computador. sendo que as partes estão todas interconectadas. não são cruciais na execução do programa). De fato. já que é difícil dividir de modo organizado. Linhas e Matriz[Linhas][Colunas] (embora tenhamos guardado alguma informação em outras variáveis como a o e s. O escalonamento. Mas. Agora iremos para a parte provavelmente mais difícil: o núcleo de processamento. não poderemos realizar nenhuma divisão. a partir da matriz escalonada. Essa segunda parte ainda se divide em mais duas. Então a primeira precaução que devemos tomar é justamente essa: mudar a linha caso o pivô seja zero. Na primeira trabalharemos em cima do escalonamento da matriz e.1 O escalonamento Essa parte do código é. enquanto realizamos a operação de escalonar a matriz (que está guardada na variável Matriz[Linhas][Colunas]). concluimos nalmente a parte de entrada de dados para nosso programa.Em termos de código. a saída. nesse ponto. na segunda. Veremos que.2.2 O núcleo Antes de continuar. 5. nosso primeiro objetivo é transformar o pivô. Com isso feito. como divisão por zero. a entrada Matriz[i][i] em 1 e dividir o resto da linha pelo valor anterior do pivô. é o núcleo do núcleo do programa. Note que não teremos nenhuma ocor16 . No entanto. caso aconteça desse número ser 0. extrairemos dela os resultados para serem mostrados na próxima seção. onde iremos trabalhar na matriz para obtê-la escalonada. podemos dizer. As variáveis i e j servirão para o mesmo de antes: serão nossas principais para percorrer as linhas e colunas. tudo que zemos na parte anterior foi para armazenar dados nessas variáveis. temos que ter em mente que apenas três variáveis são importantes para o funcionamento do processo. provavelmente. ou seja. Já devemos ter. teremos que despistar alguns problemas. 5. é importante notar que estamos usando dois "grupos"de variáveis para percorrer as linhas e colunas da matriz. tentaremos fazer isso funcionar. As variáveis c e l serão usadas apenas para a exibição da nova matriz.

no entanto agora temos um vetor. faremos o seguinte procedimento: A = e. while (Matriz[i][i] == 0) { if (l=Linhas) break. for (j=0. como o da segunda linha (Matriz[1][1]). já que esse é o único caso em que o pîvô é justamente o primeiro elemento da linha. Caso for. B = e. tendo como pivô o elemento Matriz[0][0]. nalmente. for (i=0.j++) { e[j] = Matriz[i+l+1][j]. se o pivô é nulo.i++) { l=0. caso for. tomando como referência a primeira linha. Matriz[i][j] = e[j]. Depois que trocamos as linhas. } l++. Para isso. } Antes ainda de começar a análise desse código. Por intuição. recomendo ter sempre em mente um outro pivô qualquer. Matriz[i+l+1][j] = Matriz[i][j]. isso pode nos atrapalhar bastante. muitas vezes. É 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 mudança de linha. pois isso invalidaria uma variável e teríamos uma a menos na contagem. B = A e. na maior parte do tempo. Logo em seguida já entramos num loop que irá checar se o elemento pivô é zero (e. é importante tomar uma nota mental que é difícil de trabalhar. É como mudar duas variáveis comuns de valor. mudará a linha por inteira). a partir do while. sendo que os procedimentos para as linhas posteriores podem parecer contra-intuitivos. Começamos o código já percorrendo as linhas com a variável i.i<Linhas. requerendo um novo loop para fazer a troca. a troca continuará até atingirmos a última linha 17 .j<Colunas.rência de coluna completamente nula. ele checará novamente. acamos. Digamos que queremos trocar a linha A pela linha B . No entanto.

começaremos o processo de transformação do pivô em 1 e. for (l=0. } } Usamos novamente uma condição para checar se o pivô é zero apenas por garantia (não seria necessário). pois as entradas anteriores a j=i já devem ser zero. //Aqui entrará uma outra parte que será explicada posteriormente } x++. Caso ele passe no teste (o que deve acontecer).(para que não entremos num loop innito). O loop em que usamos o for serve justamente para desse processo.d[l]*Matriz[i][c]. if (l!=i) { for (c=0. Veja que é desnecessário corrermos para as linhas superiores.j++) { Matriz[i][j] /= v. consequentemente. indo de coluna em coluna. if (Matriz[i][i] != 0) { v = Matriz[i][i].c++) { if (c>=x) { Matriz[l][c] = Matriz[l][c] .j<Colunas.l<Linhas. Você pode notar que poderíamos começar o loop apenas em j=i e não em j=0.c<Colunas. } } } } 18 . já que elas estarão organizadas (veja aqui a importância de considerar um pivô diferente do a11 ). podemos continuar sem medo nossas divisões.l++) { d[l] = Matriz[l][x]. não fazendo diferença alguma a divisão. dividiremos a linha inteira pelo valor que será gravado na variável v. for (j=0. Agora que temos certeza que o pivô que trabalharemos denitivamente não é nulo.

Unindo todos esses conceitos que acabamos de ver. Caso o leitor seja capaz de ver. ela é usada. Não podemos sair mexendo com ela de qualquer jeito. O novo valor da entrada destino c na coluna j + 1 será cnovo = cantigo − ab. pois o programa perderá a noção de qual foi a última linha que trabalhou. Usaremos a variável l para essa tarefa. como estamos tratando primariamente dos pivôs (que possuem simetria. Note que já estamos percorrendo as linhas com a variável i. isso indica que estamos tentando zerar o pivô e isso não pode acontecer de forma alguma! Para isso. os dois "varredores"de linhas na mesma linha. Veja também que se tivermos l=i.i++) rodar. provavelmente. já que estaremos recorrendo a alguns deles frequentemente. É necessário lembrar de alguns loops que zemos. estaremos utilizando a variável d[l].i<Linhas. Isso deve car claro. Essa parte apresenta complicações por alguns motivos que já devem estar aparentes: estamos constantemente trabalhando com loops e percorrendo linhas e colunas em variáveis distintas. teremos que introduzir uma nova.Essa será. Agora é preciso algo que nos faça não voltar às colunas que já estão "escalonadas". não se pode esquecer de também subtrair das outras linhas da coluna. a parte mais confusa de toda a leitura do código (como se o resto já não fosse confuso o suciente). Esse é o papel do x. que armazenará os coecientes que deverão ser multiplicados para fazer a subtração. deve ser mais fácil através do código. aii . primariamente. por mais fácil que seja zerar a coluna. pois. é aqui que começaremos a zerar a coluna na qual o pivô está presente. no caso. iremos apenas 19 . tanto faz se rodarmos por um varredor "geral"de colunas ou linhas. depois temos que checar se essa não é a linha do pivô (caso for. ou seja. Funcionará da seguinte forma: seja a o valor da entrada na linha "fonte"e b o valor da entrada na linha "destino". Outra coisa que é preciso perceber é que. para essa tarefa. mentalizando uma de cada vez. por isso é importante tentar ir aos passos. ambas na coluna j . temos que criar um if que irá checar se isso acontece ou não. no entanto. essa variável será incrementada toda vez que o loop for (i=0. O primeiro passo é recomeçar um loop varrendo as linhas. isso causa grande confusão ao tentar reproduzir mentalmente o código. para identicar o pivô. para isso. Usar uma folha de papel para escrever uma matriz pequena e ir seguindo o código também ajuda. estaremos usando uma variável que fará a contagem de quantas linhas já estão prontas.

já que isso desescalonaria a parte que já está pronta. varreremos as colunas para ir fazendo a subtração (ou zerá-las. Como estramos dentro de vários loops.ignorá-la). 20 . if (s==1) { system("cls").n<Linhas. caso seja a coluna do pivô). } } } printf("\n\n").m<Colunas. todo o trabalho que o computador está fazendo pode ser mostrado facilmente. system("pause"). E isso é tudo que muda.n++) { printf("\n"). m+1). Simplesmente imprimimos a matriz. Lá no início. for(m=0. Lembrando que temos que usar o contador para não fazer a subtração nas colunas anteriores. É aqui que entra essa possibilidade. Agora entraremos na parte central que foi escondida na parte acima do código.m++) printf(" a[%d]". como estamos trabalhando em ciclos. Tecnicamente. quando descrevíamos a entrada. é muito fácil. for (m=0. teremos que usar novas variáveis para imprimir a matriz (aqui eu usei m e n). armazenamos na variável s se o usuário gostaria de visualizar o processo de escalonamento. é claro). acabamos aqui o escalonamento da matriz. o código acima será executado. Matriz[n][m]). Esse pedaço do programa não é nada mais que uma cópia da matriz que mostrávamos no início.m<Colunas-1.m++) { printf(" %. Em caso armativo. O leitor deve lembrar de quando foi dito. Depois disso. printf("\n\n"). Note que exatamente no lugar que esse código será adicionado está a mudança nos valores da variável e. no processo de obtenção das entradas (com algumas modicações.2f". for (n=0. que seria dado quase que de graça um método para mostrar a matriz sendo escalonada.

for (i=0. iremos usar variáveis para contar o número de linhas nulas e alguma outra para checar se essas linhas nulas possuem o último elemento também nulo. caso seja diferente disso. Há alguma linha completamente nula?.i<Linhas.i++) d[i]=0. Se o sistema for possível. usaremos essa variável para fazer a interpretação dos resultados em termos de equações lineares. Então o sistema possui uma única solução. Há alguma linha cujo único elemento não nulo é o que está na última coluna? Se sim.2 Interpretação do escalonamento Na parte anterior. for (j=0.2. (a) Se houver. será somar o valor absoluto de todos esses elementos numa variável. (b) Se não houver. o sistema é possível e determinado. O método que usaremos aqui para descobrir se o último elemento das linhas nulas é realmente zero. for (i=1. como foi visto na primeira parte desse trabalho. indica que o sistema é realmente impossível. Essa análise continuará. Essa é a segunda parte do núcleo do programa. o sistema é impossível.5. A partir de agora. c=0. } if (v==0) { if (Matriz[i][Colunas-1] != 0) c++. em parte. O que temos de checar. nessa ordem. l=0. escalonamos completamente o sistema linear de equações e o guardamos na matriz Matriz[Linhas][Colunas]. Para isso. através do posto).j++) { v += fabs(Matriz[i][j]). o valor dessa variável será obrigatoriamente zero e.j<Colunas-1. 2. else l++.i++) { v=0. é: 1. quantas são? (note que isso nos dará o número de variáveis livres.i<Linhas. 3. onde iremos dizer ao usuário se o sistema é possível (e dar a(s) resposta(s)) ou impossível. 21 . na saída.

bn da última coluna são as respostas para o sistema linear.j++) e é importante notar que temos que trabalhar com valores absolutos.fará a soma de todos os elementos da linha. 2. deve ser compreensível e possuir uma interface de fácil interação. · · · . v . elas não terão a mesma função de antes. 22 . por esse motivo.e o vetor d . dizer que ele é impossível. precisamos mostrar ao usuário algumas coisas: 1. mostrar isso e dar todas as soluções possíveis. é um modo de interação com o usuário e. Aqui já temos toda a interpretação feita. da l. l .j<Colunas-1. b2 . Começamos fazendo a soma na variável v da linha inteira até uma casa antes da última (disso vem o for (j=0. em caso positivo. Caso não for. Nesse passo. já que poderíamos ter resultados do tipo 3+(−3) = 0). Na próxima parte. então o sistema é necessariamente possível.que irá armazenar o valor da última coluna caso o sistema seja possível).} else { d[i] = Matriz[i][Colunas-1]. aumentamos o valor da variável c e. nos restando checar se o último elemento também é. falaremos um pouco mais sobre essa análise. Esses valores armazenaremos no vetor d[i]. quando formos dar o resultado ao usuário. } } Embora estejamos usando algumas das mesmas variáveis de antes (c será diferente de zero caso o sistema seja impossível -. Se o sistema for impossível.3 A saída A saída. nessa ordem. Se ele não se encaixar em nenhuma das especicações. 5. isso quer dizer que a linha é nula até ali. do mesmo modo que a entrada. a saída. então os valores b1 .contará o número de linhas completamente nulas -. por isso o uso da função fabs(). Caso v ainda tenha valor zero. com exceção do último . Se o sistema for possível e indeterminado. Mas o essencial está feito.

nalmente. já que não contam como incógnitas).2f". Para isso. Caso essas condições sejam encontradas.3. Não é muito difícil perceber que a matriz escalonada forma um novo sistema totalmente equivalente. daremos. o sistema associado. Se o sistema for possível e determinado. Linhas = Colunas − 1 (estamos usando o −1 pois eliminaremos a coluna dos termos independentes. é necessariamente indeterminado. } } else { printf("\n\nO sistema possui infinitas solucoes. ou seja. É exatamente esse sistema que mostraremos ao usuário. mas pode ter innitas soluções ou apenas uma. Suas solucoes resolvem o sistema abaixo:\n\n"). uma única resposta ao sistema linear. só teremos uma única solução se l for nulo e o número de incógnitas for exatamente igual ao número de linhas não-nulas.i++) { printf("\n").\n\n"). o sistema será impossível e pararemos por aqui. if (c!=0) printf("\n\nO sistema de equacoes lineares eh impossivel. porém mais simplicado.i++) { printf("\nO valor da %da incognita eh: a[%d] = %. Caso não seja nulo. for (i=0. se não for impossível. se o valor da variável c for diferente de zero. teremos as outras duas possibilidades: ele é certamente determinado. else { if (l==0 && Linhas == Colunas-1) { printf("Resultado do sistema linear:\n\n"). Como vimos anteriormente.i<Linhas. dar a solução única. teremos que encontrar um método de listar todas as possíveis n-uplas de números reais que satisfazem a equação. que está armazenada no vetor d[i]. for (i=0.i<Linhas. system("cls"). Sendo assim. d[i]). 23 . Agora só nos resta a possibilidade do sistema ter innitas soluções. Veja que se uma matriz possui o número de incógnitas maior que o número de equações (como foi enunciado o teorema).i+1. i+1.

2f". Podemos ainda mostrar como ca a matriz escalonada ao usuário. na verdade ele não é. Matriz[i][j]). Matriz[i][j]). mas isso é mera questão de desejo. } else { printf("= "). escondendo os coecientes nulos.} } } for (j=0.j++) { if (Matriz[i][j] != 0) { if (j < Colunas-2 && Matriz[i][j]!=0) printf("%. A solução está basicamente dada.2f*a[%d] + ".j+1). } Embora esse pedaço de código possa parecer extremamente complicado.j+1).j<Colunas.2f*a[%d] = ". assim como a variância da incógnita. Segue abaixo como z: 24 . O código parece complicado pois temos que saber quando e onde incluir os sinais de multiplicação e igualdade. O código pode ser copiado de outras impressões que zemos de matriz. com algumas modicações.2f". } else if (j == Colunas-1) printf("%. Matriz[i][j]. else if (j == Colunas-2) if (Matriz[i][j]!=0) { printf("%. } if (Matriz[i][j] == 0 && j==Colunas-1) printf("%. O que fazemos aqui é simplesmente exibir as soluções do sistema linear da forma como mostra a gura abaixo: Ou seja. no código simplesmente transcrevemos a matriz em forma de sistema de equações lineares. Matriz[i][j].

printf("\n\n"). talvez editando este trabalho ou até mesmo criando um novo. É importante essa ferramenta para sair do loop.2f". scanf("%d". printf("\n\n\n\n \4 Digite zero pra sair ou qualquer outro numero para resolver outro sistema: ").l<Linhas. } printf("\n\n\n\n"). Meu objetivo foi tentar expor da forma mais clara possível. Caso queira sair. ajudando a xar conteúdos vistos nas disciplinas de 25 . 6 Conclusão Concluímos. for (l=0. como o leitor já deve estar ciente.&o).l++) { printf("\n").c<Colunas. visto que ciclos innitos são extremamente mal vistos dum ponto de vista computacional. c+1). dos sistemas de equações lineares. foi o último passo e concluímos todo o trabalho computacional de resolução de sistemas de equações lineares. Caso o usuário deseje resolver outro sistema linear. pretendo mostrar algumas dessas aplicações. ele pode simplesmente digitar qualquer entrada. com um pouco do lado matemático.c++) printf(" a[%d]".printf("\n\n\n\n\n\n\t\t\tMATRIZ ESCALONADA:\n\n\n\n\n\n"). basta entrar com 0. Esse tipo de problema é algo clássico na computação e possui uma innidade de aplicações em todos os campos do conhecimento. aqui.c<Colunas-1. nalmente. embora possa não ter tido sucesso em alguns (ou todos) momentos. Esse. Numa outra oportunidade.c++) printf(" %. o estudo computacional. system("pause"). Matriz[l][c]). Este trabalho serviu como aprendizado para mim (por ser algo quase totalmente espontâneo). } } Veja que lá no início do código adicionamos um while (o!=0) e aqui seu uso se justica. for(c=0. for (c=0.

6. Course in Linear Algebra. correlacionando-os. favor enviar um e − mail para gustavo@hobold. Hygino H. São 4. Algebra Paulo: Harbra. 352p. UNIVERSITY OF PUGET SOUND. CALLIOLI. Para contato. Elon Lages. Rio de Janeiro: IMPA. Algebra linear e aplicações. 942p. Algebra linear.com. ISBN 8570562977 2. 2010. DOMINGUES. INSTITUTO DE MATEMATICA PURA E APLICADA (BRASIL). São Paulo (SP): Atual. e rev. amp. COSTA.ed. Carlos Alberto. ed. LIMA. linear. 26 A First . Jose Luiz . Obrigado. Espero que tenha sido útil também ao leitor. BOLDRINI. BEEZER. ver 2. sugestões ou correções. Roberto Celso Fabricio. (Matematica universitaria ) ISBN 8524401028 3.22.Computação Cientíca I e Álgebra Linear. (Hygino Hugueros). 7 Referências bibliográcas 1. 411p. 1990. 3. reform. c1986. Robert A. c 1998.